【发布时间】:2019-12-27 05:41:40
【问题描述】:
在 http 请求/响应中是否应该忽略前导或尾随空格?
例如,一个符合 HTTP/1.1 的客户端是否应该解释这个:
Connection : close \r\n
这样:
Connection: close\r\n
【问题讨论】:
标签: http
在 http 请求/响应中是否应该忽略前导或尾随空格?
例如,一个符合 HTTP/1.1 的客户端是否应该解释这个:
Connection : close \r\n
这样:
Connection: close\r\n
【问题讨论】:
标签: http
不,你不应该这样做,而且这完全是无效的。
tchar= "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" /DIGIT/ @987654338 @token= 1*tcharfield-name=tokenheader-field=field-name":"OWSfield-valueOWS
field-name 不能有空格。
在Connection : close \r\n中,field-name为Connection ,无效。
【讨论】:
见RFC 7230 Appendix B. Collected ABNF
header-field = field-name ":" OWS field-value OWS
field-value = *( field-content / obs-fold )
field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
field-vchar = VCHAR / obs-text
OWS 表示可选空格,field-value 也包括空格。您必须以某种方式忽略前导和尾随空格。
前导空格不是问题,但尾随空格会破坏流式设计。您无法以纯流式传输方式(不存储任何内容)解析 HTTP 1.1 标头。
例如:Connection: a b \r\n b c\r\n d \r\n
您收到了a,而不是空格。您无法删除此空格,因为您不知道它是field-value 还是OWS 的一部分。因此,您必须在接收非空白字节或\r\n 之前存储空白。 b + 空格 + c 和 d + 空格也是一样的。
像 nginx/nodejs 这样流行的流解析器只是在第一个空格之后停止标头值。这意味着这些解析器并非 100% 兼容 RFC 7230。
OBS 折叠已被弃用,但有许多旧的网络服务器能够生成它。所以无论如何你都必须处理标题值中的空白地狱。
保持解析器以纯流方式工作的唯一一种方法是向用户提供空白而不进行修剪。
【讨论】:
根据RFC2616 (HTTP/1.1) 的第 4.2 段,字段值前面可能有空格,但字段名不能:
每个标题字段由 名称后跟冒号 (":") 和字段值。字段名称 不区分大小写。字段值前面可以有任何数量 LWS(线性空白),但最好使用单个 SP。通过在每个额外行之前至少使用一个 SP 或 HT,可以将标题字段扩展到多行。应用程序应遵循“通用形式”,其中 一个是已知的或指示的,在生成 HTTP 结构时,因为 可能存在一些无法接受任何内容的实现。
【讨论】: