HTTP2, el nuevo Fast & Furious del protocolo

Todos hemos oído hablar del nuevo protocolo, pero la realidad es que estamos tardando en adaptarnos bastante en los desarrollos actuales ya que dependemos plenamente de la evolución de los conectores en la parte servidora y de los navegadores en la parte cliente; no obstante su uso nos proporcionará sustanciosas ventajas que veremos a continuación.

Por qué Fast & Furious

  • Fast porque es la principal ventaja en conjunto que nos ofrece HTTP/2, es más ligero y ofrece un rendimiento mucho más alto debido a las mejoras incorporadas, algunas de ellas son: compresión de cabeceras, multiplexación, mensajes binarios y “server push”.
  • Furious: este aspecto es mucho más subjetivo, la verdad es que todos deberíamos de estar “enfadados” porque llevamos 30 años buscando alternativas poco elegantes para mejorar el performance de nuestras webs cuando la clave siempre ha estado en rediseñar el protocolo. Han pasado 30 años y nos hemos buscado la vida con compresiones de todo tipo de ficheros, sirviendo contenidos con diferentes dominios para poder paralelizar descargas, cachés por todos los lados, optimización de imágenes… “Hemos matado moscas a cañonazos” y no hemos abordado la raíz del problema hasta ahora.

La evolución temporal de http ha sido:

Referencia histórica, ¿de dónde venimos?

Hypertext Transfer Protocol es el protocolo de comunicación que permite las transferencias de información en la World Wide Web. HTTP fue desarrollado por el World Wide Web Consortium y la Internet Engineering Task Force en 1996, colaboración que culminó en 1999-2000.

La versión 1.1. HTTP definió la sintaxis y la semántica que utilizan los elementos de software de la arquitectura web (clientes, servidores, proxies) para comunicarse.

HTTP en todas sus versiones es un protocolo sin estado, es decir, no guarda ninguna información sobre conexiones anteriores.

En HTTP/1.x las peticiones son bloqueantes y se resuelven de forma ordenada, lo cual será rediseñado por completo en HTTP/2.

HTTP/1.x y HTTP/2 comparten los mismos componentes del protocolo:

  • Cabeceras: es información complementaria para el servidor, para el cliente o para ambos, mediante la cual se pueden incorporar nuevas funcionalidades sin alterar el mensaje. Facilitan la integración con middleware (proxy, sistemas de seguridad…) y nos permiten mantener estado en las peticiones (cookies). Existen predefinidas (Accept-Language , Location, Content-Type, Referer, Cache-Control…) y se pueden crear “custom” para lo que se necesite.
  • Métodos: con el auge de las API’s RESTful todo el mundo los conoce como verbos. Cada uno de ellos indica por convención un tipo de operación y un funcionamiento.

El protocolo está preparado para añadir fácilmente más si fueran necesarios aunque existen muchos predefinidos para su uso HEAD, GET, POST, PUT, DELETE, TRACE, OPTIONS, PATCH, SEARCH, COPY, LOCK ,UNLOCK, MOVE…

  • Códigos de respuesta: son los producidos por el servidor hacia el cliente, se componen de un código y de una descripción. Según al grupo que pertenezcan significan una cosa u otra:
    • 1xx: respuestas informativas. Indica que la petición ha sido recibida y se está procesando.
    • 2xx: respuestas correctas. Indica que la petición ha sido procesada correctamente.
    • 3xx: respuestas de redirección. Indica que el cliente necesita realizar más acciones para finalizar la petición.
    • 4xx: errores causados por el cliente. Indica que ha habido un error en el procesado de la petición, por seguridad, el cliente ha hecho algo mal…
    • 5xx: errores causados por el servidor.
  • Mensajes: los mensajes HTTP/1.x son en texto plano eso los hace más legibles, más largos y sobre todo más inseguros. Los mensajes contienen la siguiente estructura:
    • Línea inicial (url, verbo, versión http, código de respuesta…).
    • Cabeceras.
    • Cuerpo del mensaje (opcional).

Lo visto hasta ahora no es nada novedoso, es lo que hemos tenido hasta ahora. La gran ventaja es que los componentes para HTTP/2 serán exactamente los mismos, de hecho, de cara a nuestra programación debería de ser transparente siempre y cuando cliente y servidor posean la  implementación del nuevo protocolo.

SPDY, ¿es el origen de HTTP/2?

Como suele ocurrir en este mundillo que nos movemos, los grandes siempre abren puertas que para los mortales están cerradas.

Este es el caso de Google que, dándose cuenta de la ineficiencia de las webs, quiso atajar el problema por la raíz intentando crear un protocolo que le aportara esa velocidad que las webs de hoy en día necesitan.

