Vous êtes sur la page 1sur 45

HTTP : le protocole du Web passé en revue

par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Date de publication : 26/07/2009

Dernière mise à jour : 11/09/2009

HTTP est le protocole du Web. Comprendre HTTP, c'est comprendre une bonne partie du
fonctionnement du Web et une partie conséquente des enjeux d'aujourd'hui concernant la
sécurité des applications webs. Nous allons détailler dans cet article le protocole en lui-
même. Vous allez voir qu'il n'est pas spécialement simple, contrairement à ce qu'on pourrait
penser, et qu'une mauvaise compréhension ou utilisation peuvent avoir des repercussions
néfastes, notamment sur les performances, le rendu final de la réponse, voire la sécurité
du réseau. Nous nous rendrons aussi compte qu'il est complet, et qu'à ce titre on utilise
rarement son plein potenciel, à tort (même si quelques fonctionnalités sont tout de même
très spécifiques).

Cet article est publié, mais toujours en cours de conception. La date de mise à jour
indique la version.
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

I - Préambule............................................................................................................................................................... 4
II - Introduction à HTTP...............................................................................................................................................5
II-A - Définitions......................................................................................................................................................5
II-B - Historique...................................................................................................................................................... 6
II-C - Différence entre les versions........................................................................................................................ 6
II-C-1 - HTTP 0.9.............................................................................................................................................. 6
II-C-2 - HTTP 1.0.............................................................................................................................................. 6
II-C-3 - HTTP 1.1.............................................................................................................................................. 7
III - Requêtes............................................................................................................................................................... 8
III-A - Typographie..................................................................................................................................................8
III-B - Les méthodes...............................................................................................................................................9
III-B-1 - GET......................................................................................................................................................9
III-B-2 - HEAD................................................................................................................................................. 10
III-B-3 - POST................................................................................................................................................. 11
III-B-4 - PUT....................................................................................................................................................12
III-B-5 - DELETE............................................................................................................................................. 12
III-B-6 - OPTIONS...........................................................................................................................................13
III-B-7 - TRACE...............................................................................................................................................13
III-B-8 - CONNECT......................................................................................................................................... 13
IV - Réponses............................................................................................................................................................ 15
IV-A - Typographie............................................................................................................................................... 15
IV-B - Codes de retour.........................................................................................................................................15
IV-B-1 - Codes 1xx - Informations..................................................................................................................16
IV-B-1-a - 100 - Continue..........................................................................................................................16
IV-B-1-b - 101 - Switching Protocols.........................................................................................................16
IV-B-2 - Codes 2xx - Succès..........................................................................................................................17
IV-B-2-a - 200 - OK...................................................................................................................................17
IV-B-2-b - 201 - Created........................................................................................................................... 17
IV-B-2-c - 202 - Accepted......................................................................................................................... 17
IV-B-2-d - 203 - Non-Authoritative Information......................................................................................... 18
IV-B-2-e - 204 - No Content......................................................................................................................18
IV-B-2-f - 205 - Reset Content..................................................................................................................18
IV-B-2-g - 206 - Partial Content................................................................................................................ 18
IV-B-3 - Codes 3xx - Redirection................................................................................................................... 19
IV-B-3-a - 300 - Multiple Choices............................................................................................................. 19
IV-B-3-b - 301 - Permanently Redirect..................................................................................................... 20
IV-B-3-c - 302 - Found.............................................................................................................................. 20
IV-B-3-d - 303 - See Other....................................................................................................................... 20
IV-B-3-e - 304 - Not Modified....................................................................................................................21
IV-B-3-f - 305 - Use Proxy........................................................................................................................ 21
IV-B-3-g - 306 inusité................................................................................................................................ 21
IV-B-3-h - 307 - Temporary Redirect.........................................................................................................21
IV-B-4 - Codes 4xx - Erreurs client................................................................................................................ 22
IV-B-5 - Codes 5xx - Erreurs serveur............................................................................................................ 22
V - Les en-têtes......................................................................................................................................................... 23
V-A - Généraux.................................................................................................................................................... 23
V-B - D'entité........................................................................................................................................................ 23
V-C - De requête..................................................................................................................................................23
V-D - De réponse................................................................................................................................................. 23
VI - Transactions partielles........................................................................................................................................ 24
VII - Proxies............................................................................................................................................................... 26
VII-A - Définitions................................................................................................................................................. 26
VII-B - Rôles......................................................................................................................................................... 27
VII-C - La mise en place sur les clients.............................................................................................................. 28
VII-D - Exemple pratique......................................................................................................................................29
VIII - Le cache........................................................................................................................................................... 31
VIII-A - Définitions................................................................................................................................................ 31
VIII-B - Le fonctionnement................................................................................................................................... 32

-2-
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

VIII-B-1 - Au coeur du mécanisme de cache de HTTP 1.0........................................................................... 33


VIII-B-2 - Au coeur du mécanisme de cache de HTTP 1.1........................................................................... 34
VIII-B-3 - Fraicheur des données, validations et requêtes partielles..............................................................35
VIII-B-4 - Provoquer le cache ou l'éviter........................................................................................................ 36
IX - L'authentification................................................................................................................................................. 38
X - Négociation de contenu.......................................................................................................................................39
XI - Gestion des connexions TCP avec HTTP......................................................................................................... 40
XI-A - Connexions parallèles............................................................................................................................... 40
XI-B - Connexions persistantes............................................................................................................................40
XI-C - Pipelining................................................................................................................................................... 41
XII - Les outils............................................................................................................................................................42
XII-A - Les langages Web : PHP......................................................................................................................... 42
XII-B - Telnet.........................................................................................................................................................42
XII-C - Wget..........................................................................................................................................................42
XII-D - Curl........................................................................................................................................................... 43
XII-E - Outils webs............................................................................................................................................... 43
XIII - Au delà du Web avec HTTP............................................................................................................................ 44
XIV - Références....................................................................................................................................................... 45

-3-
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

I - Préambule

HTTP est l'HyperText Transfert Protocol : le protocole servant à véhiculer les pages web de l'Internet.
Le plus souvent -même si ce n'est qu'un détail- les exemples de syntaxe HTTP de cet article seront simplifiés. Un
exemple visant à démontrer l'utilisation de tel procédé ne montrera que du code le concernant, faisant l'impasse sur
certains en-têtes importants pourtant présents dans les réponses réelles. Ceci est dans un but de concision et de
clarté, en effet une transaction HTTP est souvent représentée par un flux d'informations (en-têtes) assez conséquent.
Certains en-têtes peuvent contenir des valeurs invalides, particulièrement "Content-Length" sensé représenté le poids
du message en octets. Si le lecteur s'amuse à compter le poids réel : je ne l'ai pas calculé tout le temps et ai mis
souvent des valeurs arbitraires se rapprochant de la valeur réelle (le tutoriel n'est pas écrit à partir d'un exemple
précis et concrêt, mais de multiples exemples).
Cet article n'a pas vocation à être exhaustif, ni même exempt de maladresses (même si son auteur a réellement
exercé un travail de recherche approfondi). Non, ce n'est pas la norme complète de HTTP en Français ;-)
Vraiment, je vous renvoie aux RFCs (Request For Comment) qui représentent les vraies normes (que l'on appelle
plutôt "recommendations") et dont les liens vous serons plusieurs fois suggérés. Ces RFCs sont techniques, et leur
exhaustivité laisse quelque fois à désirer. En fait elles sont claires et compréhensibles, mais elles laissent quelques
fois des flous, la plupart du temps volontaires ("les serveurs pourront alors -s'ils le souhaitent- faire ceci et celà"
"Soient 3 problèmes A B C se rapportant à un thème commun, A et B sont très nettement détaillés mais on parle à
peine de C", "Le client décidera alors ((aucun critère énoncé)) si oui ou non tel ou tel évènement"... ).

Les bases de cet article sont les RFCs cités, ainsi que des ouvrages : HTTP Developer' Handbook , de Chris Shiflett
et HTTP: The Definitive Guide des éditions O'Reilly.
Bien entendu, de nombreuses expérimentations ont été tentées pendant la rédaction de cet article. Apache est le
serveur choisi, les clients sont divers : PHP, Curl, Telnet, Firefox 3...

Notez aussi que parler du "protocole HTTP" est une bizarrerie de langue. Le "P" de HTTP signifiant "Protocol", on
devrait plutôt dire "le HTTP", plutôt que "le protocole HTTP". Mais cette appelation sera tout de même retenue dans
l'article, car elle est devenue commune dans toutes les bouches et tous les textes, elle est admise de tous.

-4-
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

II - Introduction à HTTP

HTTP est un protocole qui a été travaillé par de nombreuses personnes à partir de la fin des années 80. En sont sorties
des recommandations sous forme de RFC dont la plus importante est la RFC2616, elle définit le HTTP1.1 actuel.
Beaucoup d'autres RFCs entrent en jeu cependant dans le fonctionnement de HTTP, comme la 2617 qui décrit les
processus d'authentification, ou encore la 2109 qui décrit les mécanismes de persitance. Chaque serveur ou client
Web est tenu de l'implémenter au plus juste, et comme la recommandation laisse quelque fois des "blancs", il existe
des disparités entre les logiciels l'utilisant (clients et serveurs).
Par disparité, on pourra citer le non respect des recommandations (carrément, mais ça devient de plus en plus rare),
un respect partiel, ou encore un fonctionnement propre non décrit dans les recommandations. Les serveurs sont
plutôt "bons", c'est à dire qu'ils implémentent tous un protocole HTTP acceptable et compatible à peu près partout,
pour peu qu'ils ne datent pas d'il y a 10 ans. Heureusement, les vieux serveurs sont rares de nos jours sur Internet.
Coté navigateurs, il faut qu'il soient récents. Les navigateurs modernes sont corrects, les vieux ont des problèmes
avec HTTP de différents ordres : cache mal géré, compression de données mal ou pas supportée, en-tête ignorés...
Quoiqu'il en soit, cela représente une très maigre partie des clients HTTP d'aujourd'hui, il faudra par contre prêter
attention aux clients logés dans des appareils portatifs (téléphones portables, PDAs...) car il est possible qu'ils ne
respectent pas totalement HTTP non plus, soit du fait de leur relative jeunesse, soit par décision des constructeurs.
Quoiqu'il en soit il n'y a pas d'inquiétude particulière à avoir, il est dans l'interêt de tout le monde de respecter les
recommandations de HTTP, et HTTP fonctionne bien de nos jours sur le Web, la preuve ? Et bien c'est le Web tout
simplement !

La RFC2616 décrit le fonctionnement global de HTTP, certains points particuliers sont décrits plus précisément
dans d'autres RFCs.
RFC2617, par exemple, explique comment fonctionnent les processus d'authentification de HTTP
La gestion de la persistance, elle, est détaillée dans la RFC 2109.

II-A - Définitions

HTTP est un protocole applicatif logé sur la couche 7 du modèle OSI (ou 4 du modèle simplifié), soit : tout en haut.
Il ne faut donc pas considérer HTTP comme un "protocole réseau", car il n'a que faire du réseau à proprement parlé :
les mots IP, paquet, état ou encore synchronisation ne lui disent rien.
HTTP est logé (le plus souvent, donc on l'admettra) au dessus de TCP, lui même logé dans IP, au dessus de la
couche physique réseau. Le rôle de HTTP est d'assurer le transport d'informations relatives aux échanges portés
sur le contenu Web. Ainsi, HTTP ne "se connecte" pas d'une machine à l'autre : c'est déja fait par les couches du
dessous, par défaut sur le port TCP 80, qui est reservé à l'usage d'HTTP
HTTP n'est pas crypté (HTTPS l'est), donc n'importe que peut lire HTTP, et peut même l'écrire, du moment qu'il
respecte sa syntaxe et ses recommandations.

HTTP est une des parties du Web. Les 2 autres sont URI et HTML. Je ne présente pas HTML (je ne pense pas que
ce soit nécessaire), mais je vais éclaircir les termes URI et URL.
Les URIs sont des moyens mémorisables par l'Homme d'identifier l'emplacement d'une information que l'on appelle
ressource. C'est comme une adresse postale : une adresse web. Les URIs se décomposent en 2 catégories, les
URLs, et les URNs.
Aujourd'hui, les URNs sont tellement rares que l'on admet la confusion URI = URL, même si de manière stricte, cette
égalité n'est pas juste.
Les URLs se décomposent en plusieurs parties et ne peuvent contenir que des caractères de la table ASCII, les
autres doivent être encodés.
Les parties des URLs ainsi que sa forme générale telle que définie par la recommandation est <sheme>://
<user>:<password>@<host>:<port>/<path>;<params>.<query>#<fragment>.
Les parties scheme et host sont obligatoires.
Les URLs font donc partie de la définition du Web, qui ne se limite pas au seul protocole HTTP. Si l'URL possède
une partie scheme égale à "http", alors ce protocole entre en jeu.
HTTP sert dans un premier temps à échanger des documents lisibles, encodés en HTML. Bien sûr, il peut aussi servir
à rappatrier des fichiers, même si un protocole, FTP, est plus approrié.

-5-
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Pour distinguer le type des ressources échangées, HTTP s'appuie sur MIME : Multipurpose Internet Mail Extensions.
A la base prévu pour l'échange d'Emails, MIME a été adopté pour l'échange de documents webs.

Maintenant que nous venons de définir brièvement HTTP, URL, adresse, ressource et MIME nous allons pouvoir
passer à la suite.
Les informations officielles sur les URIs se trouvent à l'adresse http://www.w3.org/Addressing/
Concernant MIME, la RFC2045 et ses soeurs sont la référence. Pour les types MIME, voyez http://
www.iana.org/assignments/media-types/index.html

II-B - Historique

HTTP est né en 1989, en même temps que le Web, principalement grâce à Sir Tim Berners Lee. Il m'est inutile
de faire un historique, car celui-ci est disponible en ligne: Voyez http://www.w3.org/History.html et http://
www.w3.org/Consortium/history
Quoiqu'il en soit, le développement de HTTP est officiellement arrété aujourd'hui, mais l' IETF, retravaille tout de
même dessus depuis 2006 afin de l'améliorer et de le sécuriser. HTTPBis sont des idées décrites sur http://
tools.ietf.org/wg/httpbis/. Aussi, dès 1998, HTTP-NG était déja décrit, mais abandonné car trop précoce pour
l'époque.
Tous les intéréssés pourront donc lire les travaux et en apprendre un peu plus, je vous y insite ;-).

