Le protocole HTTP
Le protocole HTTP (HyperText Transfer Protocol) est un protocole de communication client-serveur.
HTTP est un protocole qui permet le transfert de données — principalement des pages web — entre un client (généralement un navigateur web) et un serveur.
Il s’agit d’un protocole sans état (→ stateless), c’est-à-dire que chaque requête est indépendante des précédentes.
Il a été créé en 1989 par Tim Berners-Lee dans le cadre du développement du World Wide Web.
Fonctionnement
Le protocole HTTP (port 80 par défaut) fonctionne selon un modèle requête-réponse :
-
Le client envoie une requête HTTP au serveur, contenant :
-
Une méthode (GET, POST, etc.)
-
L’URL de la ressource demandée
-
La version du protocole
-
Des en-têtes avec des informations supplémentaires2
-
-
Le serveur traite la requête et renvoie une réponse HTTP comprenant :
-
Un code de statut (200 OK, 404 Not Found, etc.)
-
Des en-têtes
-
Le corps de la réponse contenant les données demandées.
-
Versions
Le protocole a évolué au fil du temps :
-
HTTP/0.9 : Version initiale (1989)
-
HTTP/1.0 : Première version standardisée (1996)
-
HTTP/1.1 : Version la plus utilisée, introduisant des améliorations de performance (1997)
-
HTTP/2 : Version majeure apportant des optimisations significatives (2015)
-
HTTP/3 : Dernière version basée sur le protocole QUIC (en cours d’adoption).
Sécurité
La version sécurisée de HTTP, appelée HTTPS, utilise le port 443 et s’appuie sur le protocole TLS pour chiffrer les communications entre le client et le serveur.
GET vs. POST
Ce qui suit illustre le contenu des messages HTTP échangés entre un navigateur et un serveur au cours de l’utilisation d’une application web élémentaire qui se limite à un formulaire.
Cette application a été développée en Python avec le framework Flask qui utilise par défaut le port 5000 pour HTTP et non le port 80. |
Cet exemple vise à montrer les différences entre une requête GET et une requête POST en terme de transmission de données :
-
GET ajoute les données de formulaire à l’URL sous forme de paramètres de requête.
Par exemple :example.com/page?param1=value1¶m2=value2
-
POST envoie les données de formulaire dans le corps de la requête HTTP, séparément de l’URL.
Ci-dessous les échanges protocolaires au niveau application HTTP (→ APDU : Application Protocol Data Unit) correspondants à la vidéo précédente :
-
Client → Serveur : Requête GET pour accéder à la racine du site
GET / HTTP/1.1 Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8 Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br, zstd Connection: keep-alive Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Priority: u=0, i ␍␊ ␍␊
-
Serveur → Client : Réponse du serveur avec la page d’accueil
HTTP/1.1 200 OK Server: Werkzeug/3.0.3 Python/3.12.5 Date: Tue, 01 Oct 2024 15:08:34 GMT Content-Type: text/html; charset=utf-8 Content-Length: 736 Connection: close ␍␊ ␍␊ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Flask Forms Example</title> </head> <body> <h1>Exemple de formulaire</h1> <h2>Soumission par GET</h2> <form action="/submit_get" method="GET"> <label for="nom">Nom :</label> <input type="text" id="nom" name="name" required> <button type="submit">Soumettre (GET)</button> </form> <h2>Soumission par POST</h2> <form action="/submit_post" method="POST"> <label for="nom">Nom :</label> <input type="text" id="nom" name="name" required> <button type="submit">Soumettre (POST)</button> </form> </body> </html>
-
Client → Serveur : Soumission du formulaire avec requête GET
GET /submit_get?name=Ragnar HTTP/1.1 (1) Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,/;q=0.8 Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br, zstd Connection: keep-alive Referer: http://127.0.0.1:5000/ Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin Sec-Fetch-User: ?1 Priority: u=0, i ␍␊ ␍␊
1 La donnée de formulaire est envoyée en tant que paramètre dans l’URL -
Serveur → Client : Réponse du serveur avec une page web intégrant la donnée de formulaire
HTTP/1.1 200 OK Server: Werkzeug/3.0.3 Python/3.12.5 Date: Tue, 01 Oct 2024 15:08:50 GMT Content-Type: text/html; charset=utf-8 Content-Length: 332 Connection: close ␍␊ ␍␊ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Form Result</title> </head> <body> <h1>Résultat de la soumission de formulaire</h1> <p>Bonjour, Ragnar! (GET)</p> (1) <a href="/">Retour au formulaire</a> </body> </html>
1 Valeur soumise via le formulaire -
Client → Serveur : Soumission du formulaire avec requête POST
POST /submit_post HTTP/1.1 Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,/;q=0.8 Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br, zstd Content-Type: application/x-www-form-urlencoded Content-Length: 11 Origin: http://127.0.0.1:5000 Connection: keep-alive Referer: http://127.0.0.1:5000/ Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin Sec-Fetch-User: ?1 Priority: u=0, i ␍␊ ␍␊ name=Ragnar(1)
1 la donnée de formulaire est transmise dans la requête, à la suite de l’entête -
Serveur → Client : Réponse du serveur avec page web intégrant la donnée de formulaire
HTTP/1.1 200 OK Server: Werkzeug/3.0.3 Python/3.12.5 Date: Tue, 01 Oct 2024 15:08:56 GMT Content-Type: text/html; charset=utf-8 Content-Length: 333 Connection: close ␍␊ ␍␊ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Form Result</title> </head> <body> <h1>Résultat de la soumission de formulaire</h1> <p>Bonjour, Ragnar! (POST)</p> (1) <a href="/">Retour au formulaire</a> </body> </html>
1 Valeur soumise via le formulaire
🞄 🞄 🞄