¿Son aceptables los encabezados de respuesta HTTP duplicados?

123

No he encontrado ninguna especificación acerca de si el estándar permite encabezados de respuesta HTTP duplicados, pero necesito saber si esto causará problemas de compatibilidad.

Digamos que tengo un encabezado de respuesta como este:

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

Tenga en cuenta que hay dos Cache-Controlencabezados con valores diferentes. ¿Los navegadores siempre los tratan como si estuvieran escritos como "Cache-Control: no-cache, no-store"?

Su Zhang
fuente

Respuestas:

156

si

HTTP RFC2616 disponible aquí dice:

Múltiples campos de encabezado de mensaje con el mismo nombre de campo PUEDEN estar presentes en un mensaje si y solo si el valor de campo completo para ese campo de encabezado se define como una lista separada por comas [es decir, # (valores)]. DEBE ser posible combinar los múltiples campos de encabezado en un par "nombre-campo: valor-campo", sin cambiar la semántica del mensaje, agregando cada valor de campo subsiguiente al primero, cada uno separado por una coma. El orden en el que se reciben los campos de encabezado con el mismo nombre de campo es, por lo tanto, significativo para la interpretación del valor de campo combinado y, por lo tanto, un proxy NO DEBE cambiar el orden de estos valores de campo cuando se reenvía un mensaje

Por lo tanto, varios encabezados con el mismo nombre están bien (www-authenticate es un caso así) si todo el valor del campo se define como una lista de valores separados por comas.

El control de caché se documenta aquí: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 de esta manera:

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

La #1cache-directivesintaxis define una lista de al menos un elemento de directiva de caché (consulte aquí la definición formal de #valores: Convenciones de notación y gramática genérica )

Entonces sí,

Cache-Control: no-cache, no-store

es equivalente a (el orden es importante)

Cache-Control: no-cache
Cache-Control: no-store
Simon Mourier
fuente
2
¡Gracias por tu rápida respuesta, Simon! ¿Pero el párrafo citado del RFC 2616 no se aplica también a Cache-Control? ¿Me estoy perdiendo de algo?
Su Zhang, el
1
Casi 100% correcto. Control de caché permite múltiples valores: Cache-Control = "Cache-Control" ":" 1#cache-directive. Note el #antes cache-directive. Eso indica que se aceptan múltiples valores (directamente desde su definición anterior) ...
ircmaxell
1
"si y solo si el valor de campo completo para ese campo de encabezado se define como una lista separada por comas", eso me parece que los valores múltiples deben definirse como una lista separada por comas, es decir, no pueden ser dividido como encabezados separados.
mpen
2
@mark - "definido como una lista separada por comas" aquí significa "definido en la gramática BNF como una lista separada por comas". Los campos de control de caché se definen así (x # blahblah).
Simon Mourier
2
La sección en el nuevo RFC 7230 que habla sobre el manejo de múltiples encabezados es tools.ietf.org/html/rfc7230#section-3.2.2
Matthew Buckett
0

Tenga en cuenta que el HSTS RFC6797 contradice el RFC2616 (violando el lenguaje "if and only if") al definir el comportamiento para múltiples instancias del encabezado STS, aunque no se rellena con valores separados por comas:

  "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
fuente
Incorrecto. RFC6797 NO define el encabezado STS como que contiene una lista separada por comas. Por lo tanto, la regla "if and only if" de RFC 2616 se aplica de la misma manera (lo que significa que NO se permiten múltiples encabezados STS ya que el encabezado STS no se define como una lista separada por comas). RFC6797 simplemente hace que no sea determinista cuáles son las consecuencias de violar esa regla, algo que RFC2616 parece dejar abierto.
Frans