6

我正在使用供应商产品的自定义 servlet 引擎。我们的服务器前面是具有不同主机名的不同代理。假设主机名是host1.localhost.comhost2.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 请求中的任何信息都应该重新解析和重新加载,甚至是主机头。

4

1 回答 1

2

HTTP 对如何在客户端和服务器之间建立连接有点模糊:

https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p1-messaging-22#section-6.2

描述如何通过各种传输或会话层协议建立连接超出了本规范的范围。

如果客户端对解析为同一 IP 的两个主机名使用一个持久连接,我看不出有任何问题。它不应该在服务器端引起任何问题。

于 2013-05-17T03:08:23.573 回答