Haremos una referencia a SPDY para que una vez acabada la lectura, tú mismo valores las similitudes existentes con HTTP/2.

Las principales características de SPDY eran:

  • Trabajaba a nivel de sesión TCP/IP, por lo cual no altera el protocolo Http.
  • Mantenía con una sola conexión TCP múltiples peticiones Http (multiplexado).
  • Era binario, de tal modo que un texto de 500 bytes en ASCII en binario no ocuparán más de 2 bytes.
  • Capaz de comprimir las cabeceras (Gzip).
  • En pruebas mejoraba hasta un 60% el performance de las webs.
  • SPDY solo se ejecuta sobre SSL (perjudicial para el cacheo pero seguro por defecto).
  • Tuvo un intento de web sockets.

¡HTTP/2 en acción!

Antes de entrar en profundidad en las características del protocolo, vamos a demostrar visualmente su funcionamiento.

Los ejemplos comparativos típicos proceden de los CDN’s, que son los principales impulsores del protocolo ya que son lo más beneficiados de su uso al beneficiar la velocidad de descarga de los recursos de las webs. Podemos ver un par de ejemplos en IMAGEKIT.IO y AKAMAI.

HTTP/2… ¡Comenzamos!

Se le denominó HTTP/2 y no HTTP/2.0 para evitar confusiones y desmarcarse de las versiones HTTP/1.x , eliminaron la “minor version”. Fue creado en 2015 por The Internet Engineering Task Force (IETF), la misma entidad que creó su predecesor.

No obstante, ha sido apoyado y empujado por grandes empresas como: Firefox, Chrome, Twitter, Microsoft’s HTTP stack, curl y Akamai… todas muy interesadas en su evolución e implantación.

Posee una especificación formal para el protocolo y otra para la compresión de las cabeceras. Aunque el algoritmo de compresión fue creado específicamente para el protocolo, decidieron hacer una especificación desacoplada para que pudieran evolucionar de modo independiente.

Antes de describir las características fundamentales del protocolo es importante destacar, como antes hemos visto, que HTTP/2 es plenamente compatible con HTTP/1.x, ya que trabaja en la capa de aplicación.

Por ejemplo, si tuviéramos una web en un apache y cambiamos el conector a HTTP/2 y el navegador lo soporta, no tendríamos que tocar absolutamente nada, ese es el término “compatible” al que me refiero.

Las claves de la potencia de HTTP/2 son:

  • Es binario, no maneja texto plano como Http/1.x.
  • Es multiplexado, en lugar de secuencial y bloqueante. Usa una conexión para establecer la ejecución en paralelo.
  • Usa compresión de las cabeceras, reduce tamaño y en consecuencia overhead.
  • Permite a los servidores hacer “push” proactivamente a las caches de los clientes. ¡No confundir con el concepto “server push”! que hacemos con websockets, por ejemplo.

Binario es mejor  

Los protocolos binarios con respecto a los que manejan texto en sus comunicaciones (peticiones y respuestas) ofrecen un conjunto de ventajas:

  • Más eficientes en el parseo, serialización, deserialización…
  • Mensajes más cortos, lo cual implica menos transferencia de red. Son más compactos ya que las partes que los componen son más pequeñas.
  • Menos propensos a errores, no existe manipulación alguna con el contenido que se transmite. Por ejemplo con espacios en blanco, mayúsculas, terminaciones de línea, líneas en blanco…
  • Los mensajes están formados por streams, los cuales se dividen en “frames” (agrupados por un identificador) y “streamId”.

El corazón de HTTP/2 es su multiplexado

En el protocolo HTTP/1.x la descarga de recursos es secuencial, es ordenada y es limitada en el número de peticiones concurrentes, por lo tanto también podríamos afirmar que es bloqueante.

Estas características han provocado la búsqueda de estrategias para optimizar la carga de los elementos que componen las webs de hoy en día, como comentábamos al inicio del post.

La estrategia del multiplexado nos proporcionará un conjunto de características que mejorarán en gran medida las limitaciones que imponía la naturaleza del protocolo en la versión 1.x:

  • Las peticiones y respuestas del servidor serán asíncronas. Si una petición tardara más que otras, no será bloqueante en ninguno de los casos.
  • Peticiones y respuestas se realizarán en paralelo.
  • Existirá la posibilidad de forzar la priorización de ciertos contenidos y el servidor actuará en consecuencia. Por lo tanto, seremos capaces de decidir el orden de solicitud de la información.
  • Con una conexión TCP atenderemos o realizaremos múltiples llamadas HTTP, nos evitaremos la negociación y la resolución continua de los DNS.

