HTTP标头值允许哪些字符?

C.M*_*.M. 12 http http-headers

在研究了HTTP/1.1标准之后,特别是第31页和相关的我得出结论,任何8位八位字节都可以出现在HTTP头值中.即任何带有[0,255]范围代码的字符.

然而我试过的HTTP服务器拒绝接受代码> 127(或大多数US-ASCII不可打印的字符)的任何东西.

这里是标准中使用的语法摘录:

message-header = field-name ":" [ field-value ]
field-name     = token
field-value    = *( field-content | LWS )
field-content  = <the OCTETs making up the field-value and consisting of
                  either *TEXT or combinations of token, separators, and
                  quoted-string>

CR             = <US-ASCII CR, carriage return (13)>
LF             = <US-ASCII LF, linefeed (10)>
SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>
CRLF           = CR LF
LWS            = [CRLF] 1*( SP | HT )
OCTET          = <any 8-bit sequence of data>
CHAR           = <any US-ASCII character (octets 0 - 127)>
CTL            = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
TEXT           = <any OCTET except CTLs, but including LWS>

token          = 1*<any CHAR except CTLs or separators>
separators     = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\"
               | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT

quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )
qdtext         = <any TEXT except <">>
quoted-pair    = "\" CHAR
Run Code Online (Sandbox Code Playgroud)

正如你所看到field-content的那样quoted-string,它可以是a ,它是一个被引用的序列TEXT(即任何8位八位组,除了范围的"值和from [0-8, 11-12, 14-31, 127]值)或quoted-pair(\后跟[0, 127]范围内的任何值).即任何8位字符序列都可以通过引用它并为特殊符号添加前缀来传递\.

(注意标准不NUL(0x00)以任何特殊方式处理char)

但是,显然我所尝试的所有服务器都不符合标准,或者自1999年以来标准发生了变化,或者我无法正确阅读.

那么...... HTTP标头值允许哪些字符?为什么?

PS背后的原因:我正在寻找一种在HTTP标头值中传递utf-8编码序列的方法(如果可能的话,不需要额外的编码).

Dan*_*son 16

对于所有像我一样来这里标题“HTTP 标头值中允许使用哪些字符?”的人

\n
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~\n!#$&\'()*+,/:;=?@[]\n%20,%21,%22,%23,%24,%25,%26,%27,%28,%29,%2A,%2B,%2C,%2F,%3A,%3B,%3D,%3F,%40,%5B,%5D\n
Run Code Online (Sandbox Code Playgroud)\n

来自@CM的评论提到维基百科的 url 编码

\n
    \n
  • RFC 3986 第 2.2 节保留字符(2005 年 1 月)
  • \n
\n

!#$&\'()*+,/:;=?@[]

\n
    \n
  • RFC 3986 第 2.3 节非保留字符(2005 年 1 月)
  • \n
\n

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~

\n
    \n
  • 百分比编码后的保留字符 ( \xe2\x90\xa3 == " " )
  • \n
\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\xe2\x90\xa3#$%&\'*+,/:;=@[]
%20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D
\n
\n
    \n
  • 以及对我们的 python 代码有用的 json:
  • \n
\n
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~\n!#$&\'()*+,/:;=?@[]\n%20,%21,%22,%23,%24,%25,%26,%27,%28,%29,%2A,%2B,%2C,%2F,%3A,%3B,%3D,%3F,%40,%5B,%5D\n
Run Code Online (Sandbox Code Playgroud)\n

我相信朱利安·雷施克回答了OP的“为什么”

\n


Jul*_*hke 6

RFC 2616是过时的(见https://www.rfc-editor.org/info/rfc2616),相关部分已取代RFC 7230(见https://www.greenbytes.de/tech/webdav/rfc7230。 html#rfc.section.A.2.p.9):

注释和带引号的字符串文本中不再允许使用NUL八位字节,并且已经澄清了在其中使用反斜杠转义的处理。引号对规则不再允许转义除HTAB以外的控制字符。标头字段和原因短语中的非US-ASCII内容已过时且不透明(已删除TEXT规则)。 (第3.2.6节)

本质上,RFC 2616默认为ISO-8859-1,这既不够用,也无法互操作。因此,RFC 7230在字段值中已弃用非ASCII八位字节。建议在此之上使用转义机制(例如RFC 8187中定义的或普通URI-percent-encoding)。

  • RFC 2616已过时吗?是。这是否回答了OP的“ HTTP标头值中允许哪些字符以及为什么”的问题?没有。 (9认同)
  • 不推荐使用非 ASCII 字符。您可以发送它们,但不能保证收件人会按照您的预期执行。这就是规范所说的,这就是答案:-) (4认同)
  • @JulianReschke我终于抽出时间阅读RFC 7230。我在[p3.2.6](https://www.greenbytes.de/tech/webdav/rfc7230中没有看到任何非US-ASCII内容的“废弃”。 html#rfc.section.3.2.6) -- 似乎它允许在“quoted-string”中使用任何“0x80-0xFF”字符。不过,“0x00-0x7F”范围被大幅缩减。也就是说,根据这个标准,只要您转义“0x00-0x7F”范围的“禁止”部分,您就可以在标头值中传递 utf-8 数据。我错了吗? (2认同)