II-C - Différence entre les versions

Il existe 3 versions de HTTP à ce jour. La version 0.9 n'est plus du tout supportée. La version 1.0 l'est partiellement :
peu de navigateurs l'utilisent, mais la majorité des serveurs la prennent encore en charge.
HTTP 1.1 est clairement la version utilisée aujourd'hui, elle représente une très large majorité des requêtes HTTP
mondiales.

II-C-1 - HTTP 0.9

Première version de HTTP, apparue en 1990, elle n'est clairement plus supportée de nos jour. Ses caractéristiques :

1 Seule la méthode GET existe : il est donc impossible d'envoyer des données vers les serveurs
2 Il n'existe aucun type de fichier : seul le texte (text/plain) est géré
3 Il n'existe aucun code de retour HTTP, si le document n'existe pas, une page blanche est servie
4 De manière générale la notion d'en-tête HTTP n'est pas définie

Bref vous l'aurez compris, HTTP 0.9 est à peine plus haut que TCP : la connexion s'établit, le document, si trouvé,
est rappatrié pour être affiché, et la connexion TCP est fermée, point final.
C'est très très limité, d'ailleurs chose rigolote : interrogez Google avec HTTP 0.9 et voyez le résultat ;-)

II-C-2 - HTTP 1.0

La version 1.0 a été normalisée en 1996, même si elle a commencé à être utilisée avant. Elle décrit le "vrai" Web
que nous connaissons aujourd'hui, voyons cela :

1 Très important : introduction de la méthode POST : le client peut envoyer des données vers le serveur qui
executera alors un script CGI pour traiter ces données, apparaissent alors les formulaires, et l'interraction qui
manquait au Web pour devenir le média incontournable que nous connaissons aujourd'hui
2 D'autres méthodes HTTP font aussi leur apparition, nous ne manquerons pas de les détailler, cependant
seule HEAD est décrite. PUT, LINK et UNLINK sont suggérées seulement
3 Avec celà arrive la gestion du tag <img> et la si importante notion d'en-têtes HTTP

-6-
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

4 Aussi, arrive la gestion des types MIME : HTTP peut transporter des informations de différents types, qui
seront traités chacun d'une manière différente par les 2 extrémités (serveur et client)
5 On anticipe l'ampleur phénoménale qu'HTTP va prendre dans les communications Internet : HTTP 1.0
propose un mécanisme basique mais fonctionnel de gestion du cache et de la congestion du réseau
6 La gestion de l'authentification est aussi intégrée dans HTTP 1.0, avec 2 modes : basic ou digest
7 Les connexions persistantes sont ajoutées, mais non utilisées par défaut par les clients et les serveurs

Comme nous le voyons, HTTP 1.0 est la base du Web que nous connaissons aujourd'hui, cette version du protocole
est définie dans la RFC 1945
Notez que HTTP 1.0 ne propose aucun mécanisme de persistance applicative, il faudra attendre 1997 pour que
Netscape en propose un : les cookies. La RFC 2109 décrit le mécanisme.

II-C-3 - HTTP 1.1

En 1996, la part du Web dans l'Internet est déja considérable, mais l'Internet n'en est encore qu'à ses balbuciements.
De 1996 à 1999, le nombres de machines reliées à Internet va croitre sensiblement, et les experts anticipent alors le
monde d'aujourd'hui : une très grande partie de la planète est connectée, souvent au moyen de liaisons à très haut
débit et les "ordinateurs" ne sont plus les seules machines connectées : téléphones portables, netbooks, gadgets
divers, réfrigérateurs ...
HTTP 1.0 montre des limites en terme de cache, de gestion des connexions TCP, et des proxies. Il faut alors le
moderniser et HTTP 1.1 arrive en 1999, entièrement rétro-compatible avec HTTP 1.0 : Si un en-tête n'est pas compris
par l'une des deux parties (client/serveur), il doit alors être ignoré.

1 Support de l'hebergement virtuel par nom : en-tête Host


2 Prise en charge du relai bout-à-bout dans le transport de la version du protocole via proxies : en-tête Via
3 Découverte de version : Méthode OPTION et en-tête Upgrade
4 Prise en charge des requêtes partielles : en-têtes Range et Content-Range
5 Les connexions persistantes sont devenues les connexions par défaut, en-tête Connection
6 Prise en charge du pipelining (plusieurs requêtes par connexion TCP), en-tête Content-Length et
segmentation des réponses : chunked
7 Amélioration dans la gestion du cache : Etags, Cache-Control, Age, max-age, If-None-Match ...
8 Ajout du support de la négociation de contenu, en-têtes Vary, Accept-*
9 24 nouveaux codes de réponse : 100, 206, 409...
10 Amélioration de la compression avec une compression bout-à-bout, en-tête Transfert-Encoding

Comme on peut le constater, HTTP 1.1 est une réelle évolution, et nous ne manquerons pas de détailler tous ces
termes dans la suite de cet article.
Il faut à ce sujet savoir que la description de HTTP 1.1 est 3 fois plus grande que HTTP 1.0, le protocole se compléxifie,
s'élargit, se divertit et parfois éclaircit des notions peu abordées, ou seulement suggérées par HTTP 1.0, comme la
négociation de contenu.

-7-
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

III - Requêtes

Rappelons que nous sommes dans un environnement client/serveur. Un client va donc effectuer une requête vers
un serveur, pour lui demander des informations. Celui-ci renvoie alors une réponse.
A une requête correspond une et une seule réponse. Nous allons dans ce chapitre nous intéresser à la requête, donc
la première demi-partie d'une transaction.
Il faut savoir que celui qui effectue la requête est appelé 'client', c'est souvent un navigateur web ou une application
web, mais pas tout le temps. Lorsque nous parlerons des proxies, nous verrons que ceux-ci sont à la fois client et
serveur.

III-A - Typographie

Une fois la connexion TCP établie, le client envoie une requête HTTP, cela ressemble à :

Une requête HTTP


GET /en/html/dummy.php?page=dvp&article=http HTTP/1.1
Host: www.developper.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8
(.NET CLR 3.5.30729) FirePHP/0.2.4
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: rememberme=false;VAR=-120

{éventuel contenu de la requête ici}

Exemple hasardeux, dont voici la syntaxe:

1 Une, et une seule ligne de requête, sous la forme METHODE ressource http_version
2 Zéro ou plusieurs lignes dites d'en-têtes, sous la forme Titre-en-tête: valeur
3 Eventuellement crlf (retour à la ligne nouvelle ligne)
4 Eventuellement du contenu, sur une ou plusieurs lignes, totallement séparé des en-têtes

La ligne de requête et les en-têtes sont séparés entre eux par le caractère <crlf> Même si ce n'est pas recommandé,
pour des raisons historiques la plupart des machines acceptent juste <cr> ou juste <lf>, HTTP étant par nature assez
permissif
Tous les caractères connus de fin de ligne sont donc gérés par HTTP, <crlf> étant le plus utilisé.
Les en-têtes sont séparés du contenu par un <crlf> et le contenu est la seule partie facultative, sa présence ou non
dépend de la méthode utilisée, décrite dans la ligne de requête.
Dans notre exemple, il n'y a pas de contenu : seules une ligne de requête et quelques lignes d'en-tête sont présentes.
Nous verrons que c'est une caractéristique de la méthode GET.

La ligne de requête d'une requête vers un proxy comporte l'URL complète et non juste la
ressource demandée sur le serveur.

Les en-têtes doivent avoir la forme Titre: Valeur. Titre et Valeur doivent commencer par une majuscule, mais ils sont
tout de même acceptés sans, même si c'est un cas rare.
Valeur peut représenter plusieurs valeurs intrinsèques, elles seront alors espacées par des points-virgules. Les
virgules, elles, séparent deux termes concernant la même valeur. Par exemple :

Exemple d'en-tête de requête HTTP


Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3

-8-
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Accept-Language: est le titre (ou l'intitulé si vous préférez), et fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3 la valeur. Les parties
de la valeur sont séparées par des point-virgule, et complétées entre elles par des virgules.

Rappel: HTTP indique que tout en-tête non compris (inexistant, mal orthographié...) doit
être ignoré. Ainsi, les risques de "plantages" de HTTP sont maigres.

La ligne de requête est obligatoire, c'est la première ligne que le serveur va analyser, s'il ne la comprend pas, il
ignorera tout le reste et renverra très probablement une réponse d'erreur.
La ligne de requête commence par la méthode HTTP, toujours écrite en majuscules, suivie de la ressource demandée,
sous forme d'URI, puis la version du protocole HTTP utilisée, aujourd'hui très largement HTTP 1.1.
Les lignes d'en-têtes se décomposent en 4 groupes : génériques, réponse, requête, et entité

1 Générique : décrivent la transaction (requête ou réponse) HTTP en elle-même


2 Requête : décrivent des caractéristiques propres à la requête HTTP
3 Réponse : décrivent des caractéristiques propres à la réponse HTTP
4 Entité : décrivent le contenu de la transaction (requête ou réponse) s'il est présent

Il faut noter qu'il n'y a pas d'ordre précis dans l'apparition des en-têtes et qu'ils ne sont
pas sensibles à la casse, même si la casse "majuscule en début de mot + minuscules"
est souvent rencontrée.
Notez aussi que certains en-têtes sont obligatoires, d'autres non, nous verrons celà
lorsque nous les passerons en revue.

III-B - Les méthodes

Toute ligne de requête commence par une méthode. Il existe dans HTTP 1.1 10 méthodes, et HTTP étant extensible,
on peut tout à fait rajouter des méthodes dans les serveurs et les clients.
Les utilisateurs intéréssérés se pencheront alors par exemple sur WebDAV.
Parmi les 10 méthodes présentes dans HTTP 1.1, deux - héritées de HTTP 1.0 - ont une spécification qui tient en 4
lignes (façon de parler), en conséquence LINK et UNLINK sont trop floues et ne seront pas abordées ici.

Chaque méthode HTTP a une sémantique particulière, mais la majorité des navigateurs web d'aujourd'hui n'en
comprennent que 2 ou 3: GET et POST (parfois CONNECT), ce qui est bien dommage.
Les autres méthodes sont surtout utilisées par les serveurs, qui communiquent entre eux via des languages webs
(CGI) comme PHP ou PERL.
Les services webs REST, par exemple, exploitent très largement les potenciels de HTTP ainsi que toutes ses
méthodes et beaucoup de codes de réponse. Le protocole applicatif ATOM joue aussi très bien avec HTTP.
Les serveurs, de manière native, comprennent presque toutes les méthodes. Apache2.2 comprend nativement
GET,HEAD,POST et OPTIONS. Le support des autres méthodes se fait soit en rajoutant des modules, soit en les
activant dans la configuration des modules présents dans le binaire de la distribution.

Détaillons sans plus attendre ces méthodes.

Sous Apache, les directives Limit, LimitExcept et TraceEnable permettent de gérer les
méthodes prises en charge par le serveur.

III-B-1 - GET

GET est la première méthode qui a vu le jour. Elle indique au serveur que nous souhaitons obtenir une représentation
de la ressource, en vue de la lire. De par sa nature, cette méthode suggère que la requête soit relativement concise,
alors que la réponse, elle, peut être très lourde. En général, cette méthode déséquilibre la bande passante, le client
envoyant très peu de données, mais pouvant en recevoir en retour beaucoup (ceci n'est qu'une remarque ayant pour
but de justifier qu'aujourd'hui, en grande majorité, un internaute possède une bande passante plus large en recéption
qu'en émission).

-9-
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

C'est la méthode utilisée par les navigateurs webs lorsqu'on entre une URL dans la barre d'adresse et qu'on la valide,
ou encore lorsqu'on clique sur un lien dans une page web présentée en HTML. Cette méthode représente ainsi un
très large pourcentage du total de requêtes web sur un serveur.
Même s'il est possible de passer des paramètres dans la requête, (appelés "query string", les fameuses variables
derrière le "?" spéarées par des "&"), GET ne doit jamais faire intervenir une modification de la ressource coté serveur.
GET sert à lire des données, pas à en envoyer, ainsi une requête GET ne peut contenir de corps. Une requête GET
peut être mise en cache, elle ne doit contenir aucune information susceptible de varier dans le temps (du contenu
par exemple). Aussi, un lien web (dont l'expression sera une requête HTTP de type GET) peut être mis en favoris
ou partagé entre plusieurs personnes.

exemple de requête GET


GET /imghp?hl=fr&tab=wi HTTP/1.1
Host: images.google.fr
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.9) Gecko/2009040821 Firefox/3.0.9
(.NET CLR 3.5.30729) FirePHP/0.2.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

Dans cet exemple, le client demande au serveur de lui servir une représentation de la ressource identifiée par l'URI /
imghp?hl=fr&tab=wi. Souvent, la réponse est en HTML, mais pas toujours : aujourd'hui le Web a changé par rapport
aux débuts de HTTP, et la réponse est aussi souvent du XML, du JSON, ou encore un format binaire comme
de l'AMF
On comprend bien pourquoi Google utilise une méthode GET pour son moteur de recherche : la requête peut être
identifiée de manière unique, mise en favoris, mise en cache, sans jamais que le résultat sémantique ne change :
elle ne comporte pas de corps.
Il conviendra ainsi de faire attention à la taille des données envoyées. GET ne permet que d'envoyer des données
via l'URL, et notamment la Query String. En théorie, la limite est de 256 caractères, mais certains serveurs ou clients
en acceptent plus, ou moins, Apache par exemple, accepte 1024 caractères.
Une attention particulière devra être apportée aux paramètres dans la Query String : ils ne doivent pas comporter
d'informations sensibles telles que ?login=toto&password=developpez, car ces informations vont pouvoir être
mémorisées par les caches (proxies), par le client (navigateur souvent), et vont même pouvoir fuire via l'en-tête
Referer dont nous reparlerons.
GET est idempotente, si on execute plusieurs fois la même requête, il se passe le même résultat sur le serveur.

III-B-2 - HEAD

HEAD est très semblable à GET, si bien que si l'on supporte l'un, en théorie on supporte l'autre (sauf cas très rares).
HEAD possède la même signification que GET, à la différence que la réponse ne comportera pas de corps.
Seuls les en-têtes de la réponse seront envoyés au client, sans le corps (souvent lourd) de celle-ci. C'est très pratique
pour tester une URL ou encore pour "pinger" un serveur HTTP, car la réponse sera très légère.
On se sert de cette méthode en général pour tester l'existence d'une page (en analysant le code de réponse) : on
n'a pas besoin du corps et de la représentation de la réponse, seuls les en-têtes nous importent.

La réponse à une requête HEAD sera exactement la même qu'à une requête GET, mais
sans le corps. Les en-têtes seront identiques.

exemple de requête HEAD


HEAD / HTTP/1.1
Host: google.com
Keep-Alive: 300
Connection: keep-alive

- 10 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Comme on le voit, seuls les en-têtes de la réponse apparaissent, on connait donc les caractéristiques de la réponse
(son type, son poids, son encodage ...), mais on ne connait pas son contenu.

Apache lie GET et HEAD : si vous désactivez le support de l'un, l'autre sera aussi désactivé

III-B-3 - POST

La méthode POST est utilisée lorsque le client doit faire transiter un nombre conséquent de données, vers un script
sur le serveur qui va les traiter, ceci dans le but de créer ou mettre jour une ressource.
Aujourd'hui, la seule manière pour un navigateur web d'envoyer du POST, est de le faire via un formulaire : une des
grosses améliorations introduites par HTTP 1.1 par rapport à HTTP 1.0. Javascript aussi est capable d'envoyer des
requêtes de type POST, mais ceci sort du cadre de cet article.
Voici un exemple de requête POST :

exemple de requête POST


POST /dossier/script.php HTTP/1.1
Host: developpez.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.9) Gecko/2009040821 Firefox/3.0.9
(.NET CLR 3.5.30729) FirePHP/0.2.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Keep-Alive: 300
Connection: keep-alive

