De HTTP/1.0 a HTTP/3
Qué problema resolvió cada versión: las conexiones persistentes de HTTP/1.1, el formato binario y la multiplexación de HTTP/2, y el salto a QUIC sobre UDP de HTTP/3.
HTTP/1.0 y HTTP/1.1
En HTTP/1.0 cada petición abría su propia conexión TCP y la cerraba al terminar. Para una página con una hoja de estilos y veinte imágenes eso son veintidós conexiones abiertas y cerradas, cada una con su saludo de tres pasos, y el coste se nota.
HTTP/1.1 introdujo las conexiones persistentes: la conexión se mantiene abierta por defecto y sirve para varias peticiones seguidas. Es lo que refleja la cabecera Connection: keep-alive, que en HTTP/1.0 había que pedir expresamente y en HTTP/1.1 ya es el comportamiento normal.
- Host obligatorio, lo que hizo posible alojar varios sitios en una misma dirección IP.
- Transferencia por trozos con Transfer-Encoding: chunked, para enviar respuestas sin conocer su tamaño de antemano.
- Peticiones por rangos con Range, que permiten reanudar una descarga interrumpida.
- Pipelining: enviar varias peticiones seguidas sin esperar respuesta. Apenas se usó, porque las respuestas seguían teniendo que llegar en orden y una lenta bloqueaba a todas las de detrás.
El límite que arrastra toda la familia 1.x es que por una conexión solo puede ir una petición a la vez. Todo lo que viene después nace de intentar romper ese límite.
Para el examen
Novedades de HTTP/1.1: conexiones persistentes, Host obligatoria y respuestas por trozos
Qué permitió el Host: los hosts virtuales por nombre
HTTP/2: binario y multiplexado
HTTP/2 mantiene intacta la semántica de HTTP: los mismos métodos, los mismos códigos de estado y las mismas cabeceras. Lo que cambia por completo es cómo se transmite todo eso. Deja de ser texto y pasa a ser binario, lo que lo hace más compacto y menos ambiguo de interpretar, a cambio de que ya no se pueda leer con un simple telnet.
Sobre ese formato binario se construyen dos conceptos. El frame o trama es la unidad mínima de intercambio, y los tipos que más importan son DATA, que transporta el cuerpo, y HEADERS, que transporta las cabeceras. El stream o flujo es una secuencia de frames que corresponde a un intercambio de petición y respuesta.
Con esas dos piezas aparece la multiplexación: por una única conexión TCP viajan a la vez muchos streams, con sus frames entrelazados. El navegador ya no tiene que abrir seis conexiones ni esperar a que termine una descarga para empezar la siguiente, y la imagen, la hoja de estilos y el script llegan en paralelo por el mismo canal. Es el cambio que más se nota en el tiempo de carga.
Sobre el cifrado hay que ser preciso, porque el error circula mucho: HTTP/2 no lleva cifrado dentro, y su especificación define dos modos, h2 sobre TLS y h2c en claro. Lo que ocurre es que ningún navegador implementa h2c, de modo que en la práctica HTTP/2 siempre llega sobre TLS. Cuál de las dos versiones se va a hablar se decide dentro del propio saludo TLS mediante la extensión ALPN.
Frame es la unidad mínima, stream es la secuencia de frames de un intercambio, y multiplexar es entrelazar varios streams en una sola conexión.
Para el examen
Formato: BINARIO
Qué hace con las peticiones: las multiplexa en una sola conexión
Qué elimina: el bloqueo de cabecera de línea a nivel de aplicación
Lo demás que trajo HTTP/2
HTTP/2 no se diseñó desde cero: derivó de SPDY, un protocolo experimental de Google que ya había demostrado en producción que la multiplexación funcionaba. SPDY se retiró cuando HTTP/2 quedó estandarizado.
- Compresión de cabeceras, de serie y con el algoritmo HPACK. Como las cabeceras se repiten casi idénticas en todas las peticiones de una misma página, comprimirlas y no reenviar lo que ya se envió ahorra mucho.
- Priorización de flujos: el cliente puede indicar qué streams le interesan antes, para que la hoja de estilos que bloquea el dibujado no espere detrás de una imagen del pie de página.
- Server push: el servidor puede enviar recursos que el cliente todavía no ha pedido pero que sabe que va a necesitar. Es la idea que HTTP/1.1 no tenía y que se suplía con trucos desde la propia página. Se usó poco y los navegadores acabaron retirándolo.
Queda un problema que HTTP/2 no puede resolver por sí mismo: aunque los streams sean independientes para HTTP, todos viajan por la misma conexión TCP, y TCP entrega en orden. Si se pierde un segmento, todos los streams se paran hasta que llegue la retransmisión. Ese bloqueo residual es la razón de ser de HTTP/3.
Para el examen
Compresión de cabeceras: HPACK
Otras novedades: prioridades y empuje desde el servidor
Lo que no cambia: la semántica: métodos y códigos siguen igual
HTTP/3 y QUIC
HTTP/3 conserva otra vez la semántica del protocolo, pero cambia el transporte, que es el cambio más profundo de los tres. En lugar de TCP se apoya en QUIC, un protocolo de transporte que va sobre UDP y que implementa por su cuenta el control de fiabilidad, el control de flujo y la seguridad.
- Los flujos son independientes de verdad: la pérdida de un paquete solo detiene al flujo afectado, no a los demás.
- TLS 1.3 va integrado en el propio QUIC, así que no hay un saludo de transporte y otro de cifrado, sino uno solo. Establecer la conexión cuesta muchos menos viajes de ida y vuelta.
- La conexión se identifica por un identificador propio y no por la terna de direcciones y puertos, de forma que un móvil puede pasar de la red móvil a una red inalámbrica sin perder la sesión.
- La compresión de cabeceras se hace con QPACK, adaptado para que no dependa del orden de llegada.
La frase que hay que retener es que HTTP/3 va sobre QUIC y QUIC va sobre UDP. Si una opción dice que HTTP/3 sigue sobre TCP, está mal.
Para el examen
Sobre qué va: sobre QUIC
Y QUIC sobre qué: sobre UDP
Qué resuelve: el bloqueo de cabecera de línea del transporte, y cifra por diseño
Las tres versiones de un vistazo
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| Formato | Texto | Binario | Binario |
| Transporte | TCP | TCP | QUIC sobre UDP |
| Peticiones por conexión | Una a la vez | Muchas multiplexadas | Muchas multiplexadas e independientes |
| Cabeceras | Sin comprimir | HPACK | QPACK |
| Cifrado | Opcional (HTTPS) | Opcional en la norma, obligatorio en la práctica | TLS 1.3 integrado en QUIC |
Las tres conviven hoy y las tres hablan el mismo HTTP: un GET sigue siendo un GET y un 404 sigue siendo un 404 en cualquiera de ellas. Lo que se negocia al conectar es solo el formato del transporte.
Para el examen
HTTP/1.1: texto, sobre TCP
HTTP/2: binario y multiplexado, sobre TCP
HTTP/3: sobre QUIC y UDP