Si tenemos varios orígenes, se abrirán múltiples conexiones TCP. Es decir, si obtenemos la información de múltiples dominios se establecerá una conexión (canal de comunicación por el cual viajarán los datos) para cada uno de ellos.

En la siguiente imagen podemos observar la evolución de los protocolos en cuanto a las comunicaciones, la gestión de recursos y su comportamiento según la versión.

Compresión de las cabeceras

Hoy en día las cabeceras HTTP van en texto plano y las usamos para añadir información de forma indiscriminada de todo tipo. Tenemos que darnos cuenta de que cualquier interacción con el servidor mediante llamada HTTP/s lleva consigo el envío implícito de las cabeceras.

Esto tiene un coste alto de transmisión de información (overhead y latencia de operaciones), ya que en muchas de las peticiones que realizamos las cabeceras serán más pesadas que el propio contenido del mensaje, si es que hay contenido, claro…

Todas estas situaciones complicaban mucho el funcionamiento ágil de las aplicaciones en dispositivos móviles, tablets… Los principales cometidos de las cabeceras a día de hoy son:

  • Cookies: almacén demasiado grande de información, a día de hoy todo cabe ahí :(
  • Datos del user-agent
  • Seguridad: JWT…
  • Trazabilidad en aplicaciones.

Como SPDY, HTTP/2 tomó la decisión de comprimir las cabeceras para que el transporte fuera mucho más ligero, pero con un algoritmo diferente. Mientras que SPDY usó GZIP como base de la compresión, los precursores de HTTP/2 lo desecharon por ser el algoritmo con más vulnerabilidades CRIME (“Compression Ratio Info-leak Made Easy”), exploits, session hijacking… y el más atacado en la historia.

HTTP/2 inventó el algoritmo de compresión HPACK, que es más seguro y su eficiencia es bastante razonable. Crearon una especificación al respecto paralela a la propuesta para el protocolo como comentamos anteriormente.

Para los más curiosos los detalles de la implementación de HPACK podéis encontrarlos en esté artículo.

¿”Server Push”? Mejor llamarlo “Cache Push”

No debemos confundirlo con los términos que usamos habitualmente para las notificaciones push a dispositivos y navegadores, no es lo mismo. Tampoco es lo mismo que la comunicación desde el servidor al cliente mediante websockets, es más no tiene nada que ver.

Esta es una novedad que continúa en la línea de mejorar las latencias favoreciendo a las aplicaciones directamente en el performance y, en consecuencia, a la UX.

Consiste en que el servidor será capaz de enviar información al cliente antes de que éste la solicite, es decir, el servidor intentará prever los recursos que el cliente va a necesitar y enviárselos antes a una caché especial para este propósito.

Existen varias aproximaciones para ofrecer esta funcionalidad desde los conectores, la más extendida es hacer uso de hints para guiar al navegador y qué recursos serán candidatos de hacer push, por ejemplo:

Link: </asset/to/push.js>; rel=preload; as=script

No obstante, esta parte es muy extensa y es dependiente de la propia implementación del conector. Para los que quieran profundizar os dejo un enlace de Akamai en el que se explican las estrategias disponibles y su funcionamiento mediante el uso de promesas.

Esta funcionalidad debe verse como un servicio la cual puede incluso configurarse (activar /desactivar) desde los ajustes del navegador.

HTTP/2 es seguro

En HTTP/2 el uso de cifrado TLS inicialmente era opcional, pero un gran número de fabricantes como ​Firefox, Internet Explorer o Google Chrome… ya han anunciado que sus implementaciones solo funcionaran sobre TLS. Por lo tanto, HTTP/2 servirá contenido siempre de modo seguro, lo que añadirá cierta latencia, como es natural.

Conclusión

HTTP/2 está aquí y ha venido a reemplazar por completo a las anteriores versiones del protocolo, simplemente porque es mejor en todos los aspectos. Lo más positivo es que probablemente en algunas de las piezas de nuestras arquitecturas (normalmente CDN) lo estemos usando y ni nos hemos dado cuenta.

A día de hoy la mayoría de los navegadores son compatibles y las comparativas de su uso crecen y crecen. Ha llegado el momento de aprenderlo y en la medida de lo posible apostar por él ya que llevamos 30 años esperando este cambio.

Arquitecto de profesión, pero con corazón de programador ;) Mi objetivo del día a día es aprender, disfrutar de lo que hago y enriquecerme con las personas que me rodean. Con más de 15 años en el mundo del desarrollo e intentando seguirle el ritmo a las nuevas tecnologías.

Ver toda la actividad de J. Manuel García Rozas