nom=pauli&prenom=julien&data=some%20data

Voyez comme le corps de la requête nom=pauli&prenom=julien&data=some%20data est séparé des en-têtes via
une ligne blanche.
Ici, les données sont donc transmises dans le corps de la requête, et non dans les en-têtes via le query string comme
le suggérait GET. C'est bien là toute la différence.
Ainsi, si le client demande à rafraichir la page, le navigateur doit l'informer qu'il va retransmettre des données. POST
est non idempotente, c'est à dire que 2 requêtes de ce type, strictement identiques, peuvent mener à 2 traitement
différents coté serveur; et c'est pour cela que le client n'a pas le droit de renvoyer une requête POST sans en avertir
l'utilisateur.

Confirmation POST

La différence fondamentale par rapport à une méthode GET est que l'on est expressement invité à envoyer des
données en vue d'un traitement sur le serveur.
Comme des données sont envoyées, la page de réponse est susceptible de varier en fonction de ces données
d'entrée, HTTP interdit ainsi de gérer un quelconque cache d'une requête de type POST.
Aussi, le client doit indiquer quel type de données il envoie, et la taille de celles-ci. Les en-têtes Content-Type et
Content-Length sont donc nécessaires.

- 11 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

POST masque les données envoyées. L'URL ne contient pas (mais pourrait, ce n'est pas interdit) de query string,
les données transitent dans le corps de la requête, mais elles n'en sont pas pour autant cryptées, invisibles, ou non-
interceptables.
Attention, POST n'est pas destinée à consulter une ressource, mais bien à en créer une nouvelle ou à mettre à jour
une existente. Les codes de réponse permettent de savoir comment la requête a été traitée, un corps dans la réponse
peut aussi afficher une page informant du détail de la transaction.

III-B-4 - PUT

PUT est très semblable à POST. PUT permet au client de déposer des données vers une ressource sur le serveur,
c'est en gros l'inverse de GET, qui demande une ressource.

Il est utile de noter que souvent en PHP, on cherche à envoyer des données via un
"formulaire d'upload" ( RFC 1867) et le tableau $_FILES. Ce n'est pas tout à fait correct
niveau HTTP, souvent, utiliser PUT donne de bien meilleurs résultats, et permet de passer
outre les limitations du fichier php.ini, comme upload_max_filesize

Apache ne gère pas nativement PUT, mais sa directive Script permet de l'intégrer. L'avantage de PUT est que
le serveur est sensé obéir "bêtement" et déposer la ressource à l'endroit voulu par le client (moyennant quelques
mécanismes de sécurité).
Aucun script CGI n'est sensé intervenir, je dis sensé car Apache ne sait pas faire celà : il se repose sur un script
CGI (comme PHP) pour gérer PUT.

exemple de requête PUT


PUT /data/julien/text/liste.txt HTTP/1.1
Host: developpez.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.9) Gecko/2009040821 Firefox/3.0.9
(.NET CLR 3.5.30729) FirePHP/0.2.4
Content-Type: Text/plain
Content-Length: 44

Bonjour, voici le contenu d'un fichier texte

Aujourd'hui encore, PUT est largement méconnue et sous-utilisée, ce qui est très dommage car ce n'est pas difficile
à mettre en place.
PUT est idempotente, si on execute plusieurs fois la même requête, il se passe le même résultat sur le serveur.

III-B-5 - DELETE

Son nom ne trompe pas, DELETE demande au serveur de supprimer une ressource, c'est un peu l'inverse de PUT.
Attention, aucun mécanisme de sécurité n'existe, et lorsque le serveur répondra par "OK", ceci ne signifie pas que
la ressource en question est supprimée. Celà signifie que le serveur a compris votre requête, et va, dans un futur
plus ou moins long, executer votre souhait.

exemple de requête DELETE


DELETE /data/julien/text/liste.txt HTTP/1.1
Host: developpez.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.9) Gecko/2009040821 Firefox/3.0.9
(.NET CLR 3.5.30729) FirePHP/0.2.4

Comme pour GET, une requête DELETE ne contient pas de corps.


DELETE est idempotente, si on execute plusieurs fois la même requête, il se passe le même résultat sur le serveur.

- 12 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

III-B-6 - OPTIONS

La méthode OPTIONS permet au client de demander au serveur ces capacités de prise en charge de HTTP. Si
la requête précise une ressource, alors la demande concerne celle-ci spécifiquement. Si au contraire la ressource
indiquée est *, alors la requête concerne les capacités globales du serveur.

exemple de requête OPTIONS


OPTIONS * HTTP/1.1
Host: developpez.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.9) Gecko/2009040821 Firefox/3.0.9
(.NET CLR 3.5.30729) FirePHP/0.2.4

A cette requête, le serveur va répondre grâce à un en-tête Allow, dans lequel il va placer en toutes lettres les méthodes
HTTP qu'il gère (si celui-ci gère la méthode OPTIONS).
Ce type de requête est extrêmement pratique pour faire de la reconnaissance avant interrogation, elle permet à un
client de faire de la découverte en vue de négocier des transactions futures.

III-B-7 - TRACE

Le but de cette méthode est assez particulier, et précisons tout de suite qu'elle peut introduire des problèmes de
sécurité. La méthode TRACE demande au serveur de renvoyer dans le corps de sa réponse, les en-têtes qu'il a
reçu dans sa requête.
C'est un genre de "loopback", on envoie "ping" au serveur, qui doit répondre par "ping".

exemple de requête TRACE


TRACE /some/path/ressource.php HTTP/1.1
Host: developpez.com

Le corps de la réponse à cette requête doit être le contenu des en-tête de la requête elle-même. Une requête TRACE
ne comporte pas de corps.
A quoi cela sert-il de rejouer la requête dans la réponse ?
Et bien il faut se souvenir que des proxies, des passerelles ou encore des firewalls peuvent se loger entre le client
et le serveur (le bout à bout). Ainsi, chaque intermédiaire est susceptible de modifier la requête qu'il reçoit, souvent
en ajoutant son identitié à l'intérieur.
La méthode TRACE permet donc véritablement de tracer les intermédiaires entre les 2 bouts du réseau.

Du point de vue sécurité, TRACE offre la possibilité à Javascript de voler un cookie déclaré SecureOnly ou encore
de voler les identités d'authentification HTTP. Plus d'informations ici

III-B-8 - CONNECT

La méthode CONNECT est assez particulière. Elle ne fonctionne que sur les proxies, et permet de demander à celui-
ci de relayer une requête sur certains ports, typiquement 443 (HTTPS).
Si un client utilisant le proxy a besoin de se connecter via HTTPS, il va alors demander au proxy via la méthode
CONNECT, de tunneller ses requêtes vers le serveur de destination.
A cause de problèmes de sécurité évidents (voir par exemple ici), les serveurs proxy limitent souvent le port de
destination à l'unique port 443. La requête CONNECT ne possède comme corps qu'une seule ligne, qui indique le
serveur de destination et le port.

exemple de requête de type CONNECT


CONNECT developpez.com:443 HTTP/1.1

- 13 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Une réponse positive possible


HTTP/1.1 200 Connection Established
Proxy-agent: Apache/2.2.11 (Unix)

Apache n'accepte la méthode CONNECT que sur un port de proxy, et seulement si son
module mod_proxy_connect est activé. Sa directive AllowCONNECT permet de définir les
ports de destination vers lesquels proxier les requêtes, si le port demandé n'a pas été
ouvert par cette méthode, un retour 403 ou 405 est envoyé.

- 14 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

IV - Réponses

A toute requête correspond au moins une réponse. Il peut y avoir plusieurs réponses pour une seule requête, comme
ce sera le cas dans les transactions partielles.

IV-A - Typographie

La première chose qu'un serveur doit faire lors de l'envoi de sa réponse, est de fournir de manière concise, rapide et
pratique un moyen d'informer le client du résultat du traitement de sa demande.
Le serveur utilise pour cela une ligne de statut comprenant un code de réponse qui tient sur 3 chiffres.

exemple de réponse HTTP


HTTP/1.1 200 OK
X-Powered-By: PHP/5.2.6
Set-Cookie: bbsessionhash=5dc22176091fde3ea648f61564e566dd; path=/; HttpOnly
Cache-Control: private
Pragma: private
Content-Type: text/html; charset=ISO-8859-1
Content-Encoding: gzip
Content-Length: 58840
Date: Fri, 24 Apr 2009 15:05:08 GMT
Server: Apache

La réponse commence toujours par une ligne de statut qui rappelle la version de HTTP utilisée, puis un code de
réponse, suivi de sa description en toutes lettres.
Suivent ensuite des en-têtes, et, comme dans le cas de la requête, il peut y avoir un contenu, mais pas tout le temps
(cela dépendra de la requête). Une requête HEAD requiert que la réponse n'ait pas de corps, idem pour une requête
de type OPTIONS.

IV-B - Codes de retour

- 15 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

1xx Information
2xx Succès
3xx Redirection
4xx Erreur client
5xx Erreur Serveur

IV-B-1 - Codes 1xx - Informations

Les codes d'information ont été introduits par HTTP 1.1. Ils ne sont pas toujours bien compris et peuvent prêter à
confusion, par contre ils ne sont que deux.

IV-B-1-a - 100 - Continue

Sans doute le plus mal compris des codes. Ce code est renvoyé par un serveur face à des requêtes particulières
(incomplètes) d'un client.
Imaginons un client qui doive envoyer 300Mo de données via une méthode PUT ou POST. S'il envoie sa requête
directement, et que le serveur n'est pas dans la capacité de répondre (la méthode utilisée a été interdite par exemple),
alors le client va envoyer sur le réseau 300Mo pour rien du tout! Il se retrouvera au bout du compte avec un code de
réponse d'erreur, et il aura gaspillé du temps, de la bande passante, et sera passé pour un idiot.

Au lieu de cela, le client aurait pu demander au serveur "es-tu dans la capacité de répondre à ma requête d'envoi de
300Mo sur cette URL ?". Une réponse du serveur avec un code "100 Continue", indique que "oui, tu peux y aller".

exemple de requête demandant si l'envoi d'un fichier (mp3 ici) est possible
PUT /music/mp3/mymusic.mp3 HTTP/1.1
Host: developpez.com
Content-Type: audio/mpeg
Content-Length: 300000000
Expect: 100-Continue

Le client envoie une requête sans corps, mais avec un en-tête spécial Expect (que nous reverrons plus tard), qui dit
qu'il s'attend à ce qu'il puisse envoyer le contenu décrit.

exemple de réponse à la requête précédente


HTTP/1.1 100 Continue
Date: Fri, 24 Apr 2009 17:05:08 GMT
Server: Apache
Connection: close

Un serveur ne doit pas retourner un code 100 à une requête qui ne possède pas l'en-tête
Expect: 100-Continue. Malheureusement, certains rares serveurs le font quand même. Si
un proxy reçoit une requête Expect: 100-Continue, il ne doit la faire suivre que si le serveur
suivant comprend HTTP 1.1. Dans le cas contraire il doit renvoyer au client d'origine une
réponse 417.

