HTTP/2 constitue la dernière version majeure du protocole réseau HTTP.
Cette nouvelle version a été élaborée sur la base du projet expérimental SPDY de Google et a pour objectif principal d’améliorer la vitesse des échanges de ressources sur le World Wide Web : Pages HTML, scripts Javascript, feuilles de styles, images, etc…
Pour mémoire, HTTP 1.0 date de 1995 et la version 1.1 de 1997. La dernière mise à jour a été publiée en 1999.
La spécification HTTP/2 a été publiée le 15 mai 2015 sous la RFC 75401.
Objectif
Le projet SPDY de Google visait à combler les lacunes de HTTP 1.1 pour faire face à l’accroissement du nombre de requêtes à traiter et de l’augmentation très nette des éléments échangés entre clients et serveurs afin d’éviter les engorgements et les attentes côté client (Head of line blocking)
Des palliatifs tels que l’usage de sprites, du sharding ou de l’inlining ont permis de contourner ces lacunes souvent au prix de développements spécifiques.
L’objectif principal a donc été d’améliorer sensiblement la vitesse des échanges entre le navigateur et le serveur.
Concepts et limites de HTTP/2
Les fondements du protocole HTTP sont maintenus, L’API ne change pas, seule l’implémentation évolue. : Le client envoie une requête vers le serveur en TCP. :
- Les URLs http:// et https:// ne doivent pas changer. HTTP/2 sait donc gérer les URIs actuelles. En clair, il n’y a pas d’URI commençant par http2:// ou http2s://
La bascule HTTP 1.x vers HTTP/2 se fait à l’initiative du client s’il supporte la version 2. Pour se faire il renvoie vers le serveur l’en-tête « UPGRADE » déjà supporté par HTTP 1.x Si le serveur supporte HTTP/2 il renvoie le code « 101 Switching » et les 2 parties basculent vers HTTP/2, cela au prix d’un aller-retour réseau supplémentaire.
- Pas de nouvelles méthodes (verbes) introduites dans le protocole
- Compatibilité garantie entre HTTP1 et HTTP/2 au niveau
- des URIs
- des méthodes GET, POST, UPDATE…
- des codes retour 200, 401, 404, 550 qui auront toujours la même signification
- des entêtes (headers)
- Maintient opérationnel du protocole HTTP 1 pour encore plusieurs décennies ; une bascule HTTP 1.x vers HTTP/2 ou HTTP /2 vers HTTP 1.x doit être possible, via des proxies par exemple
- Il n’y aura pas de version mineure du protocole HTTP /2. S’il est nécessaire d’étendre le protocole ce sera dans le cadre d’HTTP3
En résumé, les fondements du protocole HTTP restent inchangé avec cette nouvelle version.
HTTP/2 et la sécurité
La spécification HTTP/2 n’impose pas l’utilisation d’un protocole sécurisé.
Toutefois, beaucoup d’acteurs du Web comme Mozzila ou Google souhaitent que HTTP/2 ne soit utilisé que conjointement avec TLS. A tel point que Firefox ou Chrome utilisent HTTP/2 uniquement qu’avec TLS (Idem pour Microsoft Edge) Dans le cas contraire ils basculent vers HTTP 1.1. Malgré les nombreux débats autour de ce sujet, la spécification finale indique qu’en cas d’utilisation de TLS c’est la version 1.2 qui doit être utilisée au minimum avec une liste restreintes d’algorithmes (ciphers)
Pour information, Internet Explorer et l’outil « curl » supporte HTTP/2 en clair (sans l’usage de TLS)
Le protocole pour négocier l’utilisation de HTTP/2 avec un serveur TLS est ALPN (Application-Layer Protocol Negociation). Avec ALPN, le client indique au serveur la liste des protocoles
ainsi que ses préférences, le serveur ayant le dernier mot.
Dans les faits, l’usage de HTTP/2 se fera donc conjointement avec des serveurs sécurisant leurs connexions avec TLS 1.2 au minimum. En conséquence, les serveurs doivent implémenter également le protocole ALPN.
En complément, OpenSSL supporte ALPN depuis la version 1.0.2
Fonctionnement
Format des échanges
Http2 est un protocole binaire, contrairement à HTTP 1.x qui est textuel donc lisible par un être humain. L’objectif est de faciliter le découpage des trames et de compresser le flux réseau.
Http2 envoie donc des trames binaires de différents types dont le format est toujours le même : Longueur, Type, Flags, Identifiant de Flux (Stream ID) et contenu (payload).
Http2 définit dix trames différentes ; 2 sont fondamentales car répliquent le fonctionnement HTTP
1.1 : DATA (données ou contenu) et HEADERS (en-tête)
Multiplexage de flux
Certainement l’élément clef du gain de performance apporté par Http/2.
Une trame (frame) est la plus petite unité de communication au sein d’une connexion HTTP/2 et comporte un en-tête et une séquence d’octets de longueur variable dont la structure correspond au type de trame.
Un flux (stream) est un flot bidirectionnel de trames au sein d’une connexion HTTP/2. La notion correspondante dans HTTP/1 est un échange de messages de type requête et réponse. Chaque flux dispose d’un identifiant unique et peu éventuellement porter une information relative à sa priorité.
En résumé, le mode requête/réponse bloquant de HTTP/1 est caduque. Avec HTTP/2 le client peut émettre plusieurs requêtes successivement sans attendre d’avoir obtenu une réponse. De même, le serveur peut envoyer au client les réponses dans un ordre différent des requêtes.
Priorités et dépendances
HTTP/2 prévoit également la possibilité d’octroyer une priorité à chaque flux et de définir les dépendances entre les flux. Cela permet au client d’influer sur le serveur en précisant quelles ressources sont à renvoyer en pririté et dans quel ordre. L’objectif étant d’améliorer le rendu visuel des pages lors du dialogue entre le client et le serveur.
Gestion des entêtes (headers)
HTTP/2 compresse les headers au format HPACK. Il est courant d’utiliser une compression GZIP actuellement sur les sites web mais celle-ci ne compresse pas les entêtes.
Le format de compression HPACK a été spécialement développé pour HTTP/2 afin de répondre aux exigences de sécurité grâce à l’algorithme d’encodage de Huffman ;
HTTP/2 optimise les flux en ne répétant pas les headers inchangés. Le client et le serveur maintiennent une table indexée des headers. Cela permet lors de requêtes successives de n’envoyer que l’index du header déjà fourni ; le client/serveur reconstruira la liste complète des headers en utilisant la table indexée à sa disposition.Très efficace par exemple avec les headers comme User-Agent ou Cookies.
Push
Toujours dans l’optique d’améliorer le temps de chargement des pages, le serveur peut de son propre chef renvoyer des ressources vers le client avant même qu’il en ait fait la demande car il sait d’avance ce que le client va lui demander. Ces ressources seront stockées en cache côté client afin d’être immédiatement disponibles quand il en aura besoin.
Concrètement, le serveur déclenche le « push » en créant un nouveau flux (stream) avec une trame PUSH_PROMISE contenant tous les headers HTTP de la ressource. A la réception de cette trame, le client peut accepter le push du serveur ou le refuser, par exemple si la ressource est déjà en cache. Dans ce cas il renvoie immédiatement une trame RST_STREAM pour arrêter le flux.
Interruption des connexions
Avec HTTP, si un logiciel client envoie une requête et décide de ne plus attendre la réponse, la seule façon de préserve la bande passante est de fermer la connexion TCP. Il n’y a aucune façon de la récupérer si cela s’avère nécessaire plus tard.
Avec HTTP/2, un logiciel client pourra maintenir active une connexion TCP même s’il abandonne un échange en cours à la suite d’une action de l’utilisateur (avec la trame RST_STREAM), ce qui rendra moins coûteuse en ressources réseaux une éventuelle reprise du dialogue ultérieurement.
Résumé
- 1 seule connexion TCP entre le client et le serveur
- Utilisation de flux (streams) pour échanger les données au sein de la connexion. Un flux est
- multiplexé
- priorisé
- Nouveau format binaire d’échange de données incluant
- un contrôle de flux
- une priorisation
- un push serveur
- La compression des en-têtes (hearders) via HPACK
Du côté des navigateurs
La plupart des navigateurs du marché support HTTP/2 depuis un bon moment maintenant :
Mozzila Firefox et Google Chrome propose une extension qui permet de savoir si le site que vous parcourez utilise HTTP/2 :
- Firefox : HTTP/2 Indicator
- Chrome : HTTP/2 and SPDY indicator
Le support de HTTP/2 est indiqué par un éclair bleu dans la barre supérieure des 2 navigateurs.
Du côté des serveurs
HTTP/2 est pris en charge dans l’API Servlet 4.0 (JSR 369) de JEE 8.
Les serveurs HTTP et serveurs d’application Java supportant déjà HTTP/2 (en date de septembre 2019) :
- Apache à partir de la version 2.4.17 via le module mod_http2
- Apache Tomcat à partir de la version 8.5
- HAProxy à partir de la version 1.8
- Jetty à partir de la version 9.3
- Microsoft IIS supporte HTTP/2 avec Windows 10 and Windows Server 2016.
- nginx à partir de la version 1.9.5 via le module ngx_http_v2_module
Support du mode Push depuis la version 1.13.9 - Wildfly à partir de la version 9
Conclusion
HTTP/2 apporte son lot d’évolutions à un protocole vieillissant et plus trop adapté au web moderne. Les gains de performance espérés par le multiplexage et le format binaire des échanges sont à relativiser avec l’utilisation de TLS rendue obligatoire par les principaux navigateurs du marché. Sa mise en application rend obsolète, voire contre-productive, certaines optimisations utilisées avec HTTP 1.x telles que le Sharding, l’inlining, etc… Comment faire quand un site web doit adresser des clients HTTP 1.x et HTTP/2 s’il veut en tirer le meilleur parti ?
Oracle WebLogic Server est le grand absent des serveurs d’application Java supportant HTTP/2 mais gageons que cette situation n’est que temporaire et sera réglée avec la prochaine version 12.2.1.4
HTTP/2 n’est pas encore déployé partout mais la suite est déjà en préparation chez Google avec QUIC.
Sources et références
Les pages suivantes ont été utilisées pour rédiger cet article :
- Guide HTTP/2 du serveur HTTP Apache
- http2 explained : Une ou la référence en la matière
- Wikipédia – Hypertext Transfer Protocol/2Hypertext Transfer Protocol/2
- Vidéo de la conférence « HTTP/2 101 (Chrome Dev Summit 2015) »