我正在使用供应商产品的自定义 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
。
反编译供应商产品的代码显示,只要套接字保持活动状态,他们的 servlet 引擎就会缓存 Host 标头。
为了重现该问题,我编写了一些低级套接字代码来发出 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 引擎是否通过缓存并为同一个套接字连接返回相同的主机标头来正确运行,还是应该重新解析 HTTP 标头并更新缓存的主机标头?我的想法是,由于 HTTP 假设是无状态的,所以 HTTP 请求中的任何信息都应该重新解析和重新加载,甚至是主机头。