IV-B-1-b - 101 - Switching Protocols

Il existe plusieurs versions du protocole HTTP. Aussi, un client peut vouloir changer de protocole (vers des protocoles
sécurisés, comme TLS) dans sa communication. Pour celà, il peut indiquer au serveur, via l'en-tête Upgrade, la liste
des protocoles vers lesquels il souhaite basculer. Si le serveur est d'accord, il répondre alors par une réponse 101.

exemple de requête demandant un changement de protocole


HEAD /ressource HTTP/1.1

- 16 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

exemple de requête demandant un changement de protocole


Host: developpez.com
Upgrade: TLS/1.0, SHTTP/1.3, IRC/6.9, RTA/x11
Connection: upgrade

réponse possible
HTTP/1.1 101 Switching Protocols
Upgrade: TLS/1.0
Connection: upgrade

Apache ne connait pas 101, ce n'est pas encore implémenté pour des raisons bien
précises

IV-B-2 - Codes 2xx - Succès

Les codes de succès paraissent simples, mais il y a des subtilités et un réel "langage" à respecter; A un type de
requête peuvent correspondre plusieurs types de réponses "succès".
Les codes 2xx signifient que le serveur "a réussi à faire ce qu'on lui a demandé".

IV-B-2-a - 200 - OK

200 est un code très classique, car c'est le code de réponse positif à une requête GET/HEAD, TRACE ou POST.
La réponse contient un corps (un contenu), qui est envoyé donc à la suite de l'en-tête.

IV-B-2-b - 201 - Created

Ce code est une réponse (positive) à une requête de type PUT, ordonnant la création d'une ressource sur le serveur.
Notez que POST peut aussi être utilisée, si un CGI est responsable de crée la ressource, il devra alors répondre
avec ce code.
Un en-tête de réponse Location doit être attaché, précisant l'URL absolue vers la ressource crée (La ressource doit
donc exister et être disponible). Un corps peut être attaché, il doit représenter une série de liens vers la ressource
en question.

IV-B-2-c - 202 - Accepted

202 diffère de 201 dans le fait que la demande de création d'une ressource peut prendre du temps. En général, PUT
dépose la ressource sur le serveur.
POST demande à un CGI de traiter la tâche. Ce CGI peut lui-même demander cette création à un programme externe.
Il devra alors retourner 202 - Accepted, pour dire que "oui, nous avons pris en compte la requête de création, nous
sommes en train de la traiter".
Mieux : la ressource peut très bien exister, mais ne pas avoir de représentation (être cachée), donc une réponse
201 n'est appropriée.

202 doit aussi obligatoirement proposer un contenu décrivant l'état de traitement de la requête. Un en-tête Location
peut éventuellement être attaché, fournissant l'URL d'une page pouvant nous renseigner sur le traitement de la
requête.

Une requête de type POST, envoi de données


POST /livre/create.php HTTP/1.1
Host: developpez.com
Content-Type: application/x-www-form-urlencoded
Content-length:27

id=32&titre=http%20protocol

- 17 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Une réponse positive


HTTP/1.1 202 Accepted
Date: Wed, 29 Apr 2009 19:05:03 GMT
Server: Apache/2.2.11 (Unix) PHP/5.2.9
Content-Length: 20
Content-Type: text/html; charset=ISO-8859-1
Content-Language: fr

<h1>Livre posté</h1>

IV-B-2-d - 203 - Non-Authoritative Information

Bouhh, Ce code est carrément inusité (à ma connaissance), et signifie que la réponse renvoyée ne provient pas du
serveur d'origine.
Plutôt confu, d'autant plus que le texte officiel dit "Use of this response code is not required and is only appropriate
when the response would otherwise be 200 (OK)" (que l'utilisation de ce code est facultative et reservée au cas où
le code aurait été 200).

IV-B-2-e - 204 - No Content

La réponse neutre. "Ok, j'ai compris : ne bouge pas". En gros, ceci permet au client de discuter avec le serveur, sans
que l'affichage n'ait besoin de changer.
No Content signifie bien "pas de contenu". Par exemple, l'envoi d'un formulaire qui a déja été envoyé, une réponse
positive mais vide à une requête DELETE, ou encore l'accès à un document vide.
En réponse à une requête POST de type envoi de formulaire, IE8 et FF3 ont fait juste : ils ont rafraichi l'interface
graphique, mais sans vider les formulaires, comme si il ne s'était rien passé (mais pas une erreur en tout cas).
Concernant AJAX, c'est au développeur de savoir que "si je reçois 204, c'est que c'est OK, point final je n'ai rien à
faire", afin de bien respecter la norme.

IV-B-2-f - 205 - Reset Content

Requête acceptée, la page en cours doit être "remise à zéro". Ici ambiguïté, même si on sent bien ce que celà signifie.
La réponse à l'envoi d'un formulaire POST de IE8 se comporte comme en réponse à une 200 : page blanche puisque
205 n'est pas suposé avoir de corps. S'il y en a un, il sera affiché.
FF3, lui, semble avoir le même comportement que face à 204, il ne met donc pas à zéro l'affichage (entendez par
là qu'il ne vide pas les formulaires).

Le comportement de FF3 n'est pas correct. 205 a été crée dans le but de saisir rapidement plusieurs informations à
la suite, avec remise à zéro de la page à chaque retour OK. (IE8 ignore lui carrément 205 et le traite comme 200).
Une réponse 205 à une requête AJAX doit se traiter par la remise à zéro de l'affichage (remise à zéro des formulaires).

IV-B-2-g - 206 - Partial Content

206 liée directement à une spécificité très méconnue de HTTP et pourtant tellement géniale : le contenu partiel.
Nous n'allons pas détailler ce processus ici, il le sera plus tard. Simplement : les requêtes partielles permettent de
ne demander qu'une partie de la ressource (en octets), et non son ensemble d'un coup.
206 indique que la requête partielle (ou requête par parties) a été traitée avec succès, le contenu est retourné. De
ce fait, l'en-tête Content-Range est obligatoire dans la réponse.

Une requête par parties (de type GET)


GET /tutos/http.zip HTTP/1.1
Host: developpez.com
Range: 500-1500

- 18 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Une réponse positive


HTTP/1.1 206 Partial Content
Date: Wed, 29 Apr 2009 20:14:23 GMT
Server: Apache/2.2.11 (Unix) PHP/5.2.9
Accept-Ranges: bytes
Content-Range: 500-1500/3587
Content-Type: application/zip
Content-Length: 1000

{contenu binaire ici}

IV-B-3 - Codes 3xx - Redirection

Ahhh les fameux "300"... Ils sont méconnus et mal utilisés, mais HTTP y est pour quelque chose car il y a eu de
gros changements entre HTTP 1.0 et 1.1.
Les codes 3xx définissent des contextes de redirection, ils sont donc souvent (voire obligatoirement pour certains)
accompagnés d'un en-tête Location indiquant l'URL que le client va devoir suivre.
HTTP 1.0 ne définissait que deux codes de redirections, 301 et 302, c'est maigre. HTTP 1.1 vient renforcer tout celà
en en proposant 8 et ils ne sont pas difficiles à utiliser, il suffit de lire leur descriptif et de bien l'assimiler en fonction
de ce qu'on cherche à faire du client.

IV-B-3-a - 300 - Multiple Choices

Ce code de réponse est utilisé dans la négociation de contenu (voir rubrique dédiée) pour signaler au client que sa
requête comporte plusieurs réponses, et qu'il va devoir effectuer un choix.
Ce choix peut être automatique, mais très souvent il est manuel : le corps de la réponse doit contenir des liens vers
les URLs correspondantes aux différentes possibilités. Le navigateur peut éventuellement suivre un éventuel lien
proposé par le serveur via l'en-tête Location (Firefox et IE8 suivront).
Par exemple, le client indique une préférence de langue équivalente avec un facteur identique pour 2 langues dont
le serveur possède des représentations. Il est donc impossible pour le serveur de determiner correctement la bonne
ressource à servir, dans ce cas, il peut soit faire un choix par défaut, soit proposer une réponse 300 et demander
au client de choisir lui-même.

Exemple de requête GET à négociation nulle


GET /tutos/http.zip HTTP/1.1
Host: developpez.com
Accept-Language: en,fr;q=0.8

Une réponse indiquant un choix multiple


HTTP/1.1 300 Multiple Choices
Date: Wed, 10 Jun 2009 22:27:23 GMT
Server: Apache/2.2.11
Content-Length: 243

<html><head>
<title>300 Multiple choices</title>
</head><body>
<h1>Multiple Choices</h1>
Available variants:
<ul>
<li><a href="http.en.zip">http.en.zip</a> , type application/zip, language en</li>
<li><a href="http.fr.zip">http.fr.zip</a> , type application/zip, language fr</li>
</ul>
</body></html>

- 19 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

IV-B-3-b - 301 - Permanently Redirect

"Permanently" est clair : la ressource demandée par le client a changé de place définitivement. Le client devrait alors
suivre l'en-tête Location avec la même méthode qu'il a utilisé.
Le problème est que la plupart des navigateurs Web d'aujourd'hui suivent la redirection via une méthode GET, même
si la requête dorigine est POST, en héritage à HTTP 1.0.
Evitez donc d'utiliser ce code de retour sur une méthode autre que GET (ou HEAD). Dans tous les cas, ce code
indique au client qu'il doit mettre à jour ses liens pour référencer la nouvelle URL. Ceci signifie qu'en théorie, un
navigateur Web devrait modifier le lien d'un "favoris", si l'on accède à une page depuis un "favoris" (via GET)et qu'elle
aboutit sur 301. Les moteurs de recherches, eux, vont mettre à jour leur index pour référencer la nouvelle URL. Aussi,
le corps de la réponse devrait indiquer un lien HTML vers la ressource en question.

Exemple de requête GET classique


GET /tutos/http HTTP/1.1
Host: developpez.com

Une réponse indiquant que la ressource n'est plus à cet endroit et n'y sera plus
HTTP/1.1 301 Moved Permanently
Date: Wed, 3 Jun 2009 22:27:23 GMT
Server: Apache/2.2.11
Location: /tutos/http/main.zip
Content-Length: 42

