Ci-dessous, les différences entre deux révisions de la page.
— | 210http:20_le_protocole [le 03/03/2009 à 19:48] (Version actuelle) – créée - modification externe 127.0.0.1 | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ====== Le protocole HTTP ====== | ||
+ | |||
+ | ===== Les versions du protocole ===== | ||
+ | |||
+ | Les versions les plus utilisées actuellement sont les versions 1.0 et 1.1, l' | ||
+ | |||
+ | La version 1.1 de HTML introduit quelques commandes supplémentaires, | ||
+ | |||
+ | ==== Remarque préliminaire : ==== | ||
+ | |||
+ | une page est en principe définie par un URI (Unified Ressource Identifier). On dit aussi URL (Unified Ressource Locator). Par exemple : [[http:// | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * ''/ | ||
+ | |||
+ | Pourtant, si nous indiquons comme URI http:// | ||
+ | |||
+ | ===== La démonstration ===== | ||
+ | |||
+ | Nous allons voir tout ceci à travers quelques manipulations très simples. | ||
+ | |||
+ | Pour réaliser cette démonstration, | ||
+ | |||
+ | Il contient une unique page html nommée index.html. C'est la page qui est servie par défaut (Les manipulatons datent de 2002, sur un apache 1.3 et une distribution d' | ||
+ | |||
+ | ==== 1° On fait comme tout le monde... ==== | ||
+ | |||
+ | Commençons par faire ce que tout le monde fait : Utiliser son navigateur favori pour visiter cette page. Voici l' | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | A titre indicatif, en voici le code HTML, tel qu'on peut l' | ||
+ | < | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | |||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | </ | ||
+ | |||
+ | Les puristes constateront que ce code n'est plus du tout conforme aux recommandations du [[http:// | ||
+ | |||
+ | ==== 2° On fait avec Telnet... ==== | ||
+ | |||
+ | Essayons d' | ||
+ | |||
+ | Nous sommes sur un protocole applicatif basé sur TCP et, dans ce cas là, il est généralement possible d' | ||
+ | |||
+ | === La commande GET === | ||
+ | |||
+ | Nous ouvrons une session telnet sur le serveur HTTP de linux.maison.mrs (Un serveur web écoute par convention sur le port 80). | ||
+ | |||
+ | telnet linux.maison.mrs 80 | ||
+ | | ||
+ | Trying 192.168.0.253... | ||
+ | Connected to linux.maison.mrs (192.168.0.253) | ||
+ | Escape character is ' | ||
+ | |||
+ | La session est ouverte. Utilisons maintenant la commande GET... | ||
+ | |||
+ | GET / HTTP/1.0 | ||
+ | |||
+ | Nous la faisons en protocole 1.0, c'est un peu plus simple. Deux « return » pour valider... Et voici qu' | ||
+ | |||
+ | HTTP/1.1 200 OK | ||
+ | Date: Wed, 08 May 2002 14:26:57 GMT | ||
+ | Server: Apache-AdvancedExtranetServer/ | ||
+ | (Mandrake Linux/4mdk) auth_ldap/ | ||
+ | Last-Modified: | ||
+ | ETag: " | ||
+ | Accept-Ranges: | ||
+ | Content-Length: | ||
+ | Connection: close | ||
+ | Content-Type: | ||
+ | |||
+ | Le serveur sait faire du HTTP 1.1. C'est un Apache version 1.3.23. Il annonce également ce qu'il sait faire : | ||
+ | * Authentification par annuaire LDAP | ||
+ | * Secure Socket Layer en OpenSSL version 0.9.6c | ||
+ | * Interprétation de code PHP version 4.1.2 | ||
+ | |||
+ | Il indique également La date GMT de dernière modification du document demandé, qu'il mettra fin à la connexion TCP à la fin de l' | ||
+ | |||
+ | Et voici le document proprement dit : | ||
+ | < | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | |||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | </ | ||
+ | |||
+ | Le message '' | ||
+ | |||
+ | Bien ! Mais l' | ||
+ | |||
+ | < | ||
+ | telnet linux.maison.mrs 80 | ||
+ | |||
+ | Trying 192.168.0.253... | ||
+ | Connected to linux.maison.mrs (192.168.0.253). | ||
+ | Escape character is ' | ||
+ | |||
+ | GET / | ||
+ | Trying 192.168.0.253... | ||
+ | |||
+ | Connected to linux.maison.mrs (192.168.0.253). | ||
+ | Escape character is ' | ||
+ | |||
+ | HTTP/1.1 200 OK | ||
+ | Date: Wed, 08 May 2002 14:44:17 GMT | ||
+ | Server: Apache-AdvancedExtranetServer/ | ||
+ | (Mandrake Linux/4mdk) auth_ldap/ | ||
+ | Last-Modified: | ||
+ | ETag: « cf98a-a20-3cb94bfc » | ||
+ | Accept-Ranges: | ||
+ | Content-Length: | ||
+ | Connection: close | ||
+ | |||
+ | <span class=" | ||
+ | GIF89aasæ???? | ||
+ | ('' | ||
+ | ©¶ÙÙëà³LhhÓ? | ||
+ | ... | ||
+ | Connection closed by foreign host. | ||
+ | </ | ||
+ | |||
+ | Là, il ne fallait tout de même pas s' | ||
+ | |||
+ | ==== 3° On espionne avec le sniffeur... ==== | ||
+ | |||
+ | === Comment travaille le navigateur ? === | ||
+ | |||
+ | Il a fait exactement la même chose que nous : | ||
+ | |||
+ | * Il appelle la page d' | ||
+ | * Une fois la page reçue, il va chercher dedans tous les URI, ici celui de l' | ||
+ | * Il affiche alors la page, dans son intégralité. | ||
+ | |||
+ | === Première observation de la conversation === | ||
+ | |||
+ | Nous appelons la page avec Internet Explorer et le sniffeur va enregistrer ce qu'il se passe. Les trames surlignées sont celles qui sont propres à HTTP. Mais n' | ||
+ | < | ||
+ | No. Time | ||
+ | 1 0.000000 192.168.0.10 | ||
+ | 2 0.000163 192.168.0.253 192.168.0.10 | ||
+ | 3 0.000565 192.168.0.10 | ||
+ | <span class=" | ||
+ | 5 0.001487 192.168.0.253 192.168.0.10 | ||
+ | <span class=" | ||
+ | 7 0.098435 192.168.0.10 | ||
+ | 8 0.098593 192.168.0.253 192.168.0.10 | ||
+ | <span class=" | ||
+ | 10 0.099724 192.168.0.253 192.168.0.10 | ||
+ | 11 0.102794 192.168.0.10 | ||
+ | <span class=" | ||
+ | 13 0.280331 192.168.0.10 | ||
+ | </ | ||
+ | * La trame 4 représente la première requête du client | ||
+ | * La trame 6 renvoie le document demandé, c'est à dire la page d' | ||
+ | * La trame 7 indique une requête supplémentaire pour l' | ||
+ | * Les trames 9, 10 et 12 représentent l' | ||
+ | |||
+ | === La première requête HTTP === | ||
+ | |||
+ | Pour cette première analyse, je laisse volontairement la totalité de la trame, afin de bien montrer que HTTP est un protocole « application », qui s' | ||
+ | < | ||
+ | Frame 4 (380 on wire, 380 captured) | ||
+ | Arrival Time: Apr 13, 2002 16: | ||
+ | Time delta from previous packet: 0.000861000 seconds | ||
+ | Time relative to first packet: 0.001408000 seconds | ||
+ | Frame Number: 4 | ||
+ | Packet Length: 380 bytes | ||
+ | Capture Length: 380 bytes | ||
+ | |||
+ | Ethernet II | ||
+ | Destination: | ||
+ | Source: 00: | ||
+ | Type: IP (0x0800) | ||
+ | |||
+ | |||
+ | Internet Protocol, Src Addr: 192.168.0.10, | ||
+ | Version: 4 | ||
+ | Header length: 20 bytes | ||
+ | Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00) | ||
+ | 0000 00.. = Differentiated Services Codepoint: Default (0x00) | ||
+ | .... ..0. = ECN-Capable Transport (ECT): 0 | ||
+ | .... ...0 = ECN-CE: 0 | ||
+ | Total Length: 366 | ||
+ | Identification: | ||
+ | Flags: 0x04 | ||
+ | .1.. = Don't fragment: Set | ||
+ | ..0. = More fragments: Not set | ||
+ | Fragment offset: 0 | ||
+ | Time to live: 128 | ||
+ | Protocol: TCP (0x06) | ||
+ | Header checksum: 0xad95 (correct) | ||
+ | Source: 192.168.0.10 (192.168.0.10) | ||
+ | Destination: | ||
+ | |||
+ | Transmission Control Protocol, Src Port: 2752, Dst Port: 80 | ||
+ | Source port: 2752 (2752) | ||
+ | Destination port: 80 (80) | ||
+ | Sequence number: 1135843004 | ||
+ | Next sequence number: 1135843330 | ||
+ | Acknowledgement number: 2485285689 | ||
+ | Header length: 20 bytes | ||
+ | Flags: 0x0018 (PSH, ACK) | ||
+ | 0... .... = Congestion Window Reduced (CWR): Not set | ||
+ | .0.. .... = ECN-Echo: Not set | ||
+ | ..0. .... = Urgent: Not set | ||
+ | ...1 .... = Acknowledgment: | ||
+ | .... 1... = Push: Set | ||
+ | .... .0.. = Reset: Not set | ||
+ | .... ..0. = Syn: Not set | ||
+ | .... ...0 = Fin: Not set | ||
+ | Window size: 17520 | ||
+ | Checksum: 0x6ec7 (correct) | ||
+ | |||
+ | Hypertext Transfer Protocol | ||
+ | GET / HTTP/ | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | <span class=" | ||
+ | \r\n | ||
+ | </ | ||
+ | Si IE se permet d' | ||
+ | |||
+ | === La page d' | ||
+ | |||
+ | < | ||
+ | Frame 6 (710 on wire, 710 captured) | ||
+ | ... | ||
+ | Hypertext Transfer Protocol | ||
+ | HTTP/1.1 200 OK\r\n | ||
+ | Date: Sun, 14 Apr 2002 09:30:12 GMT\r\n | ||
+ | Server: Apache-AdvancedExtranetServer/ | ||
+ | auth_ldap/ | ||
+ | mod_ssl/ | ||
+ | OpenSSL/ | ||
+ | PHP/ | ||
+ | Last-Modified: | ||
+ | ETag: « 57d44-116-3cb94bfc »\r\n | ||
+ | Accept-Ranges: | ||
+ | Content-Length: | ||
+ | Keep-Alive: timeout=15, max=100\r\n | ||
+ | Connection: Keep-Alive\r\n | ||
+ | ** Content-Type: | ||
+ | ** \r\n | ||
+ | |||
+ | Data (278 bytes) | ||
+ | 0000 3c 68 74 6d 6c 3e 0d 0a 3c 68 65 61 64 3e 0d 0a & | ||
+ | 0010 3c 74 69 74 6c 65 3e 55 6e 74 69 74 6c 65 64 20 & | ||
+ | 0020 44 6f 63 75 6d 65 6e 74 3c 2f 74 69 74 6c 65 3e | ||
+ | 0030 0d 0a 3c 6d 65 74 61 20 68 74 74 70 2d 65 71 75 | ||
+ | 0040 69 76 3d 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 | ||
+ | 0050 22 20 63 6f 6e 74 65 6e 74 3d 22 74 65 78 74 2f " | ||
+ | 0060 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 3d 69 73 html; charset=is | ||
+ | 0070 6f 2d 38 38 35 39 2d 31 22 3e 0d 0a 3c 2f 68 65 | ||
+ | 0080 61 64 3e 0d 0a 0d 0a 3c 62 6f 64 79 20 62 67 63 | ||
+ | 0090 6f 6c 6f 72 3d 22 23 46 46 46 46 46 46 22 20 74 | ||
+ | 00a0 65 78 74 3d 22 23 30 30 30 30 30 30 22 3e 0d 0a | ||
+ | 00b0 3c 70 3e 48 65 6c 6c 6f 20 77 6f 72 6c 64 2e 0d & | ||
+ | 00c0 0a 3c 2f 70 3e 0d 0a 3c 70 3e 3c 69 6d 67 20 73 | ||
+ | 00d0 72 63 3d 22 69 6d 61 67 65 73 2f 74 75 78 2e 67 < | ||
+ | 00e0 69 66 22 20 77 69 64 74 68 3d 22 39 37 22 20 68 < | ||
+ | 00f0 65 69 67 68 74 3d 22 31 31 35 22 3e 0d 0a 3c 2f < | ||
+ | 0100 70 3e 0d 0a 3c 2f 62 6f 64 79 3e 0d 0a 3c 2f 68 | ||
+ | 0110 74 6d 6c 3e 0d 0a | ||
+ | </ | ||
+ | C'est au navigateur de se débrouiller pour aller chercher les données de cette image, à partir des références fournies. Tous ceux qui pratiquent le HTML le savent bien... | ||
+ | |||
+ | Ceci justifie la présence de la requête de la trame 7 : | ||
+ | |||
+ | < | ||
+ | Frame 7 (298 on wire, 298 captured) | ||
+ | ... | ||
+ | Hypertext Transfer Protocol | ||
+ | GET / | ||
+ | Accept: */*\r\n | ||
+ | Referer: http:// | ||
+ | < | ||
+ | < | ||
+ | Accept-Language: | ||
+ | Accept-Encoding: | ||
+ | User-Agent: Mozilla/4.0 (compatible; | ||
+ | Host: linux.maison.mrs\r\n | ||
+ | Connection: Keep-Alive\r\n | ||
+ | \r\n | ||
+ | </ | ||
+ | |||
+ | Le serveur envoie les données à partir de la trame 9 : | ||
+ | |||
+ | < | ||
+ | Frame 9 (1514 on wire, 1514 captured) | ||
+ | .... | ||
+ | Hypertext Transfer Protocol | ||
+ | HTTP/1.1 200 OK\r\n | ||
+ | Date: Sun, 14 Apr 2002 09:30:12 GMT\r\n | ||
+ | Server: Apache-AdvancedExtranetServer/ | ||
+ | auth_ldap/ | ||
+ | mod_ssl/ | ||
+ | OpenSSL/ | ||
+ | PHP/ | ||
+ | Last-Modified: | ||
+ | ETag: « cf98a-a20-3cb94bfc »\r\n | ||
+ | Accept-Ranges: | ||
+ | Content-Length: | ||
+ | Keep-Alive: timeout=15, max=99\r\n | ||
+ | Connection: Keep-Alive\r\n | ||
+ | <span class=" | ||
+ | \r\n | ||
+ | Data (1082 bytes) | ||
+ | |||
+ | 0000 47 49 46 38 39 61 61 00 73 00 e6 00 00 04 04 05 < | ||
+ | 0010 a4 85 2f 49 48 47 a3 48 49 ed c8 10 c5 a4 32 9b | ||
+ | 0020 69 07 ba 85 0e be 67 70 a9 3a 3c 85 66 1d d7 a5 | ||
+ | 0030 15 c4 48 4c a7 76 0c 8b 88 8d e8 e8 fc b8 88 94 | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | === Conclusions === | ||
+ | |||
+ | Nous avons vu quelques choses intéressantes : | ||
+ | |||
+ | * Le navigateur, en gros, fait ce que nous avons fait avec Telnet, à quelques détails près : | ||
+ | * Il envoie un certain nombre d' | ||
+ | * Il se débrouille tout seul pour appeler tous les documents nécessaires à l' | ||
+ | |||
+ | ===== Le coup du cache... ===== | ||
+ | |||
+ | Puisque nous y sommes, profitons en pour observer un comportement intéressant du navigateur : La mise en cache des pages consultées. | ||
+ | |||
+ | L' | ||
+ | |||
+ | < | ||
+ | No. Time | ||
+ | 1 0.000000 192.168.0.10 | ||
+ | 2 0.000144 192.168.0.253 192.168.0.10 | ||
+ | 3 0.000540 192.168.0.10 | ||
+ | <span class=" | ||
+ | 5 0.001461 192.168.0.253 192.168.0.10 | ||
+ | <span class=" | ||
+ | 7 0.200392 192.168.0.10 | ||
+ | </ | ||
+ | La réponse n'est pas la même que dans le cas précédent. Voyons ceci de plus près... | ||
+ | |||
+ | === La requête === | ||
+ | < | ||
+ | Frame 4 (336 on wire, 336 captured) | ||
+ | ... | ||
+ | Hypertext Transfer Protocol | ||
+ | GET / HTTP/ | ||
+ | Accept: */*\r\n | ||
+ | Accept-Language: | ||
+ | Accept-Encoding: | ||
+ | <span class=" | ||
+ | |||
+ | If-None-Match: | ||
+ | User-Agent: Mozilla/4.0 (compatible; | ||
+ | Host: linux.maison.mrs\r\n | ||
+ | Connection: Keep-Alive\r\n | ||
+ | \r\n | ||
+ | </ | ||
+ | Internet Exlorer demande au serveur la page, si elle a été modifiée depuis la date de son précédent chargement, tout simplement parce qu'il a conservé en cache cette page que nous avons déjà demandée il n'y a pas si longtemps. | ||
+ | |||
+ | === La réponse === | ||
+ | < | ||
+ | Frame 6 (327 on wire, 327 captured) | ||
+ | ... | ||
+ | Hypertext Transfer Protocol | ||
+ | <span class=" | ||
+ | Date: Sat, 13 Apr 2002 13:53:52 GMT\r\n | ||
+ | Server: Apache-AdvancedExtranetServer/ | ||
+ | auth_ldap/ | ||
+ | Connection: Keep-Alive\r\n | ||
+ | Keep-Alive: timeout=15, max=100\r\n | ||
+ | ETag: " | ||
+ | \r\n | ||
+ | </ | ||
+ | Le serveur s'est contenté de répondre que la page n'a pas été modifiée... | ||
+ | |||
+ | Le navigateur va donc réafficher la page qu'il a conservée en cache. Cette méthode de travail présente deux particularités: | ||
+ | |||
+ | * Le temps d' | ||
+ | * L' | ||
+ | |||
+ | <note warning> Méfiez vous des effets de bord du cache local ! | ||
+ | Il existe de nombreux cas où le contrôle sur la modification n'est pas efficace. Votre navigateur affichera alors une version obsolète de la page. Ceci est surtout gênant pour les développeurs de sites. | ||
+ | </ | ||
+ | |||
+ | Un procédé analogue est également employé par les serveurs proxy. | ||
+ | |||
+ | ===== Toutes les commandes de HTTP 1.0 ===== | ||
+ | |||
+ | La compréhension de la navigation ne nécessite pas la connaissance de toutes les commandes, loin de là. Aussi, nous ne les verrons pas en détail. | ||
+ | |||
+ | * **La commande HEAD.** | ||
+ | |||
+ | * **La commande GET.** | ||
+ | |||
+ | |||
+ | * **La commande POST.** C'est la commande qui permet d' | ||
+ | |||
+ | ===== Et HTTP 1.1 ? ===== | ||
+ | |||
+ | Il propose quelques commandes supplémentaires, | ||
+ | |||
+ | * OPTIONS qui permet d' | ||
+ | * TRACE qui est en quelque sorte une commande de débogage | ||
+ | * DELETE qui permet de détruire un fichier sur le serveur (généralement désactivée, | ||
+ | * PUT Qui permet d' | ||
+ | |||
+ | Ces deux dernières commandes sont introduites pour permettre une mise à jour des sites distants via HTTP. | ||