Os cabeçalhos de resposta HTTP duplicados são aceitáveis?

123

Não encontrei nenhuma especificação sobre se cabeçalhos de resposta HTTP duplicados são permitidos pelo padrão, mas preciso saber se isso causará problemas de compatibilidade.

Digamos que eu tenha um cabeçalho de resposta 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

Observe que existem dois Cache-Controlcabeçalhos com valores diferentes. Os navegadores sempre os tratam como se fossem escritos como "Controle de cache: sem cache, sem armazenamento"?

Su Zhang
fonte

Respostas:

156

sim

O HTTP RFC2616 disponível aqui diz:

Vários campos de cabeçalho de mensagem com o mesmo nome de campo PODEM estar presentes em uma mensagem se e somente se todo o valor do campo para esse campo de cabeçalho for definido como uma lista separada por vírgula [ou seja, # (valores)]. DEVE ser possível combinar os vários campos de cabeçalho em um par "nome do campo: valor do campo", sem alterar a semântica da mensagem, acrescentando cada valor de campo subsequente ao primeiro, cada um separado por vírgula. A ordem na qual os campos de cabeçalho com o mesmo nome de campo são recebidos é, portanto, significativa para a interpretação do valor combinado do campo e, portanto, um proxy NÃO DEVE alterar a ordem desses valores de campo quando uma mensagem é encaminhada.

Portanto, vários cabeçalhos com o mesmo nome são válidos (nesse caso, www-authenticate) se todo o valor do campo for definido como uma lista de valores separados por vírgula.

O controle de cache está documentado aqui: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 assim:

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

A #1cache-directivesintaxe define uma lista de pelo menos um elemento de diretiva de cache (veja aqui a definição formal de #values: convenções de notação e gramática genérica )

Então sim,

Cache-Control: no-cache, no-store

é equivalente a (a ordem é importante)

Cache-Control: no-cache
Cache-Control: no-store
Simon Mourier
fonte
2
Obrigado pela sua resposta rápida, Simon! Mas o parágrafo citado da RFC 2616 também não se aplica ao controle de cache? Estou esquecendo de algo?
Su Zhang
1
Quase 100% correto. Cache Control permite a vários valores: Cache-Control = "Cache-Control" ":" 1#cache-directive. Observe o #antes cache-directive. Que indica vários valores são aceitos (desde a sua definição acima) ...
ircmaxell
1
"se e somente se todo o valor do campo para esse campo de cabeçalho for definido como uma lista separada por vírgula" - para mim parece que os vários valores devem ser definidos como uma lista separada por vírgula, ou seja, eles não podem ser dividir como cabeçalhos separados.
MPEN
2
@mark - "definido como uma lista separada por vírgula" aqui significa "definido na gramática BNF como uma lista separada por vírgula". Os campos de controle de cache são realmente definidos assim (x # blahblah).
Simon Mourier
2
A seção na RFC 7230 mais recente, que fala sobre o manuseio de vários cabeçalhos, é tools.ietf.org/html/rfc7230#section-3.2.2
Matthew Buckett
0

Observe que o HSTS RFC6797 contradiz o RFC2616 (violando o idioma "se e somente se"), definindo o comportamento para várias instâncias do cabeçalho STS, embora não seja preenchido com valores separados por vírgula:

  "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."
Garoto-propaganda
fonte
Incorreta. O RFC6797 NÃO define o cabeçalho do STS como contendo uma lista separada por vírgula. Portanto, a regra "se e somente se" da RFC 2616 se aplica da mesma forma (o que significa que vários cabeçalhos STS NÃO são permitidos, pois o cabeçalho STS não está definido como uma lista separada por vírgula). O RFC6797 apenas não determina quais são as consequências de violar essa regra, algo que o RFC2616 parece deixar em aberto.
Frans