【问题标题】:Read complete HTTP request-header读取完整的 HTTP 请求标头
【发布时间】:2012-02-09 21:45:13
【问题描述】:

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

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

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 循环)。所有这些都被永久阻止,浏览器给了我一个“网站无法访问”的错误。

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

我现在有点迷茫,你会怎么做?

【问题讨论】:

    标签: java sockets io http-headers


    【解决方案1】:

    您正在从套接字读取,直到没有更多数据要读取。那是错的。需要一直读到遇到长度为0的行,然后处理接收到的headers,判断是否还有更多的数据要读取(寻找Content-Length: ...Transfer-Encoding: chunked headers),eg:

    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 保持活动(用于在单个连接上发送多个请求)。

    【讨论】:

    • 虽然您给定的代码片段无法编译(String 以大写开头),但固定版本可以正常工作。我还会检查引用的 RFC,谢谢。
    【解决方案2】:

    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?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 1970-01-01
      • 2014-11-15
      • 2020-05-12
      • 1970-01-01
      • 2014-07-31
      相关资源
      最近更新 更多