Чи прийнятні повторювані заголовки відповідей 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заголовки з різними значеннями. Чи завжди браузери ставляться до них так, ніби вони написані як "Кеш-контроль: немає кешу, немає магазину"?

Відповіді:


157

Так

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

Кілька полів заголовка повідомлень з тим самим іменем поля МОЖЕ бути присутнім у повідомленні лише тоді, коли все значення поля для цього поля заголовка визначено як список, розділений комами [тобто, # (значення)]. ОБОВ'ЯЗКОВО бути можливим поєднувати декілька полів заголовка в одну пару "ім'я поля: поле-значення", не змінюючи семантику повідомлення, додаючи кожне наступне значення поля до першого, кожне розділене комою. Отже, порядок, у якому одержуються поля заголовка з тим самим іменем поля, є значущим для інтерпретації об'єднаного значення поля, і, таким чином, проксі НЕ МОЖЕ НЕ змінювати порядок цих значень поля під час пересилання повідомлення

Отже, кілька заголовків з одним іменем є нормальним (www-автентифікація є таким випадком), якщо все значення поля визначається як розділений комою список значень.

Кеш-контроль задокументований тут: 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 також для кеш-контролю? Я щось пропускаю?
Су Чжан

1
Майже на 100% правильно. Контроль кешу дозволяє кілька значень: Cache-Control = "Cache-Control" ":" 1#cache-directive. Зауважте #раніше cache-directive. Це вказує на те, що багато значень прийнято (прямо з вашого визначення вище) ...
ircmaxell

1
"якщо і лише в тому випадку, якщо все значення поля для цього поля заголовка визначено як список, розділений комами", - мені це здається, що кілька значень повинні бути визначені як розділений комою список, тобто вони не можуть бути розділити як окремі заголовки.
mpen

2
@mark - "визначений як розділений комою список" тут означає "визначений у граматиці BNF як список, розділений комами". Поля кеш-керування дійсно визначені так (x # blahblah).
Саймон Мур’є

2
Розділ у новій програмі RFC 7230, яка розповідає про обробку декількох заголовків, - tools.ietf.org/html/rfc7230#section-3.2.2
Matthew Buckett

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."

Неправильно. RFC6797 НЕ визначає заголовок STS як такий, що містить список, розділений комами. Таким чином, правило "якщо і тільки якщо" з RFC 2616 застосовується точно так само (це означає, що декілька заголовків STS НЕ дозволено, оскільки заголовок STS не визначається як прийняття списку, розділеного комами). RFC6797 просто робить недетермінованим наслідки порушення цього правила, що, здається, RFC2616 залишає відкритим.
Франс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.