繁体   English   中英

为什么有些服务器在最后一个块长度为零后不使用 CRLF?

[英]Why are some servers not using CRLF after the last chunk length of zero?

我正在使用 HTTP 请求工具(类似于 cURL)并且遇到服务器响应问题。 或者我对 HTTP 1.1 和分块数据的 RFC 的理解。

我所看到的是分块数据应采用以下格式:

4\r\n
Wiki\r\n
5\r\n
pedia\r\n
e\r\n
 in\r\n\r\nchunks.\r\n
0\r\n
\r\n

我实际看到的是以下内容:

4\r\n
Wiki\r\n
5\r\n
pedia\r\n
e\r\n
 in\r\n\r\nchunks.\r\n
0

换句话说,我测试过的少数服务器在 0.. 之后不再发送数据。不是 CRLF,更不用说 CRLFCRLF。

如果没有正确的分块标签格式,我们怎么知道这是分块数据的结尾? 超时发生在 0 之后寻找 CRLF,这还不够。

是的,它违反了标准。 但是我们希望与所有可能的 http 服务器和客户端兼容,因此我们必须了解如何违反它。

分块通常用于通过 http 1.1 协议进行内容流传输 标准要求以额外的CRLF结束内容。 所以我们可以看到如下伪代码:

def stream(endpoint)
  Socket.open(endpoint) do |socket|
    sleep 10

    more_data do |data|
      print data.length.to_s(16)
      print data
      print "CRLF"
    end
  end

  print "CRLF"
end

但正确的代码如下:

def stream(endpoint)
  Socket.open(endpoint) do |socket|
    sleep 10

    more_data do |data|
      print data.length.to_s(16)
      print data
      print "CRLF"
    end
  end

ensure
  print "CRLF"
end

这意味着在输入套接字中断后任何其他异常错误版本的方法将无法打印额外的“CRLF”到输出套接字。

如果没有正确的分块标签格式,我们怎么知道这是分块数据的结尾? 超时发生在 0 之后寻找 CRLF,这还不够。

许多实现忽略了这种违规,因为它们不需要知道内容的大小。 他们只是尝试在套接字关闭之前接收尽可能多的数据。

使用 Content-Length,绝对是我知道的时候; 对于文件下载,检查文件大小在资源方面无关紧要。 对于分块传输,我们不扫描消息正文中的 CRLF 对。 它首先读取指定数量的字节,然后再读取两个字节以确认它们是 CR 和 LF。 如果不是,则消息正文格式错误,并且大小指定不正确或数据已损坏。

有关更多信息,请阅读RCF ,其中说

在响应中使用分块传输编码的服务器不得对任何标头字段使用尾部,除非至少满足以下一项:

a) 请求包含一个 TE 头字段,表明在响应的传输编码中“trailers”是可接受的,如第 14.39 节所述; 或者,

b) 服务器是响应的源服务器,尾部字段完全由可选的元数据组成,接收者可以使用消息(以源服务器可接受的方式)而无需接收此元数据。 换句话说,源服务器愿意接受这样的可能性,即拖车字段可能会在通往客户端的路径上被悄悄丢弃。

确定消息体长度的方法:

如果报头有传输编码并且分块传输是最终编码,则消息体长度通过读取和解码分块数据来确定,直到传输编码指示数据完成。

如果 header 有 Transfer-Encoding 并且分块传输不是最终编码,则消息正文长度通过读取连接来确定,直到它被服务器关闭。

如果请求头中有传输编码,并且分块传输不是最终编码,则无法可靠地确定消息体长度; 服务器必须以 400(错误请求)状态代码响应,然后关闭连接。

如果接收到的消息同时带有 Transfer-Encoding 和 Content-Length 头域,Transfer-Encoding 会覆盖 Content-Length。 这样的消息可能表示尝试执行请求响应拆分,应该作为错误处理。 在向下游转发此类消息之前,发送方必须删除接收到的 Content-Length 字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM