Quando um navegador envia uma solicitação a um servidor pela primeira vez, como ele decide qual versão do HTTP deve ser aplicada? A especificação HTTP RFC diz:
Um cliente HTTP DEVE enviar uma versão de solicitação igual à versão mais alta para a qual o cliente é pelo menos condicionalmente compatível
Mas, do meu experimento no inspetor do Chrome, o Chrome usa HTTP 2 ao enviar solicitações para alguns sites, mas também usa HTTP 1.1 em outros casos.
Gostaria de saber como o Chrome sabe qual versão da solicitação HTTP deve usar? Eu sei que o servidor deve responder com a versão mais alta do HTTP que ele suporta, então o Chrome envia a primeira solicitação para cada site com http2 por padrão, então salva a versão HTTP que o site suporta e usa essa versão para sempre?
Qualquer explicação seria apreciada.
HTTP/1.x
Tanto o HTTP/1.1 quanto o HTTP/1.0 usam formatos de solicitação compatíveis. Após a primeira solicitação, a resposta do servidor indicará a versão que ele suporta , além de cabeçalhos como "Connection: keep-alive" indicando quais recursos podem ser utilizados.
HTTP/2
Os navegadores decidiram oferecer suporte apenas a HTTP/2 em uma conexão TLS. Isso permite que eles usem um novo recurso TLS chamado ALPN (negociação de protocolo de camada de aplicativo).
Quando o Chrome estabelece a conexão TLS, ele envia uma lista de protocolos suportados (
http/1.1
eh2
) como parte do handshake TLS e o servidor responde com o que deseja usar – por exemplo, "h2" indicando que agora está esperando HTTP/2.Caso o servidor não retorne uma extensão ALPN, o navegador assume que ele suporta apenas HTTP/1.x. (Esta é a razão pela qual habilitar o suporte HTTP/2 em servidores costumava exigir a atualização do OpenSSL.)
O próprio protocolo HTTP/2 suporta o uso em uma conexão de texto simples usando o mecanismo HTTP Upgrade . Na maioria dos casos, a primeira solicitação deve ser HTTP/1.1, com um
Upgrade:
cabeçalho listando novamente os protocolos para os quais o cliente deseja alternar.A resposta também será HTTP/1.1, ou "101 Switching Protocols" indicando que o servidor agora espera HTTP/2 nas mesmas conexões, ou outra coisa indicando que HTTP/2 não é suportado.
Os navegadores não usam o HTTP Upgrade dessa maneira, eles simplesmente não suportam HTTP/2 sem TLS. (No entanto, o servidor web Apache HTTPD pode ser configurado para aceitar conexões 'h2c' para teste.)
HTTP/3
O HTTP/3 usa um protocolo de transporte diferente (QUIC vs TCP), portanto, uma atualização em linha não é possível. O navegador não sabe se o servidor pode suportar QUIC, então ele ainda faz uma conexão TCP inicial e negocia HTTP/1.1 vs HTTP/2 usando TLS ALPN como acima.
A atualização para HTTP/3 é, na verdade, iniciada pelo servidor – em suas respostas HTTP, o servidor envia o cabeçalho Alt-Svc (ou um quadro ALTSVC especial em HTTP/2) indicando que ele suporta HTTP/3 na porta UDP/QUIC especificada. O navegador pode seguir essa sugestão e tentar estabelecer uma conexão QUIC e, se for bem-sucedida, fechará a conexão TCP.