{contenu HTML répétant l'URL de Location}

Ce code doit être utilisé pour forcer un moteur de recherche à mettre à jour un lien dans sa base.

IV-B-3-c - 302 - Found

"Found" signifie que la ressource demandée a été localisée ailleurs, pensez à la notion de "lien" dans les systèmes
de fichiers Unix. Ainsi, ce code n'est pas correct pour rediriger le traitement d'un POST vers une page d'information
car le client est sensé garder la méthode qu'il a utilisée pour requêter la nouvelle URL.
Malheureusement là encore, la plupart des navigateurs Web vont utiliser GET alors que ce n'est pas correct et notez
que certains clients Web mobiles (téléphones portables) suivent eux la recommendation ... bonjour les dégats si 302
est mal utilisé ! Le corps de la réponse devrait indiquer un lien HTML vers la ressource en question, là encore, peu
d'applications (types PHP suivent la recommendation.

Ce code est celui généré par défaut par PHP lorsqu'on indique une redirection via l'ajout un
en-tête "Location". Il peut ainsi ne pas être approprié et devra être changé le cas échéant
par le développeur. Voyez la section "Les outils" pour plus d'infos.

IV-B-3-d - 303 - See Other

Voila le code à utiliser pour rediriger une requête de type POST vers une ressource qui doit alors être intérrogée via
GET. Les navigateurs webs modernes suivent cette recommendation.
303 ne signifie pas que la ressource demandée se situe à un autre endroit (contrairement à 301 ou 302), mais que
le résultat du traitement de la requête originelle (très souvent POST) se situ à tel endroit (indiqué comme toujours
par l'en-tête Location).

Exemple d'une requête POST, mise à jour de données


POST /reservations/items/38 HTTP/1.1
Host: developpez.com
Content-Type: application/x-www-form-urlencoded
Content-Length:20

- 20 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Exemple d'une requête POST, mise à jour de données


name=exemple&count=4

Une réponse indiquant le statut du traitement de la requête


HTTP/1.1 303 See Other
Date: Wed, 3 Jun 2009 22:27:23 GMT
Server: Apache/2.2.11
Location: /reservations/items/status/38

IV-B-3-e - 304 - Not Modified

Cette réponse est appropriée dans le cadre d'une requête de validation incluant un en-tête de condition comme If-
Modified-Since ou encore If-None-Match.
Elle signifie que la réponse n'a pas changé et que le cache peut mettre à jour des paramètres concernant la ressource,
comme Last-Modified ou Expires. Certains en-têtes de réponse sont obligatoires (la RFC les indique).
Vous trouverez plus d'informations sur le fonctionnement du cache HTTP dans la rubrique appropriée.

Exemple d'une requête de validation de cache


GET /articles/http/tutoriels/cache.html HTTP/1.1
Host: www.developpez.com
If-Modified-Since: Wed, 01 Sep 2004 13:24:52 GMT
If-None-Match: "84d1-3e3073913b100"

Une réponse indiquant un non-changement de la requête


HTTP/1.1 304 Not Modified
Date: Wed, 03 Jun 2009 20:56:09 GMT
Server: Apache/2
Etag: "84d1-3e3073913b100"
Expires: Thu, 04 Jun 2009 02:56:09 GMT
Cache-Control: max-age=21600

IV-B-3-f - 305 - Use Proxy

Très simple : la ressource demandée doit être accéder via un proxy obligatoirement. L'adresse du proxy en question
doit être livrée dans l'en-tête de réponse Location.

IV-B-3-g - 306 inusité

Ce code a été utilisée dans la rédactions des spécifications, puis abandonné. Il n'est donc plus utilisé.

IV-B-3-h - 307 - Temporary Redirect

Ce code est à utiliser pour rediriger une requête POST vers une page, en conservant la méthode POST originale.
Les navigateurs webs modernes suivent cette recommandation et avertiront le client utilisateur via un message que
les données doivent être retransmises à une URL différente. Si une autre méthode est utilisée, la redirection prend
lieu normalement, mais les clients (comme les moteurs de recherches) ne doivent pas mettre à jour leurs liens, la
redirection n'est que (théoriquement) permanente. Un en-tête Location doit être présent.
La différence avec 302 est subtile, "Found" ne veut pas dire "Temporary Redirect" dans la sémantique profonde des
mots, 307 est pour HTTP 1.1 l'ancien 302 de HTTP 1.0 (très mal utilisé des clients).

Exemple de requête GET classique


GET /tutos/http.zip HTTP/1.1
Host: developpez.com

- 21 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Une réponse indiquant que la ressource n'est plus à cet endroit et n'y sera plus
HTTP/1.1 307 Temporary Redirect
Date: Wed, 3 Jun 2009 22:27:23 GMT
Server: Apache/2.2.11
Location: /tutos/http/main.zip
Content-Length: 42

{contenu HTML répétant l'URL de Location}

IV-B-4 - Codes 4xx - Erreurs client

IV-B-5 - Codes 5xx - Erreurs serveur

- 22 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

V - Les en-têtes

Une transaction HTTP, c'est donc une requête suivie d'une réponse. Dans les 2 cas, la "demie-transaction" se
décompose en 2 parties : des en-têtes, la partie obligatoire, et un corps, qui est facultatif.
La partie en-têtes se décompose elle aussi en plusieurs parties.On distingue les en-têtes généraux (ou globaux), les
en-têtes dits "d'entité" dont le rôle est de rensigner sur le corps de la demie-transaction, et enfin des en-têtes propres
à la réponse ou propres à la requête.

V-A - Généraux

Les en-têtes généraux renseignent sur la demie-transaction HTTP en elle-même.

V-B - D'entité

Dans le cas où la demie-transaction (requête ou réponse) comporte un corps (du contenu), il convient de définir ce
corps. Comme il peut être de tout type, de toute taille, de tout encodage etc..., il convient d'informer la partie récéptrice
(le serveur dans le cas d'une requête et le client dans le cas d'une réponse) des caracteristiques du message utile
transporté (le corps donc).

V-C - De requête

Les requêtes sont les demi-transactions HTTP montantes, allant toujours du client vers le serveur. A ce titre, une
requête peut être caractérisée par des en-têtes qui n'ont de signification que pour elle.

V-D - De réponse

Les réponses sont les demi-transactions HTTP descendantes, allant toujours du serveur vers le client. A ce titre, une
réponse peut être caractérisée par des en-têtes qui n'ont de signification que pour elle.

- 23 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

VI - Transactions partielles

Une transaction HTTP est toujours décomposée en 2 parties : une requête et une réponse. Dans tous les cas, une
ressource entre en jeu. Nous avons vu en introduction qu'une ressource était "un objet" échangeable via le web, par
exemple un document HTML, un fichier audio ou vidéo, ou encore un document texte.
Les transactions partielles permettent aux 2 parties (client et serveur) de ne s'échanger qu'un partie de la ressource,
exprimée en octets.
Le cas d'exemple concrêt pour comprendre est le lecteur PDF de Adobe : lorsqu'on possède ce lecteur et que l'on
demande via méthode GET la lecture d'un document PDF sur HTTP, le programme de lecture PDF fondu dans le
navigateur va prendre la main et demander au serveur de lui servir le document page par page, alors que celui-ci
ne représente qu'une seule et même ressource.
L'avantage est devinable : le client va pouvoir commencer à prendre connaissance du document alors que celui-ci
n'est pas encore totallement rapatrié.

Ce processus de découpe d'une ressource en parties a été introduit par HTTP 1.1 et est très pratique dans certains
cas.
Toute ressource peut être ségmentée et rapatriée par parties. Si elle pèse un certain poids, ou si la qualité de la
connexion est dégradée, les requêtes partielles prennent tout leur sens.

Le principe est simple : le client demande quelle partie (en octet) de la requête il souhaite récupérer, ceci en envoyant
un en-tête Range dans sa requête.
La partie demandée peut être bornée ("De l'octet 100 à 500") ou infinie ("à partir du 100ème octet"). Aussi, le client
peut demander plusieurs parties en une seule requête ("de l'octet 10 au 100 et du 200 au 500") : la réponse sera
alors une réponse ségmentée contenant les parties demandées.
Dans tous les cas, si la requête ne peut être satisfaite (on demande les octets 2456 à 100, au lieu des 100 à 2456),
alors un code de réponse 416 sera retourné.

Exemple de requête partielle


GET /articles/http.zip HTTP/1.1
Host: developpez.com
Range: bytes=100-1000

Réponse positive
HTTP/1.1 206 Partial Content
Date: Wed, 10 Jun 2009 18:50:59 GMT
Server: Apache/2.2.11
Accept-ranges: bytes
Content-range: bytes 100-1000/3258
Content-type: application/zip
Content-length: 900

{ contenu binaire de 900 octets de longueur }

La réponse inclut un en-tête Accept-Range qui signifie que le serveur autorise comme unité de mesure l'octet (c'est
le plus classique et il est supporté par tous les serveurs).
On note via Content-Range que le serveur indique bien qu'il répond à la partie demandée, et donne aussi le poids
total de la ressource (la réponse contient les octets 100 à 1000 sur un total de 3258).
Enfin, Content-Length confirme bien que le corps de la réponse pèse 900 octets.

Exemple de requête incorrecte : la borne maximale est inférieure à la borne minimale


GET /articles/http.zip HTTP/1.1
Host: developpez.com
Range: bytes=1000-100

Réponse positive
HTTP/1.1 416 Requested Range Not Satisfiable

- 24 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Réponse positive
Date: Wed, 10 Jun 2009 18:57:17 GMT
Server: Apache/2.2.11
Content-type: application/zip

Enfin voici un exemple de demande de plusieurs parties en une seule requête:

Exemple de demande de plusieurs parties


GET /articles/http.html HTTP/1.1
Host: developpez.com
Range: bytes=100-1000, 1500-1900

Réponse positive contenant plusieurs parties d'une même ressource découpée


HTTP/1.1 206 Partial Content
Date: Wed, 10 Jun 2009 19:15:04 GMT
Server: Apache/2.2.11
Accept-ranges: bytes
Content-length: 1673
Content-type: multipart/byteranges; boundary=46c03675fc9384ac

--46c03675fc9384ac
Content-type: text/html
Content-range: bytes 100-1000/15869

{#### premier contenu de 900 octets #####}


--46c03675fc9384ac
Content-type: text/html
Content-range: bytes 1500-1900/15869

{#### deuxième contenu de 400 octets #####}


--46c03675fc9384ac--

La réponse est ségmentée grâce à un joker de contrôle appelé "boundary" qui délimite les parties dans le corps de
la réponse. Chaque partie répète certains en-tête notamment le type MIME. Cette technique est la même qui est
utilisée par exemple dans les protocoles mails (SMTP) pour gérer les "pièces jointes".
Notez que le Content-Length contient bien le poids total du corps de la réponse, soit le poids des parties + les 3
répétitions de la chaine joker et les multiples en-têtes écrits (Content-Length représente toujours le poids total du
corps en octets).

- 25 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

VII - Proxies

Les proxies sont très utilisés de nos jours, sur le Web notamment. Nous allons tenter d'expliquer leur fonctionnement
et leur utilité.

VII-A - Définitions

Un proxy est un serveur qui va agir à la place d'un autre. C'est une machine intercalée sur le réseau, qui souvent
"prend la place" logique d'une autre.
On distingue 2 cas de proxies HTTP : forward ou reverse, et il est très important de comprendre la différence entre
un forward et un reverse proxy.
Dans un forward proxy, les clients demandent à un serveur de relayer la requête vers le serveur de destination. Cela
se fait généralement en réglant le navigateur et en lui spécifiant un proxy à utiliser (pas toujours, on peut aussi régler
le réseau pour utiliser un proxy de manière totalement transparente). En entreprise, c'est assez courant : le firewall
bloque le port 80, les clients doivent donc obligatoirement passer par le proxy pour aller surfer sur le Web. Le proxy
va alors souvent mettre en cache des ressources qu'il pourra resservir à différents clients

Une configuration en forward proxy

Dans un reverse proxy, les utilisateurs accèdent à un contenu sur un serveur (par exemple http://serveur/page/
ressource) mais ce contenu n'est en réalité pas stocké sur ce serveur. Celui-ci va alors agir comme un proxy vers
le serveur de destination. Ces serveurs proxy là peuvent aussi jouer un rôle dans l'équilibrage de charge (load
balancing), ils peuvent par exemple contacter plusieurs serveurs de destination en fonction de leur charge respective,
mais ceci dépasse le cadre de cet article.

- 26 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Une configuration en reverse proxy

Il est bien sûr possible de mixer le forward et le reverse proxy, et il est aussi possible
que plusieurs proxies relayent la requête du client entre eux en créant alors un chemin
de proxies.
Le but principal des proxies HTTP est souvent le même : si une machine proxy proche du
client possède la ressource demandée et que celle-ci est valide, la chaine va alors être
brisée et le serveur d'origine (ainsi que les éventuels proxies intermédiaires éventuels) ne
sera alors pas contacté.
Il existe des protocoles, comme "ICP" (Inter Cache Protocol), capables de faire
communiquer les caches entre eux, dans des relations parents/enfants. Cela dépasse le
cadre de cet article, notez simplement quelques protocoles s'ils vous intéressent : ICP,
CARP, HTC et WCCP).

VII-B - Rôles

Les rôles d'un proxy HTTP sont très divers :

1 Cache: C'est clairement le rôle principal et la partie sur laquelle nous allons nous étendre dans le chapitre
suivant, un proxy va pouvoir mettre en cache une ressource qu'un client A lui demande, et éventuellement la
resservir à un client B la demandant plus tard. Il y a donc économie de bande passante et de latence réseau,
car le serveur original dissimulé derrière le (ou les) proxy n'est pas réintérrogé et souvent le serveur proxy se
situe physiquement proche des clients (donc un routage et une latence optimale).
2 Authentification: Un proxy peut demander à ses utilisateurs de s'authentifier avec lui avant de pouvoir l'utiliser.
C'est un processus simple de contrôle de l'accès au web.
3 Filtrage de requête: Très à la mode dans les entreprises, un proxy va pouvoir interdir telle ou telle requête à
tel ou tel client. L'exemple typique est le cas des sites à caractères pornographiques, ou encore les sites de
partage de vidéos. Une liste de sites est alors chargée dans le serveur proxy, qui l'analyse à chaque requête
de client.
4 Filtrage de réponse: Plus rare mais tout aussi possible, le proxy va analyser la source (HTML souvent) de
la réponse, et remplacer des parties de codes avant d'envoyer la réponse modifiée au client. Typiquement il
pourra s'agir de plublicités ou encore de javascripts malicieux. Notez que les reverses proxies utilisent une
telle technique pour réécrire les liens des pages afin qu'ils ne comportent pas d'indication sur le serveur de
destination. Apache permet ceci via mod_proxy_html.
5 Balance de charge: Un proxy peut aiguiller certains clients, sur cetains serveurs, en fonction de la ressource
demandée. C'est assez rare, d'autres solutions plus adaptées et jouant avec les couches basses d'OSI
existent. (Voyez mod_proxy_balancer de Apache)

- 27 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

6 Préchargement: Charger des données avant même qu'un client ne les demande, en supposant qu'il va les
demander dans le futur. Le cas classique des images d'une page HTML est très explicite : le proxy télécharge
en avance les images sur le serveur original, à la seconde même ou le client lui a demandé la page HTML les
comportant.
7 Transcodage: Le proxy peut traduire ou transcoder les caractères d'une page, en fonction des préférences
linguistiques du client et de la réponse du serveur.

Il existe sur l'Internet des tonnes de proxies HTTP. La plupart sont des reverse, et en
entreprise, souvent, des forwards proxies sont présents. Les tâches principales d'un proxy
HTTP sont le cache et le filtrage, notamment en entreprise.
Souvent, un proxy signale qu'il a été utilisé en rajoutant sa signature au travers d'un en-
tête spécifique : "Via"; mais ça n'est pas obligatoire : un proxy peut alors agir de manière
totalement transparente, et il demeure impossible de savoir qu'il est là à première vue.
Certes, une analyse bas niveau du réseau au moyen de mtrace, traceroute ou autres outils
Linux permettra de découvrir les proxies sur le chemin.

VII-C - La mise en place sur les clients

Pour mettre en place un forward proxy sur un client (navigateur), il existe 3 méthodes :

1 Indiquer explicitement au client quel serveur utiliser comme proxy


2 Indiquer explicitement au client un script javascript qui va determiner le serveur proxy à utiliser
3 Utiliser du filtrage réseau bas niveau pour rerouter la requête de manière transparente vers un proxy

Dans le cas d'une mise en place manuelle, il faut configurer chaque client. Pour Firefox, il suffit d'aller dans les options
avancées du réseau, et indiquer le serveur et le port du proxy. Pour les programmes comme wget ou lynx, ils scrutent
une variable d'environnement "http_proxy".
L'autre méthode consiste à indiquer l'adresse URL vers un script PAC (Proxy Auto Configuration) écrit en javascript,
qui devra alors retourner l'adresse d'un serveur proxy que le navigateur utilisera alors pour effectuer sa requête. Cette
technique est pratique dans le cas d'une entreprise, car tous les navigateurs auront dans leur configuration le même
fichier PAC qu'il suffira alors de changer pour repercuter les modifications partout.
Le script PAC va pouvoir aussi faire tourner les adresses des serveurs proxy qu'il retourne, en fonction du hasard
ou de la requête effectuée (équilibrage de charge)
La valeur de retour d'un telle fonction est de la forme :

PROXY host:port
SOCKS host:port
DIRECT

Il est important de noter que ce script doit être situé sur un serveur HTTP accessible du client, et doit être retourné
avec un en-tête "Content-Type: application/x-ns-proxy-autoconfig" sinon il ne sera pas reconnu comme script de
configuration automatique par les navigateurs Webs.
Le PAC a été inventé par Netscape dans sa version 2 et est encore largement utilisé en entreprise de nos jours.

Enfin la troisième méthode, elle, est totalement transparente. On appelle celà un "proxy d'interception" (et non pas un
proxy transparent). Ceci consiste à modifier les règles de routage du routeur physique qui se charge de la requête, afin
de détecter s'il s'agit d'une requête HTTP (port 80). Si c'est le cas, la requête est alors routée vers un serveur proxy.
Cisco propose des protocoles pour cela, certains switchs matériels aussi (le firmware DD-WRT propose cela), mais
sinon, toute machine UNIX peut faire l'affaire.
Nous allons prendre comme exemple une machine Linux avec un noyau supérieur à 2.4 (autorisant la fonction
iptables)

routage bas niveau pour proxy d'interception


> iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 80 -j REDIRECT --to-ports 8080

- 28 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Ce code suppose que la machine de routage est la même que la machine qui heberge le proxy. Sinon, il faudra faire
du NAT de source et de destination.
Tout le monde peut tester ceci, il suffit d'une machine Linux avec un noyau 2.4 ou plus et de 2 cartes réseaux. Bien
sûr il faudrait compléter un tel script de manière à ce que si le proxy ne fonctionne plus, le traffic soit libéré.

VII-D - Exemple pratique

Squid est un excellent produit, il s'agit d'un programme dédié à la tâche de proxy HTTP. Cependant nous allons baser
un exemple pratique avec Apache et mod_proxy.
Il s'agit tout d'abord de compiler Apache avec le support du proxy. Nous ne nous interessons qu'à HTTP, le proxy
FTP est autre chose, non abordé ici :

Ligne basique de compilation d'Apache


./configure --enable-modules=proxy proxy_http
make
make install

Si vous voulez qu'Apache proxie tout le temps (et non ponctuellement), compilez les
modules en statique comme dans l'exemple si dessus : vous gagnerez en performance
face à un chargement dynamique (DSO)

Attention, mod_proxy n'effectue aucune opération de cache, cette tâche est déléguée à
mod_cache et ses amis.
Attention, mod_proxy ne sait proxier les demandes de tunnel HTTPS (méthode
CONNECT), il faut pour cela compiler mod_proxy_connect en plus.

Passons à la configuration du serveur. En général, un forward proxy n'écoute pas sur le port 80 réservé au service
HTTP. Il est usuel d'utiliser 8080, c'est ce que nous allons faire :

Configuration d'Apache pour agir en forward proxy


Listen 8080
NameVirtualHost *:8080

<VirtualHost *:8080>
ServerName proxy.jp-developpez

ProxyRequests On
ProxyVia On
<Proxy *>
Order deny,allow
Allow from 192.168
Allow from 127.0.0.1
Deny from all
</Proxy>

ProxyBlock verybadsite.com
ProxyRemote * http://the-second-proxy.com:8080

LogFormat "From:%h(%a) at %t for \"%r\" \n %V responded: %>s (at %s) -%B bytes- %f" proxycommon
CustomLog logs/proxy.log proxycommon

ErrorDocument 403 "<h1>Forbidden</h1> This port should be used as a proxy"

<Directory />
Order allow,deny
Deny from all
</Directory>
</VirtualHost>

- 29 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Toutes ces directives sont clairement documentées dans la documentation officielle de Apache, j'en passe tout de
même quelques une en revue :

1 ProxyRequest : permet à Apache d'agir comme forward proxy


2 ProxyVia : Apache va indiquer dans les réponses à ses clients qu'il a été utilisé comme proxy dans la requête
3 <Proxy *> : Très important, permet de limiter l'usage du proxy à certains clients identifiés par leurs adresses
IP. Faites très attention de ne pas ouvrir un proxy sur le Web, vous serviriez alors de relai à tout et n'importe
quoi, c'est très dangereux.
4 ProxyBlock empêche l'accès à certains sites par domaine ou adresses IP. Un proxy peut donc filtrer le traffic
qui passe par lui et éventuellement le bloquer totalement.
5 ProxyRemote indique un proxy vers qui relayer formant ainsi le début d'une chaine de proxies. Ici, toutes les
requêtes proxiées par Apache le seront non pas vers le serveur de destination, mais vers un autre serveur
proxy.
6 LogFormat et CustomLog permettent d'enregistrer toutes les requêtes des clients
7 ErrorDocument et Directory permettent d'empêcher quelqu'un d'accéder à ce port 8080 de manière directe,
via l'URL

Il suffit maintenant d'indiquer ce serveur comme proxy dans les navigateurs des clients, et le tour est joué.

mod_proxy ne supporte pas encore les proxies transparents. Pour celà, vous devez
indiquer
RewriteEngine on
RewriteCond %{THE_REQUEST} ^[A-Z]{3,5}\ (/[^?\ ]*)
RewriteRule ^/ http://%{HTTP_HOST}%1 [NE,P]
dans votre VirtualHost.
Ceci permet de réécrire la requête en une requête de proxy.

Un proxy repère une requête à proxier grâce à la ligne de requête. Une requête vers un
proxy comporte toute l'URL dans la ligne de requête, et non juste la ressource demandée.
Cette transformation est mise en oeuvre par les clients HTTP usuels, ainsi en cas de proxy
transparent, cette transformation n'est pas effectuée.

- 30 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

VIII - Le cache

Depuis la conception de HTTP 1.0, l'économie de ressources par le cache a été pensé. Globalement, le cache
HTTP permet à un client de ne pas retélécharger une ressource si celle-ci est encore, ou a une grande probabilité
d'être encore valide dans un cache (généralement situé proche du client afin de raccourcir au maximum le temps
de réponse)
Le cache HTTP a été crée avec 3 objectifs à accomplir :

1 Faire en sorte que les pages webs chargent plus vite (réduire la latence)
2 Réduire la bande passante globale consommée
3 Réduire la charge sur le(s) serveur(s) proposant la ressource

HTTP 1.0 propose une solution très basique de cache de ressources, nous la détaillerons.
HTTP 1.1 fournit un mécanisme beaucoup plus complet et complexe de gestion du cache, nous le détaillerons aussi
et noterons les différences avec HTTP 1.0.

Même si cela n'est pas très français, nous parlerons de donnée "cachable" ou encore de
donnée "cachée" (non pas dans le sens "invisible" mais dans le sens "stockée dans un
cache")

VIII-A - Définitions

La latence représente le temps que met une requête pour arriver à sa destination. Cet article n'étant pas orienté
réseau, sachez simplement qu'il existe des algorithmes d'une compléxité incroyable permettant à un paquet IP de
"choisir la meilleure route" pour arriver d'un point A à un point B. Or, il arrive dans certains cas (pensez à une finale
de coupe du monde fraichement remportée) que le réseau soit surchargé. Vont alors apparaitre des files d'attentes
dans les routeurs Internet, et une partie du traffic devra trouver une route plus longue que la normale.
Dans le meilleur des cas, le cache permet d'éviter totalement la requête, dans un cas moins bon, il permet de router
la requête de manière plus appropriée (au moyen de proxies).

Le problème de la bande passante, lui, est simple à comprendre : elle coûte (très) cher et au moins un client en
consomme, au plus son fournisseur est heureux. Ainsi, si un client peut charger une ressource HTTP depuis un
cache sur son réseau local, plutôt que d'en sortir par sa passerelle pour aller sur le Web, c'est alors de la bande
passante Web économisée.

Idem concernant la charge des serveurs, on comprend rapidement qu'au moins un serveur est chargé (au moins il
traite de clients à la seconde), au plus il sera réactif.

