【问题标题】:Get content from HTTP request even if there is no contentlength header即使没有 contentlength 标头,也可以从 HTTP 请求中获取内容
【发布时间】:2013-07-22 21:34:33
【问题描述】:

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

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

【问题讨论】:

  • 请求是否包含Transfer-Encoding: 标头?

标签: java http header


【解决方案1】:

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

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

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

现在,如果您正在处理一个 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"

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

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

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

【讨论】:

  • 并且读取应该在标题结束之后开始,对吧?
  • @Geo:是的。通常,HTTP API 会为您解析标头,并为您提供内容的输入流。
  • 啊,好的。我假设因为他需要这样做,所以他不能依赖任何现有的类。
  • 这对于响应来说当然是正确的,但是 OP 说这是一个请求;如果客户端关闭了连接,它应该如何读取您的响应?
  • 如果没有内容长度,也可能意味着分块编码已经到位。 (我想正确的答案取决于所使用的层;例如,它是一个 ServletInputStream,然后 servlet 容器将处理这个问题,并且应该已经处理了分块编码)
【解决方案2】:

如果这是一个响应,那么可以通过关闭连接来终止消息。但这不是一个选项,因为客户端仍然需要读取响应。

除了Content-Length:,其他确定内容长度的方法有:

  • Transfer-Encoding: chunked
  • 猜测

希望是前者,在这种情况下,请求应该如下所示:

POST /some/path HTTP/1.1 主机:www.example.com 内容类型:文本/纯文本 传输编码:分块 25 这是第一个块中的数据 1C 这是第二个 3 骗局 8 序列 0

(无耻地从Wikipedia article盗取并修改为一个请求)

  • 每个块的格式为:十六进制编码长度、CRLF、数据、CRLF
  • 在最终的数据承载块之后是一个没有数据的零长度块
  • 在零长度块之后是可选的额外 HTTP 标头
  • 在可选的 HTTP 标头之后是另一个 CRLF

【讨论】:

    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      相关资源
      最近更新 更多