HTTP标头中的非法字符

Svi*_*ish 16 java http http-headers

我正在创建HttpUrlConnection并需要设置多个自定义标头.

我想按照以下方式做一些事情,但标题映射的内容需要来自单个字符串.在HTTP标头名称和HTTP标头值中是否存在任何非法或极少使用的字符?

HashMap<String, String> headers = new HashMap<String, String>();

// TODO: How can I fill the headers map reliably from a single string?

HttpURLConnection c = (HttpURLConnection) url.openConnection();
for(Map.Entry<String, String> e : headers.entrySet())
    c.setRequestProperty(e.getKey(), e.getValue());
Run Code Online (Sandbox Code Playgroud)

解决方案现在

似乎任何HTTP标头名称都不包含任何空格(通常使用破折号?),因此我可以使用单个空格将名称与值分开.至于名称 - 值集,似乎我搞砸了,因为根据给定的答案,值可以包含几乎任何东西.所以我选择了一个我非常肯定最不可能使用的角色:§.如果事实证明它确实需要,我只需要调整我的代码:p

Header1 Value1§Header2 Value2§Header3 Header3
Run Code Online (Sandbox Code Playgroud)

mc0*_*c0e 14

RFC7230的相关BNF是:

field-name = token

token = 1*tchar

tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / 
        "." / "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
Run Code Online (Sandbox Code Playgroud)

字符集是可见的USASCII.

RFC 7230比您的问题更新,但在相关细节中,它并没有改变RFC 2616之前所说的内容.

对于字段名称有一个非常强大的约定,它比RFC允许的限制性更强,并且在各种实现中强制执行不同程度.字段名称通常遵循[ASCII/NUMERAL]字序列的模式,每个字的首字母(仅)大写.单词用单个连字符分隔.

因此,例如"HttpUrlConnection"应该是HTTP标头名称(而不是Java标记),您将其称为"Http-Url-Connection".

我朦胧地记得曾经跟踪过一个错误到一些严格到足以不承认多个大写字母(这恰好是一个缩写词)的实现.也就是说,非常严格地遵循这种更受限制的格式是值得的.

  • 非ASCII字符集在字段名称中不起作用,但它们可以在字段值中使用.

  • 标准不支持在字段名称中转义.逃避值不是HTTP或MIME标准的关注点,但您可以选择重用标准URL编码方法来编码一组名称值对.