Il existe différents types de cache qu'il faut bien différencier :

1 Les caches privés : se sont les caches intégrés aux clients web de type navigateurs webs, ils peuvent être
mémoires (RAM), ou disques.
2 Les caches publics : se sont des caches partagés : des machines proxy (forward proxy) situées entre des
clients et un/des serveurs. Ils peuvent être volontaires, ou alors forcés (invisibles)

Quoiqu'il arrive, il faut bien distinguer le cache public du cache privé. Le cache privé est
(par définition) propre à un seul client : c'est son navigateur, et ce cache là est désactivable
ou configurable selon les navigateurs
Un cache public (reverse ou forward proxy) est partagé entre plusieurs clients, et là il va
s'agir de faire très attention de ne pas afficher la page de l'utilisateur "toto", à l'utilisateur
"titi".
Ainsi, les mécanismes de cache HTTP paraissent souvent confus et compliqués, alors
qu'ils ne le sont pas. Ils sont simplement "touffus" : il y a pas mal de paramètres qui peuvent
entrer en jeu.

- 31 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Sous Firefox, tapez "about:config" dans la barre d'adresse et validez. Les paramètres
network.http.use-cache, et browser.cache.*** servent à gérer le cache privé.
Voyez http://kb.mozillazine.org/About:config_entries pour plus d'infos, et faites
attention de ne pas "jouer" avec ses paramètres à l'aveugle : vous risquez de bloquer votre
navigation ou de devenir un "mauvais client" web.
Sous Firefox toujours : taper F5 demande une revalidation de la ressource envers le
serveur de destination, alors que taper ctrl+F5 demande de sauter tous les proxies et
de contacter directement le serveur de destination et désactive donc le cache lors du
rafraichissement.

