读取完整的HTTP请求标头

时间:2012-01-13 17:39:08

标签: java sockets io http-headers

我目前正在创建一个小型网络服务器(用于测试目的),我在阅读HTTP请求标题时遇到问题(来自浏览器,在我的情况下为chrome)。

首先,我只是尝试过这样的事情:

BufferedReader in = new BufferedReader(
  new InputStreamReader(client_socket.getInputStream(), "UTF-8")
);
StringBuilder builder = new StringBuilder();
while (in.ready()){
    builder.append(in.readLine());
}
return builder.toString();

这对第一个请求很好。但是,在第一次请求完成后,ready() - 方法仅返回false(我关闭了client_socket以及所有读者/作者。)

经过一番搜索后,我偶然发现了这个问题:Read/convert an InputStream to a String

我尝试了前四个解决方案(两个使用Apache Commons,一个使用Scanner,另一个使用do-while循环)。所有这些都被封锁了,浏览器给了我一个“网站无法访问” - 错误。

我想自己做这件事(不使用任何图书馆或嵌入式服务器),这就是我尝试的原因。

我现在有点失落,你会怎么做?

2 个答案:

答案 0 :(得分:1)

您正在从套接字读取,直到没有更多数据要读取。那是错的。您需要继续阅读,直到遇到0长度的行,然后处理收到的标头以确定是否有更多数据要读取(查找Content-Length: ...Transfer-Encoding: chunked标头),例如:

StringBuilder builder = new StringBuilder(); 
String line;
do
{
    line = in.readLine(); 
    if (line == "") break;
    builder.append(line);
}
while (true);
// use builder as needed...
// read message body data if headers say there
// is a body to read, per RFC 2616 Section 4.4...

阅读RFC 2616 Section 4了解更多详情。这不仅有助于正确的请求读取,而且这样做还可以正确支持HTTP保持活动(用于在单个连接上发送多个请求)。

答案 1 :(得分:1)

Remy Lebeau上面提出的解决方案是错误的,因为它在我的测试中显示出来。这种替代方案是故障安全的:

StringBuilder builder = new StringBuilder(); 
String line;
do
{
    line = in.readLine(); 
    if (line.equals("")) break;
    builder.append(line);
}
while (true);

请参阅:How do I compare strings in Java?