Допустимы ли повторяющиеся заголовки ответа HTTP?

123

Я не нашел никакой спецификации о том, разрешены ли дублирующиеся заголовки HTTP-ответа стандартом, но мне нужно знать, вызовет ли это проблемы совместимости.

Скажем, у меня есть такой заголовок ответа:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.4; JBoss-4.0.3SP1 (build: CVSTag=JBoss_4_0_3_SP1 date=200510231054)/Tomcat-5.5
Cache-Control: no-cache
Cache-Control: no-store
Location: http://localhost:9876/foo.bar
Content-Language: en-US
Content-Length: 0
Date: Mon, 06 Dec 2010 21:18:26 GMT

Обратите внимание, что есть два Cache-Controlзаголовка с разными значениями. Всегда ли браузеры обрабатывают их так, как будто они написаны как «Cache-Control: no-cache, no-store»?

Су Чжан
источник

Ответы:

157

да

HTTP RFC2616, доступный здесь, говорит:

Несколько полей заголовка сообщения с одинаковым именем поля МОГУТ присутствовать в сообщении тогда и только тогда, когда все значение поля для этого поля заголовка определено как список, разделенный запятыми [то есть # (значения)]. ДОЛЖНА быть возможна объединение нескольких полей заголовка в одну пару «имя-поля: значение поля» без изменения семантики сообщения путем добавления каждого последующего значения поля к первому, каждое из которых разделено запятой. Таким образом, порядок, в котором принимаются поля заголовка с одинаковым именем поля, важен для интерпретации значения комбинированного поля, и, таким образом, прокси-сервер НЕ ДОЛЖЕН изменять порядок значений этих полей при пересылке сообщения.

Таким образом, можно использовать несколько заголовков с одним и тем же именем (например, www-authentication), если все значение поля определено как список значений, разделенных запятыми.

Кэш-контроль задокументирован здесь: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 следующим образом:

Cache-Control   = "Cache-Control" ":" 1#cache-directive

#1cache-directiveСинтаксис определяет список , по крайней мере , один кэш-директива элементов (см здесь для формального определения #values: Условные обозначения и Generic грамматики )

Так да,

Cache-Control: no-cache, no-store

эквивалентно (порядок важен)

Cache-Control: no-cache
Cache-Control: no-store
Саймон Мурье
источник
2
Спасибо за быстрый ответ, Саймон! Но разве цитируемый абзац из RFC 2616 не применим и к Cache-Control? Я что-то упускаю?
Су Чжан
1
Почти на 100% правильно. Контроль кэша позволяет несколько значений: Cache-Control = "Cache-Control" ":" 1#cache-directive. Обратите внимание на то, что было #раньше cache-directive. Это означает, что принимаются несколько значений (прямо из вашего определения выше) ...
ircmaxell
1
"тогда и только тогда, когда все значение поля для этого поля заголовка определено как список, разделенный запятыми" - мне кажется, что несколько значений должны быть определены как список, разделенный запятыми, т. е. они не могут быть разделены на отдельные заголовки.
mpen
2
@mark - «определенный как список, разделенный запятыми» здесь означает «определенный в грамматике BNF как список, разделенный запятыми». Поля Cache-control действительно определены таким образом (x # blahblah).
Саймон Мурье
2
Раздел в новом RFC 7230, в котором говорится об обработке нескольких заголовков, называется tools.ietf.org/html/rfc7230#section-3.2.2
Мэтью Баккет,
0

Обратите внимание, что HSTS RFC6797 противоречит RFC2616 (нарушая язык «если и только если»), определяя поведение для нескольких экземпляров заголовка STS, хотя он не заполняется значениями, разделенными запятыми:

  "If a UA receives more than one STS header field in an HTTP
  response message over secure transport, then the UA MUST process
  only the first such header field."
PosterBoy
источник
Неправильно. RFC6797 НЕ определяет заголовок STS как содержащий список, разделенный запятыми. Таким образом, правило «если и только если» из RFC 2616 применяется точно так же (это означает, что несколько заголовков STS НЕ разрешены, поскольку заголовок STS не определяется как принимающий список, разделенный запятыми). RFC6797 просто делает недетерминированным, каковы последствия нарушения этого правила, что RFC2616, похоже, оставляет открытым.
Франс,