Lorsqu'un client demande une ressource et que la réponse provient d'un cache, on appelle cela un "cache hit". Si la
réponse au contraire est issue du serveur original, il s'agira d'un "cache miss"
Le ratio cache hit / cache miss donne la performance globale d'un serveur de cache. Il faudra par contre porter une
attention très particulière à la "fraicheur" des données. En effet, lorsqu'on demande à un cache une ressource, il doit
être capable de savoir si celle qu'il possède en lui est fraiche (il peut alors la servir lui même au client), ou périmée
(il doit alors contacter le serveur d'origine pour lui demander une copie fraiche).
Pour déterminer la fraicheur d'une ressource, le cache possède 2 solutions : soit la ressource a déclaré elle-même
(c'est le comportement conseillé) sa période de fraicheur aux moyens d'en-têtes HTTP que nous allons détailler,
soit alors le cache doit faire appel à des heuristiques (des lois d'hypothèses mathématiques) afin de deviner (de
supposer) si la ressource est fraiche ou périmée.

VIII-B - Le fonctionnement

Un cache est donc soit un proxy (cache public : une machine physique située entre le client et le serveur de
destination), soit un navigateur web (cache privé). Comment fonctionne le cache ?
Dans un premier temps, il convient de déterminer si la ressource demandée est "cachable", car elles ne le sont pas
toutes. Pour cela, il faut analyser :

1 Le code de réponse
2 Le type de requête
3 Les en-têtes Expires, Cache-Control et Pragma
4 La présence ou non, d'un mécanisme d'authentification

La gestion du cache sur HTTP est un jeu complexe entre tous ces paramètres, dont certains ont une priorité supérieure
à d'autres.
Le but est toujours le même : faire pour le mieux, c'est à dire fournir un maximum de données depuis le cache aux
clients et un maximum de données valides, c'est à dire n'ayant pas changé entre temps. Tout un programme !

Le cache en fonction des méthodes de requête


• GET: Toujours cachable par défaut, sauf si un en-tête de cache précise le contraire.
• HEAD: Peut être utilisé pour mettre à jour la donnée précédemment cachée.
• POST: Non cachable par défaut, sauf si un en-tête de cache précise le contraire.
• PUT: Cache interdit
• DELETE: Cache interdit
• OPTIONS: Cache interdit
• TRACE: Cache interdit

Voici déja un bon point, il faut savoir que certains serveurs ou clients peuvent passer outre ces recommendations
fournies par la RFC, même si c'est bien entendu fortement déconseillé.
Ainsi, les en-têtes de cache que sont Cache-Control et Expires sont maitres, car ils peuvent changer les
comportements par défaut de certaines méthodes de requête HTTP.

Petite note concernant HEAD. Nous avons vu que cette méthode de requête ne contient
pas de corps, et que sa réponse non plus. HEAD n'est donc pas cachable, cela n'a pas

- 32 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

de sens, mais HEAD peut être utilisée pour lire les en-têtes de réponse et mettre à jour
un cache trop vieux (on parle de validation du cache).

VIII-B-1 - Au coeur du mécanisme de cache de HTTP 1.0

HTTP 1.0 proposait un mécanisme de cache sommaire, mais qui continue aujourd'hui de fonctionner et de suffir dans
de nombreux cas (car pour rappel HTTP 1.1 est compatible 1.0).

Une réponse d'un serveur doit toujours comporter un en-tête Date, ceci est obligatoire,
mais encore aujourd'hui certains (très rares) ne l'envoient pas.
Ce champ va servir au cache à faire des calculs.

Commençons par les plus simples : toute réponse comportant un en-tête Expires est cachable. Même une requête
POST normallement non cachable le devient si un en-tête Expires est présent dans la réponse.
Si un client sait quand est-ce qu'expire une ressource, il pourra alors sans problème se servir dans son cache (pour
un navigateur web, il se servira sur le disque dur ou dans la mémoire vive) à chaque demande de cette ressource,
jusqu'à ce que la date spécifiée par Expires soit atteinte ou dépassée. Idem pour les cache publics (les proxies).
Expires évite donc au client HTTP de demander la ressource, mais évite aussi toute requête de validation, c'est à
dire demander si la ressource est toujours "fraiche" en cache.

Concernant les ressources dont on sait qu'elles ne changeront pas (images, css, js, etc...)
il FAUT envoyer un en-tête Expires. Trop peu de concepteurs d'applications sur le web
oublient cette évidence pourtant tellement simple et salvatrice de bande passante, de
réseau, etc... Attention, il est indiqué dans la RFC de ne pas dépasser un délai de 1 an
dans Expires (date actuelle + 1 an maximum).

Une réponse cachable


HTTP/1.1 200 OK
Date: Sun, 04 May 2009 18:27:12 GMT
Content-Type: image/gif
Expires: Sun, 12 May 2009 18:27:12 GMT
Connection: Keep-Alive

Une réponse invalide car pas d'en-tête 'Date:', elle peut par contre être accéptée par un client de manière
transparente
HTTP/1.1 200 OK
Content-Type: image/gif
Connection: Keep-Alive

C'est simple : si la date indiquée par Expires est supérieur à celle de l'en-tête Date (c'est le cas de notre premier
exemple ci-dessus), alors le cache sait que la donnée est non-seulement cachable, mais il sait aussi quand est-ce
qu'il devra demander au serveur d'origine de revalider la donnée (via une requête HEAD par exemple). Il ne le fera
pas avant, sauf si on le force (typiquement : rafraichissement volontaire de la page par pression sur F5).
Un en-tête Expires exactement égal à l'en-tête Date signifie que la ressource est cachable, mais devra être revalidée
dès la prochaine requête (c'est aussi le cas avec une valeur de Expires à 0)
Pour désactiver le cache en HTTP 1.0, utilisez Pragma: no-cache.

Sous Apache, le champ Expires n'est pas géré par défaut, il faut pour celà activer le
mod_expires et le configurer.

Notons que les en-têtes Date comme Expires expriment une date calendaire ce qui mène souvent à des problèmes
de synchronisation d'horloge car des serveurs peuvent avoir une horloge déréglée ou décalée. La date est toujours
spécifiée GMT, les décalages horaires ne représentent donc pas un problème.
Une solution aux problèmes de synchronisation a été trouvée et implémentée dans HTTP 1.1.

- 33 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Passons à l'en-tête de réponse Last-Modified. Du même format que Date (une date calendaire), il indique au client
la date à laquelle la ressource est supposée avoir été modifiée pour la dernière fois. Pour un fichier statique, le
serveur HTTP interroge simplement le système de fichier. Pour les ressources "dynamiques" (CGI, PHP etc...), c'est
au développeur à penser à fournir cet en-tête, car le serveur ne le fera pas par défaut, sauf si on le configure pour
(mod_header de Apache).
Last-Modified va servir à la validation de la ressource. Lorsque la date indiquée par Expires est dépassé, ou lorsque
l'en-tête Expires est absent de la réponse, à la prochaine demande de la ressource concernée, le cache va effectuer
une requête conditionnelle au moyen de l'en-tête If-Modified-Since. Si la ressource n'a pas changé depuis cette date,
une réponse 304 Not-Modified sera retournée (sans le contenu de la ressource en question, bien entendu) et le cache
considèrera alors cette ressource comme toujours fraiche.
Mieux que celà : le cache va alors mettre à jour la Date de cet élement dans son espace de stockage et pourra
effectuer des calculs de "vieillesse" et de fréquence de demande de cette ressource là, afin de mieux gérer son
espace de stockage.
Le facteur appellé LM-age, (LM - Date) va servir au cache dans des statistiques de calcul concernant la ressource.

En conclusion, l'absence de Expires dans la réponse ne va pas empêcher le cache


(attention tout de même : voir les méthodes HTTP cachables) mais va faire provoquer au
cache une demande de validation envers le serveur de destination à chaque requête de
la ressource.
L'absence de Last-Modified dans la réponse inhibe le processus de validation, et le cache
ne pourra alors pas savoir si la ressource a changé ou pas, lorsqu'il a besoin de la
valider : ceci amène donc à la redemande complète de la ressource envers le serveur
de destination et à une perte lourde dans l'interêt du cache HTTP (Apache par exemple,
envoie systématiquement un en-tête Last-Modified sur un contenu "statique").
L'absence à la fois de Expires et Last-Modified annule tout mécanisme de cache
(recommandé par la RFC)

VIII-B-2 - Au coeur du mécanisme de cache de HTTP 1.1

HTTP 1.1 apporte un mécanisme de cache beaucoup plus poussé et détaillé que celui implémenté dans HTTP 1.0
(qui n'en demeure pas moins efficace tout de même).
Tout va se jouer sur l'en-tête Cache-Control, réellement spécifique à HTTP 1.1. Cet en-tête peut à la fois faire partie
d'une requête comme d'une réponse. Nous analyserons ici sa position dans une réponse HTTP.
Cache-Control va permettre de gérer très finement à la fois les processus de cache (navigateur et proxies, ou encore
caches publics et privés, vont être différenciés), mais aussi le processus de validation. Il va aussi donner une réponse
au problème des dates au format calendaire.

Cache-Control: private indique que les caches privés (navigateurs) peuvent stocker la ressource, mais pas les caches
publics (proxies). Pratique lorsqu'il s'agit d'informations propres à un utilisateur.
Cette directive rend cachable toute réponse qui ne l'est pas par défaut (réponse à POST par exemple).

Cache-Control: public autorise le stockage par les caches publics et privés. C'est aussi le seul en-tête qui autorise
les caches, notamment les proxies, à stocker une réponse à une requête demandant authentification.

Cache-Control: no-cache est un faux-ami, ceci n'indique pas d'éviter à tout prix de mettre en cache la réponse! Cette
directive oblige les caches privés ou publics à systématiquement revalider la ressource à chaque demande, et à ne
jamais supposer qu'elle sont valides au sein du cache sans revérifier ceci sur le serveur de destination.
Un cas particulier concerne la spécification d'un en-tête de réponse derrière no-cache : Cache-Control: no-cache=Set-
cookie par exemple indique aux caches de ne pas stocker cet en-tête de réponse dans le cache. Très important pour
les cookies de session!

Cache-Control: no-store. Voici la directive interdisant la mise en cache de la réponse, quel que soit le cache considéré.
(Notons que si cet en-tête est un en-tête de requête, il indique alors que la réponse doit comporter la même directive,
et donc ne pas être cachable).

- 34 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Certains serveurs, comme Apache, proposent des directives permettant volontairement de


violer le protocole, et de mettre en cache des réponses malgrés des en-têtes indiquant le
contraire. Il est bien entendu hautement recommandé de ne pas utiliser de telles directives.

Cache-Control: must-revalidate va indiquer à un cache que la ressource doit être revalidée si elle arrive à expiration.
Comme c'est théoriquement le cas par défaut, cet en-tête est confu et utilisé dans le cas ou le cache (proxy
typiquement) serait tenté de retourner une réponse expirée sans la revalider (congestion réseau par exemple).
Cette directive autorise aussi le cache de ressources qui n'étaient pas cachables à l'origine (réponses soumises à
authentification par exemple). Cache-Control: proxy-revalidate est indentique mais concernant les caches publics.

Cache-Control: max-age=xxx max-age corrige le problème des dates en donnant un temps relatifs à la date de la
réponse, pendant lequel le contenu est toujours valides.
Cet en-tête peut donc remplacer Expires en HTTP1.1 et de ce fait, permet la mise en cache d'une ressource même
si celle-ci n'est par défaut pas cachable.

Cache-Control: s-maxage=xxx s-maxage est identique à max-age, mais ne s'applique qu'aux caches publics : les
proxies.

Cache-Control: no-transform Cette directive indique aux proxies de ne pas transformer la ressource. Certains proxies
peuvent ré-encoder des images, ou compresser la ressource pour plus d'efficacité. Cette directive leur indique de ne
pas transformer celle-ci, de quelque manière que ce soit.

Cache-Control: max-stale:xxx Un en-tête de requête indiquant qu'un client accepte des réponses non fraiches. Si un
proxy s'aperçoit que la ressource a expiré, il va tenter de la revalider. Si la revalidation échoue, le proxy est autorisé à
renvoyer la ressource vieille depuis son cache, et non validée (celle-ci peut alors être erronnée car elle a pu changé).
Le client indique via max-stale qu'il accepte des réponses risquant d'être erronnées, mais la réponse devra le spécifier
par un Warning: 110 Response is stale par exemple.

VIII-B-3 - Fraicheur des données, validations et requêtes partielles

Lorsqu'une ressource a expiré, le cache (privé ou public) doit la revalider. Il est aussi possible de demander
revalidation explicitement, quel que soit l'âge de la ressource, grâce à 3 mécanismes : Cache-Control: no-cache,
Cache-Control: max-age=0 ou Cache-Control: must-revalidate.
La validation se fait par une "requête partielle", qui consiste simplement à demander "La ressource XXX a-t-elle
changé ?". Il existe alors 2 manières de faire.

La requête conditionnelle sur Last-Modified. Toute réponse cachable devrait inclure un en-tête Last-Modified qui
précise la date de modification de la ressource. Le cache peut ainsi forger une requête conditionnelle If-Modified-
Since afin de valider la fraicheur de la ressource expirée (ou non : forcée à être revalidée) par rapport à cette date là:

Validation d'une ressource


HEAD /path/to/resource HTTP/1.1
If-Modified-Since: Fri, 11 Sep 2009 11:28:49 GMT

Une réponse négative sera de type 200 et refournira la ressource complète que le cache mettra à jour.
Une réponse positive en revanche, sera de type 304 et incluera une Date et un nouvel en-tête Expires qui pemettront
au cache de se mettre à jour afin d'éventuellement prolonger la durée de vie da la ressource.

Last-Modified est très important aussi pour calculer la fraicheur de la donnée que l'on appelle le "LM factor". En
soustrayant la date de Last-Modified à la date de Date, un cache peut ainsi estimer la fraicheur de la ressource
et organiser son espace de stockage en conséquence. Par exemple il pourra supposer qu'une ressource ayant un
LM-factor petit vient de changer, et sera plus susceptible de changer encore qu'une autre ressource ayant un plus
grand LM factor.

- 35 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

Last-Modified présente cependant quelques problèmes : echelle de une seconde (si la ressource change 8 fois par
seconde ?), problème de synchronisation des horloges, et problème lors de la copie de ressources sur le serveur,
altérant la date de modification du fichier alors que celui-ci n'a pas changé (cp -p sous Linux pour pallier à ce
problème).
Un autre système de validation existe aussi : l'entity tag (Etag) L'Etag est calculé en fonction de facteurs (dépend
des programmes) et se présente de cette manière :

Une réponse incluant un Etag


HTTP/1.1 200 OK
Date: Fri, 11 Sep 2009 11:28:49 GMT
ETag: "8eca4-205f-17b94c"

La requête conditionnelle utilise alors "If-None-Match" :

Requête de validation utilisant l'Etag


HEAD /path/to/resource HTTP/1.1
If-None-Match "8eca4-205f-17b94c"

Si le tag est valide, une 304 sera retournée. HTTP autorise par contre un serveur à utiliser plusieurs tags pour une
seule ressource. Un cache peut stocker plusieurs versions de la même ressource, avec des tags différents, d'où le
"If-None-Match" qu'on peut traduire par "Si aucun Tag ne correspond". On peut donc voir des requêtes de validation
comme :

Requête de validation utilisant plusieurs valeurs d'Etag


HEAD /path/to/resource HTTP/1.1
If-None-Match "foo", "bar", "baz"

Attention car les ETags sont générallement calculé par serveur (voyez le mécanisme de calcul de votre cache en
lisant sa doc technique), et souvent basé sur l'inode du fichier. Ainsi si un tourniquet est mis en place, un client pourrait
contacter un serveur d'abord, puis un autre ensuite mais concernant la même ressource. Comme les deux serveurs
n'ont pas le même Etag, la validation échouera et la ressource sera alors retéléchargée.

VIII-B-4 - Provoquer le cache ou l'éviter

Pfiouuu, que d'informations (et encore, c'est non exhaustif hein). Le mieux est que chacun fasse des TPs de son
coté ;-) Avec les machines virtuelles en plus de nos jours, c'est très facile de tester un produit ou même plusieurs
(et de créer des chaines de proxies).
Bon, pour y voir plus clair quand même, dans un premier temps, comment provoquer le cache de ressources ?

1 Si vous connaissez le principe des SSI (Server Side Includes) : ceux-ci sont pas définition non cachables :
évitez les
2 Utilisez GET. POST n'est par défaut pas cachable et c'est logique quand on sait à quoi sert POST
3 Ne renommez pas les fichiers sur votre serveur : ils compteront comme de nouvelles ressources et feront
échouer le cache et la validation
4 Utilisez Expires, c'est l'en-tête magique le plus puissant pour le cache
5 Utilisez Last-Modified, vous aiderez énormément le cache lors de la validation de la requête. Vous l'aiderez
aussi pour ses calculs internes de fraicheur. Last-Modified est presque aussi important que Expires, c'est le
duo de choc pour provoquer le cache
6 Si vous utilisez du CGI et du contenu statique, séparez les physiquement sur 2 serveurs différents. Les
serveurs s'en sortent bien concernant le contenu statique : ils peuvent tout faire eux-mêmes, alors que sur le
CGI c'est aux développeurs de tout implémenter à la main
7 N'utilisez pas la négociation de contenu, ou alors réglez le très finement grâce à l'en-tête Vary
8 N'utilisez pas l'authentification HTTP, elle provoquera par défaut la désactivation de tout mécanisme de cache

- 36 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

9 Si vous n'aimez pas les proxies, proposez tout de même la mise en cache niveau navigateur, grâce à Cache-
Control: private

Ou au contraire, voyons quelques recommandations sur comment éviter le cache ?

