即使没有 contentlength 标头,也可以从 HTTP 请求中获取内容

Koz*_*lov 3 java header http

正在与向我发送没有内容长度标头但有内容的 HTTP 请求的客户端进行测试。

如何在没有 contentlength 标头的帮助下提取此内容?

Jon*_*eet 5

为了完整起见,我保留了原始答案,但我一直在查看HTTP RFC (2616)部分 4.3:

通过在请求的消息头中包含 Content-Length 或 Transfer-Encoding 头字段来表示请求中消息正文的存在。如果请求方法的规范(第 5.1.1 节)不允许在请求中发送实体主体,则消息主体不得包含在请求中。服务器应该读取并转发任何请求的消息体;如果请求方法不包括为实体主体定义的语义,那么在处理请求时应该忽略消息主体。

因此,如果您没有内容长度,您必须有一个传输编码(如果您没有,您应该以 400 状态响应以指示错误请求或 411(“需要长度”))。在这一点上,你按照 Transfer-Encoding 告诉你的去做:)

现在,如果您正在处理 servlet API(或类似的 HTTP API),它可以很好地为您处理所有这些 - 此时您可以使用下面的技术从流中读取,直到它不再产生更多数据,因为 API 会处理它(即它不仅仅是原始套接字流)。

如果您可以向我们提供有关您的上下文的更多信息,那将会有所帮助。


原答案

如果没有内容长度,这意味着内容会一直持续到数据结束(当套接字关闭时)。

继续从输入流中读取(例如将其写入 ByteArrayOutputStream 以存储它,或者可能是一个文件),直到InputStream.read返回 -1。例如:

byte[] buffer = new byte[8192];
ByteArrayOutputStream output = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1)
{
    output.write(buffer, 0, bytesRead);
}
// Now use the data in "output"
Run Code Online (Sandbox Code Playgroud)

编辑:正如评论中指出的那样,客户端可能正在使用分块编码。通常,您使用的 HTTP API 应该为您处理这个问题,但如果您正在处理原始套接字,则必须自己处理。

关于这是一个请求(因此客户端无法关闭连接)的观点是一个有趣的问题 - 我认为客户端可以关闭发送部分,但我看不到它如何映射到 TCP 中的任何内容在这一刻。我的低级网络知识不是它可能的样子。

如果这个答案“绝对没用”,我会删除它......