Quand tu tapes une adresse dans ton navigateur et que la page s'affiche,
une conversation a eu lieu entre ton navigateur et le serveur.
Cette conversation suit un protocole précis, le HTTP (HyperText Transfer Protocol).
C'est le protocole qui fait fonctionner le web.
Chaque page que tu visites, chaque image qui s'affiche, chaque formulaire
que tu soumets passe par lui. Il a été imaginé au début des années 1990 par
Tim Berners-Lee au CERN, avec un objectif assez modeste, permettre à un document
de pointer vers un autre document situé sur une autre machine.
Trente-cinq ans plus tard, il transporte à peu près tout ce que tu fais en ligne.
Requête et réponse
HTTP fonctionne sur un modèle simple. Le client demande, le serveur répond.
Jamais l'inverse, un serveur HTTP ne prend pas l'initiative de te contacter.
Quand tu cliques sur un lien, ton navigateur envoie une requête HTTP au serveur.
Cette requête contient quatre choses.
- La méthode : ce que le client veut faire. GET pour récupérer, POST pour envoyer, PUT ou PATCH pour modifier, DELETE pour supprimer.
- L'URL : l'adresse de la ressource demandée, par exemple /produits/42 pour le produit numéro 42.
- Les en-têtes, ou headers : des métadonnées sur la requête. "Je veux du JSON", "voici mon cookie de session", "j'accepte le français et l'anglais", "voici quel navigateur je suis".
- Le corps, ou body : les données envoyées avec la requête, pour un POST ou un PUT. Les champs d'un formulaire d'inscription, par exemple. Une requête GET n'a normalement pas de corps.
Le serveur traite la requête et renvoie une réponse construite sur le même modèle.
- Un code de statut : un nombre qui résume ce qui s'est passé. 200 veut dire que tout va bien, 404 que la ressource n'existe pas, 500 qu'il y a eu une erreur côté serveur. Nous consacrons le chapitre suivant à ces codes.
- Des en-têtes : des métadonnées sur la réponse. "Le contenu est du HTML", "cette page peut être mise en cache une heure", "voici un cookie à conserver".
- Le corps : le contenu demandé. Le HTML de la page, le JSON d'une API, les octets d'une image.
La chose peut surprendre, mais HTTP est un protocole textuel, du moins jusqu'à sa version 1.1 incluse. Une requête ressemble littéralement à ça.
GET /produits/42 HTTP/1.1
Host: boutique.example.com
Accept: application/json
Accept-Language: fr-FR
Cookie: session=a1b2c3d4Et la réponse ressemble à ça, avec une ligne vide qui sépare les en-têtes du corps.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=3600
{"id": 42, "nom": "Chaise de bureau", "prix": 149.90}Les méthodes comptent vraiment
On pourrait croire que le choix entre GET et POST est une coquetterie de développeur.
C'est en réalité un contrat avec tout l'écosystème du web.
Un GET est censé ne rien changer. Il se contente de lire.
Par conséquent, un navigateur, un proxy ou un
CDN se sentent parfaitement autorisés à le mettre en cache,
à le rejouer, ou à le déclencher à l'avance pour gagner du temps.
Un POST, lui, modifie quelque chose, donc personne ne se permet de le rejouer tout seul.
C'est aussi pour ça que ton navigateur t'affiche un avertissement quand tu rafraîchis
une page obtenue après l'envoi d'un formulaire. Il te demande la permission de renvoyer
le POST, parce qu'il sait qu'il pourrait créer une deuxième commande.
Exemple :
Une équipe met en place une suppression de produit accessible par un lien, donc en GET, du type /produits/42/supprimer. Ça fonctionne parfaitement en test. En production, le robot d'indexation de Google parcourt le site, suit consciencieusement tous les liens qu'il trouve, et vide le catalogue. L'erreur n'est pas technique, elle est contractuelle, une lecture n'a pas le droit de détruire quoi que ce soit.
HTTP est sans état
Chaque requête HTTP est indépendante. Le serveur ne se souvient pas de la précédente.
Il ignore que tu as visité la page d'accueil il y a trente secondes.
C'est ce qu'on appelle un protocole sans état, ou stateless.
Le choix est délibéré, puisqu'il simplifie énormément le serveur et lui permet
de traiter des millions de requêtes sans garder en mémoire l'historique de chaque visiteur.
C'est aussi ce qui autorise à répartir le trafic sur cent machines identiques,
chacune pouvant répondre à n'importe qui à n'importe quel moment.
Reste une question évidente, comment savoir que tu es connecté si le serveur oublie tout
entre deux requêtes ? C'est là qu'interviennent les
cookies. Le navigateur renvoie automatiquement
un identifiant de session à chaque requête, et c'est cet identifiant
qui permet au serveur de te reconnaître. L'état existe donc bien,
mais il est reconstruit à chaque fois, il ne vit pas dans le protocole.
HTTPS, le cadenas
HTTP a un défaut majeur, tout circule en clair.
N'importe qui placé sur le chemin peut lire les données échangées,
les mots de passe, les numéros de carte bancaire, les messages privés.
Le Wi-Fi gratuit d'un aéroport est l'exemple type de l'endroit
où ça devient une très mauvaise idée.
HTTPS, le S signifiant Secure, résout le problème en glissant une couche de
chiffrement appelée TLS entre le navigateur
et le serveur. Les données sont chiffrées avant l'envoi et déchiffrées à l'arrivée.
Un intercepteur ne voit plus que du charabia.
Le chiffrement n'est d'ailleurs qu'une moitié du travail.
L'autre moitié est l'authentification. Le certificat présenté par le serveur
prouve qu'il est bien celui qu'il prétend être, ce qui évite qu'un intermédiaire
se fasse passer pour ta banque tout en chiffrant parfaitement la conversation.
Aujourd'hui, HTTPS est la norme absolue. Les certificats sont devenus gratuits
et automatiques, les navigateurs signalent les pages en HTTP comme non sécurisées,
et Google en fait un critère de classement dans ses résultats de recherche.
Il n'existe plus de bonne raison de servir un site en HTTP.
Les versions de HTTP
Le protocole a évolué par étapes, presque toujours pour la même raison, la performance.
- HTTP/1.0, en 1996 : une connexion par requête. Pour charger une page contenant dix images, le navigateur ouvrait et refermait dix connexions successives. Lent, et coûteux pour le serveur.
- HTTP/1.1, en 1997 : les connexions restent ouvertes et sont réutilisées, ce qu'on appelle le keep-alive. Les requêtes sont toutefois traitées une par une dans l'ordre, donc une réponse lente bloque toutes celles qui suivent. Les navigateurs contournaient le problème en ouvrant six connexions en parallèle par domaine.
- HTTP/2, en 2015 : le multiplexage. Plusieurs requêtes et réponses circulent en parallèle sur une seule connexion, sans ordre imposé. Les en-têtes, très répétitifs d'une requête à l'autre, sont aussi compressés.
- HTTP/3, en 2022 : le transport passe de TCP à QUIC, un protocole construit au-dessus d'UDP. La connexion s'établit en moins d'allers-retours et une perte de paquet ne bloque plus l'ensemble des échanges. C'est particulièrement sensible sur les réseaux mobiles instables.
Bonne nouvelle, ces améliorations sont transparentes. Le navigateur et le serveur négocient au moment de la connexion la meilleure version qu'ils supportent tous les deux, et retombent sur l'ancienne si besoin. Côté produit, il n'y a rien à faire, si ce n'est vérifier de temps en temps que ton hébergeur ou ton CDN t'a bien fait bénéficier des versions récentes. C'est souvent quelques dizaines de millisecondes gagnées sur chaque page, sans écrire une ligne de code.