1 Plutôt que d'éviter le cache à tout prix, préférez spécifier que vous voulez systématiquement revalider vos
ressources à tous niveaux. Un cache-control: no-cache est très efficace pour cela
2 Pour désactiver vraiment le cache, utilisez alors Cache-control: no-store ou son équivalent HTTP 1.0 Pragma:
no-cache

- 37 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

IX - L'authentification

- 38 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

X - Négociation de contenu

- 39 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

XI - Gestion des connexions TCP avec HTTP

HTTP est un protocole de niveau 7 OSI sur la couche applicative. Il est donc porté par tous les protocoles de niveau
inférieur. Sans entrer dans les détails d'OSI, HTTP utilise la couche transport TCP (port 80), avec tous les avantages
et les inconvénients de ce protocole. Nous n'allons pas faire un cours sur TCP, mais simplement rappeler (très
globalement) que l'avantage de TCP réside dans son mode "connecté".
TCP effectue un lourd travail permettant d'assurer que les données transportées ont bien été reçues (détection
d'erreurs et accusés de réception), elles sont intègres (détection d'erreurs et ré-émission éventuelle) et numérotées
ce qui permet de les recomposer à l'autre bout de la connexion. La machine réceptrice envoie pour chaque paquet
TCP un accusé de réception, et les 2 machines en communication négocient la taille et la segmentation des données
en paquets.
TCP est donc un protocole d'une grande fiabilité et ceci a un coût. Les mécanismes de connexion de TCP imposent
une poignée de main en 3 temps entre les 2 machines. Lorsqu'une machine émétrice désire envoyer des données,
elle doit d'abord ouvrir une connexion (étape 1). La machine récéptrice indique alors qu'elle est là, et qu'elle accepte
la connexion (étape 2).
Enfin, la machine émétrice renvoie un paquet indiquant qu'elle a pris en compte la réponse postive de l'autre partie
(étape 3), la connexion est alors établie et les paquets de données "utiles" peuvent alors commencer à circuler.
La fermeture de la connexion, elle, s'effectue en 2 temps.

Ce processus est lourd. Chaque connexion HTTP necéssite une connexion TCP. Une page Web comportant 50
images et 10 fichiers javascripts nécessitera donc 61 connexions entre le client et le serveur.
Une telle page web peut alors mettre un certain temps avant d'arriver "entière" jusqu'au client, qui peut vite avoir une
impression de ralentissement très désagréable.
Pour pallier à ce problème, HTTP utilise des mécanismes pour gérer, piloter et commander la connexion entre les
2 parties concernées (ou plus, si des proxies existent). Les connexions parallèles, les connexions persistantes et
le "pipelining".

XI-A - Connexions parallèles

Pour assurer un meilleur traffic et une meilleure perception de fluidité sur le Web, les navigateurs peuvent envoyer
plusieurs requêtes simultanément sur plusieurs connexions TCP. On appelle celà les connexions parallèles. L'erreur
est de se dire tout de suite que ceci accélère les choses. Si vous avez bien suivi l'introduction de ce chapitre, vous
savez qu'établir une connexion TCP coûte cher.
Aussi, un serveur est limité en nombre total de connexions qu'il peut traiter, il y a un risque de le saturer. Enfin,
les connexions parallèles ne sont efficaces et avantageuses que si la bande passante le permet : un client surfant
avec un modem à bas débit va saturer probablement une des connexions parallèles, plus lourde que les autres (une
très grosse image), laissant ainsi les autres avec très peu de bande passante disponible : elles deviennent alors
inefficaces, voire même contre-efficaces, lorsqu'on sait que TCP emet des paquets de contrôle entre chaque paquet
de données.

Il faut donc utiliser un nombre de connexions restreint (Firefox 3 propose 15 par défaut), et utiliser une connexion à
large bande, sinon l'efficacité ne sera pas au rendez-vous.

Firefox permet de modifier le nombre de connexions via ses paramètres network.http.max-


connections et network.http.max-connections-per-server.

XI-B - Connexions persistantes

Les connexions persistantes n'ont rien à voir avec les connexions parallèles vues juste avant. Elles permettent au
serveur de ne pas fermer la connexion TCP dès que la requête est terminée. Le client pourra alors réutiliser la
connexion sans devoir la re-négocier.
HTTP 1.0 ne supporte pas les connexions persistantes nativement, mais des extensions de la norme ont tout de
même rendu possible ce paradigme. Il est en HTTP 1.0 mal supporté, et peu efficace.

- 40 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

HTTP 1.1 introduit un changement fondamental dans la gestion des connexions entre le client et le serveur, puisqu'il
définit et supporte clairement les connexions persistantes, mais en plus il fait de celles-là un standard utilisé par défaut.
Sauf avis contraire, en HTTP 1.1, toute connexion est par défaut persistante (cette caractéristique à été longuement
débattue à l'époque). Au contraire avec HTTP 1.0, sauf si le serveur répond avec un en-tête Connection: keep-alive
et que le client a expréssement demandé une connexion persistante avec le même en-tête dans sa requête : la
connexion est fermée par défaut.

Nous allons rester sur HTTP 1.1. Lorsqu'un client emet une requête, il sait que le serveur par défaut ne fermera pas
la connexion. Ainsi le client va pouvoir réutiliser celle-ci dès qu'elle est libre, pour envoyer une autre requête.
A tout moment, le serveur comme le client peut répondre par un en-tête Connection: close, ce qui aura pour but de
fermer la connexion. Un client ne peut pas savoir si un serveur fermera un jour une connexion, c'est pour celà qu'un
processus de ré-emission de la requête est mis en place si la connexion venait à être fermée au moment précis où
le client tente d'envoyer une requête.
Quoi qu'il en soit, toute connexion persistante est tout de même fermée au bout d'un moment sinon le serveur peut
arriver à cours de connexions TCP et ne plus pouvoir répondre.

Apache propose pour la gestion des connexions, les directives KeepAliveTimeout,


KeepAlive, Timeout et MaxKeepAliveRequests

Il est impératif pour que les connexions persistantes puissent prendre place, de bien spécifier un en-tête Content-
Length ou un Transfert-Encoding: chunked. Ceci va permettre aux 2 parties de faire la différence entre les parties de
2 requêtes consécutives sur une même connexion. Là encore, un client devrait rester raisonnable et ne pas ouvrir
trop de connexions persistantes afin d'éviter que celle-ci ne restent en attente et non fermées.
Il existe un en-tête permettant de définir les caractéristiques de la connexion persistante, il s'agit de Keep-alive. Il
peut prendre 2 valeurs (plus en réalité, mais les autres sont peu importants). timeout va indiquer combien de temps
la connexion va être maintenue dans un état de sommeil. max précise combien de requêtes peuvent encore être
envoyées sur cette connexion avant qu'elle ne soit fermée.
Attention, ces indications ne sont en aucun cas des garanties, et un serveur pourra changer d'avis (notamment dans
le cas ou il arrive au bord de la saturation). L'en-tête de réponse Keep-alive n'est pas définit dans HTTP 1.1, mais
dans HTTP 1.0. Il est cependant précisé dans HTTP 1.1 la plupart du temps, tout comme la plupart des navigateurs
webs précisent connection:keep-alive en HTTP 1.1 alors que ceci n'est pas nécessaire (compatibilité HTTP 1.0).

Firefox permet de modifier le nombre de connexions persistantes par serveur via son
paramètres network.http.max-persistent-connections-per-server.

Pour aller plus loin, vous pouvez lire HTTP Performance du W3C ou encore HTTP Connection Management

XI-C - Pipelining

Le pipelining est une application des connexions persistantes. Cela consiste pour un client à envoyer plusieurs
requêtes à la suite dans la même connexion, sans attendre la réponse entre chaque requête.
Ceci évite encore quelques latences en évitant un "ping-pong" permanent entre le client et le serveur, même si tout
ceci se passe sur la même connexion. Un client ne doit utiliser le pipelining que s'il est sûr que la connexion est bien
persistante. Aussi, le serveur doit envoyer ses réponses sur cette connexion dans le même ordre que les requêtes
lui sont arrivées, car il n'existe aucune numérotation ou trace des requêtes dans une même connexion.

- 41 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

XII - Les outils

HTTP est un protocole "human readable", il est donc possible d'agir dessus, et pourquoi pas d'écrire sa syntaxe à
la main.
Tous les navigateurs webs possèdent une solide couche HTTP, voyez celle de Firefox par exemple.
Bien sûr, tous les serveurs webs aussi, voyez celle d'Apache par exemple.
Mais en réalité, n'importe quel logiciel lié à un réseau TCP/IP peut communiquer via HTTP, sur le port 80, voyons
quelques possibilités

XII-A - Les langages Web : PHP

PHP est un langage de script Web. Je ne vais pas le présenter ;-). Voyons un peu comment on peut agir sur HTTP
via PHP.

Les fonctions suivantes jouent sur les en-têtes de la réponse du serveur, la liste n'est pas exhaustive :

• header() : permet de spécifier à la main un en-tête de réponse et éventuellement de changer le code de


réponse HTTP
• headers_sent() : indique si les en-têtes de la réponse ont déja été envoyés au client ou pas
• setcookie() : envoie un en-tête Set-Cookie dans la réponse, peut aussi être fait via header()
• session_start() : envoie des en-têtes pour la gestion de la session : cache, cookie, etc...
• headers_list() : récupère la liste des en-têtes à envoyer dans la réponse courante
• apache_response_headers() : récupère la liste des en-têtes à envoyer dans la réponse courante, plus précise
que headers_list(), mais nécessite de tourner sous module apache
• get_headers() : récupère les en-têtes de la réponse à une requête fournie

PHP dispose aussi d'extensions permettant de manipuler HTTP de manière très complète, ext/http est très
puissante.
Des frameworks proposent aussi de manipuler HTTP via des objets PHP, c'est le cas de Zend_Http par exemple.
Enfin, PHP pouvant ouvrir une socket réseau, il peut tout à fait (à plus bas niveau donc), écrire un code HTTP et
attendre la réponse de la socket.
Avec ces outils et la maitrise du protocole HTTP, il est possible de créer des programmes de toutes sortes : robots
indexeurs, serveurs webs (oui oui, on en trouve des "persos" en python, en C, en PHP... ), mais aussi des outils relatifs
à la sécurité, qui cherchent des failles dans les formulaires en sniffant la source HTML et en injectant des paramètres
dans les formulaires ou les requêtes GET. Je ne vais pas m'étendre, mais on peut aller beaucoup plus loin.
Il est clair et net que lorsqu'on maitrise HTTP, on ne regarde plus du tout le web de la même manière, et on s'aperçoit
du nombre Ô combien important de serveurs et de sites bourrés de failles de sécurité, en grande partie parce que
leurs administrateurs ou leurs développeurs n'ont aucune ou très peu de notions de HTTP. Vraiment étrange lorsqu'on
sait que tous les travaux sur HTTP sont en ligne, il existe des ouvrages très bons ainsi que des tutoriaux ;-)

XII-B - Telnet

La commande Unix Telnet est très pratique puisqu'elle permet d'écrire soit même à la main, octet par octet, des
instructions HTTP sur un serveur.
Rien de mieux pour tester son serveur, même si c'est souvent long d'écrire toutes les lignes. Telnet vous permet
d'écrire directement du code dans une socket connectée via TCP.

XII-C - Wget

Les puristes Linux peuvent passer leur chemin, je ne leur apprendrai rien ici :-D. Wget est une commande qui peut
aussi être utilisée pour se connecter à un serveur via HTTP.

- 42 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

XII-D - Curl

XII-E - Outils webs

Rex Swain's HTTP Viewer Askapache headers tool Web-sniffer HTTP Debugger Fiddler
Proxy HTTP Charles Proxy HTTP Nginx

Firefox propose tout un tas d'extensions permettant de "jouer" avec HTTP, les cookies, les données envoyées,
le referer, etc... AddNEditCookie LiveHTTPHeaders HeaderMonitor TamperData Refspoof
Firebug FireCookie HttpFox UseragentSwitcher

- 43 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

XIII - Au delà du Web avec HTTP

HTTP n'est pas limité au Web dans le sens "je consulte une page HTML de l'Internet". Aujourd'hui, les services Webs
utilisent HTTP pour transporter de l'information. En fait, vous avez vu dans cet article le potentiel de HTTP, et je pense
que vous vous êtes rendu compte que oui : il s'agit d'un protocole de la couche OSI "applicatif" : il peut transporter
à peu près toute sorte d'information.
Prenons SOAP par exemple. Ce protocole décrivant des services Web est en fait une surcouche de HTTP qui utilise
uniquement la méthode POST et des descriptions XML pour effectuer du RPC (appels de procédures distantes).

D'un point de vue HTTP, rien n'est mieux que REST. Les services webs dits "RESTFul" tirent vraiment partie de
HTTP : il ne sert à rien de réinventer la roue (réinventer un protocole), alors que HTTP est là.
Connaissez-vous des projets comme Apache CouchDB ? Non ? Regardez plutôt. Il s'agit de services REST
avec réponses JSON qui exploitent une fois de plus une grande partie des capacités de HTTP.
ATOM, celà vous dit-il quelque chose ? Non ? Oulala, courrez voir ce protocole de liaison de données entièrement
bâti sur HTTP, d'une beauté comparable à celle de REST ! On pourrait aussi citer la surcouche protocolaire WebDav,
et plus encore...

- 44 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/
HTTP : le protocole du Web passé en revue par Julien Pauli (Tutoriels, article et conférences PHP et developpement web) (Blog)

XIV - Références

LA page officielle de HTTP, qui retrace toute son histoire et ses évolutions : http://www.w3.org/Protocols/
Firefox networking performance (about:config) IBM Software information server HTTP Schéma de
décision HTTP dans le traitement d'une requête (très bien fait)

- 45 -
Copyright © 2009 - Julien PAULI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes,
documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
http://julien-pauli.developpez.com/tutoriels/web/http/

Vous aimerez peut-être aussi