我正在使用供应商产品的自定义 servlet 引擎。我们的服务器前面有不同的代理,具有不同的主机名。假设主机名为 host1.localhost.com
和 host2.localhost.com
。
我们有以下servlet
public class MyServlet {
public void doGet(...) {
response.getOutputStream.write(request.getServerName().getBytes())
} }
我们遇到了一个问题,有时如果我们发出请求 host1.localhost.com/my/servlet
我们实际上看到了 host2.localhost.com/my/servlet
在响应中。
反编译供应商产品的代码显示,只要套接字保持 Activity 状态,他们的 servlet 引擎就会缓存主机 header 。
为了重现该问题,我编写了一些低级套接字代码来发出 HTTP 请求:
Socket s = new Socket();
s.connect(new InetSocketAddress("host2.localhost.com", 8080));
OutputStream os = s.getOutputStream();
/*this thread keeps printing stuff in the input stream*/
Thread t = new ResponsePrintThread(s.getInputStream());
t.start()
os.write("GET /my/servlet/testservlet HTTP/1.1\r\n".getBytes());
os.write("Host: 12345\r\n".getBytes());
os.write("\r\n".getBytes());
os.flush();
os.write("GET /my/serlet/testservlet HTTP/1.1\r\n".getBytes());
os.write("Host: 7891011\r\n".getBytes());
os.write("\r\n".getBytes());
os.flush();
上面会打印
12345
12345
但我希望
12345
7891011
我的问题是,servlet 引擎是否通过缓存并为相同的套接字连接返回相同的主机 header 来正确运行,或者它是否应该重新解析 HTTP header 并更新缓存的主机 header ?我的想法是,由于 HTTP 假设是无状态的,因此应该重新解析和重新加载 HTTP 请求中的任何信息,甚至是主机 header 。
最佳答案
HTTP 对于如何在客户端和服务器之间建立连接有点模糊:
https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p1-messaging-22#section-6.2
It is beyond the scope of this specification to describe how connections are established via various transport or session-layer protocols.
如果客户端对解析为同一 IP 的两个主机名使用一个持久连接,我看不出有什么问题。它应该不会在服务器端引起任何问题。
关于java - 一个套接字,多个http请求,不同的主机头但服务器返回缓存的主机头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16600534/