IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
11.3. Fonctionnalités de HTTP

11.3. Fonctionnalités de HTTP

Il y a cinq fonctionnalités importantes de HTTP que nous devons supporter dans notre programme.

11.3.1. User-Agent

La chaîne d'identification User-Agent est simplement un moyen pour le client de déclarer au serveur qui il est lorsqu'il demande une page, un fil ou tout autre service Web par HTTP. Quand le client demande une ressource, il doit toujours annoncer qui il est, de la manière la plus spécifique possible. Cela permet à l'administrateur du serveur de contacter le développeur du client si les choses se passent mal.

Par défaut, Python envoi une chaîne User-Agent générique : Python-urllib/1.15. Dans la section suivante, nous verrons comment la changer pour quelque chose de plus spécifique.

11.3.2. Les redirections

Parfois, les ressources changent d'emplacement. Les sites Web sont réorganisés, les pages sont déplacées à une nouvelle adresse. Les services Web aussi peuvent être réorganisés. Un fil de syndication à l'adresse http://example.com/index.xml peut être déplacé vers http://example.com/xml/atom.xml. Un domaine complet peut être déplacé, si une organisation s'élargit et se réorganise. Par exemple, http://www.example.com/index.xml peut être redirigé vers http://server-farm-1.example.com/index.xml.

A chaque fois que nous demandons une ressource quelle qu'elle soit à un serveur HTTP, le serveur inclut un code de statut dans sa réponse. Le code de statut 200 signifie «tout est normal, voici la page demandée». Le code de statut 404 signifie «page non trouvée» (vous avez sans doute déjà rencontré des erreurs 404 en navigant sur le Web).

Le protocole HTTP a deux manières différentes de signaler qu'une ressources a été déplacée. Le code de statut 302 est une redirection temporaire, il signifie «attention, cette page a été déplacée ici temporairement» (il est suivit d'une adresse temporaire dans un en-tête Location:). Si nous recevons un code de statut 302, la spécification HTTP dit que nous devons utiliser la nouvelle adresse pour obtenir la ressource, mais que nous devons réessayer l'ancienne adresse la prochaine fois que nous voulons y accéder. Par contre, si nous recevons un code de statut 301 et une nouvelle adresse, nous devons dorénavant utiliser la nouvelle adresse.

urllib.urlopen «suit» automatiquement les redirections lorsqu'il reçoit le code de statut approprié du serveur, mais malheureusement, il ne nous le signale pas. Nous obtenons ainsi les données que nous voulions, mais nous ignorons que la bibliothèque a suivit une redirection «pour vous aider». Donc, nous risquons de continuer d'utiliser l'ancienne adresse et d'être à chaque fois redirigé sur la nouvelle. Cela fait deux aller-retours au lieu d'un seul, ce qui n'est pas très efficace. Nous verrons plus loin dans ce chapitre comment contourner cette difficulté pour pouvoir prendre en compte les redirections permanentes correctement.

11.3.3. Last-Modified/If-Modified-Since

Certaines données changent constamment. La page d'accueil de CNN.com est mise à jour au bout de quelques minutes. Par contre, la page d'accueil de Google.com ne change qu'au bout de plusieurs semaines. Les services Web ne sont pas différents, en général le serveur sait quand les données que nous demandons ont été modifiées pour la dernière fois et HTTP fournit un moyen pour le serveur d'inclure cette date de modification avec les données que nous demandons.

Si nous demandons ces mêmes données une deuxième fois (ou une troisième, une quatrième), nous pouvons dire au serveur la date de dernière modification que nous avons obtenu la dernière fois : nous envoyons un en-tête If-Modified-Since avec notre requête avec la date que nous avions obtenue. Si les données n'ont pas été modifiées depuis la dernière fois, le serveur renvoi un code de statut 304, qui signifie «ces données n'ont pas changé depuis la dernière fois». Qu'est-ce que cela apporte ? Quand le serveur renvoi un code 304, il ne renvoi pas les données. Nous ne recevons que le code de statut. Nous n'avons donc pas besoin de télécharger les mêmes données encore et encore si elles n'ont pas changé, le serveur considère que nous les avons en cache.

Tous les navigateurs récents implémentent la vérification de date de dernière modification. Si nous retournons voir une page qui n'a pas été modifiée de puis votre dernière visite, elle se charge très rapidement. Notre navigateur a mis le contenu de la page dans son cache local à la première visite et à la deuxième il a automatiquement envoyé la date de dernière modification qu'il avait obtenu la première fois. Le serveur a répondu simplement 304: Not Modified, donc notre navigateur sait qu'il doit recharger la page à partir de son cache. Les services Web peuvent suivre la même procédure.

La bibliothèque URL de Python n'implémente pas la vérification de date de dernière modification, mais comme nous pouvons ajouter les en-têtes que nous voulons à chaque requête et lire les en-têtes que nous voulons à chaque réponse, nous pouvons l'implémenter nous même.

11.3.4. ETag/If-None-Match

Les ETags sont une manière alternative d'accomplir la même chose que la vérification de date de dernière modification : ne pas télécharger des données qui n'ont pas été modifiées. Leur fonctionnement est le suivant : le serveur envoi un code de hachage des données (dans un en-tête ETag) avec les données que nous avons demandé. La manière dont ce code est généré est entièrement à la discrétion du serveur. La deuxième fois que nous demandons les données, nous incluons le code de hachage ETag dans un en-tête If-None-Match: et si les données n'ont pas été modifiées, le serveur nous renvoi un code de statut 304. Comme pour la vérification de date de dernière modification, le serveur n'envoi que le code 304, il n'envoi pas les données une nouvelle fois. En incluant le code de hachage ETag dans notre seconde requête, nous disons au serveur qu'il n'est pas nécessaire de renvoyer les mêmes données si elles correspondent à ce code de hachage, puisque nous avons encore les données de la dernière fois.

La bibliothèque URL de Python n'implémente pas les Etags, mais nous verrons plus loin comment les ajouter.

11.3.5. La compression

La dernière fonctionnalité important de HTTP est la compression gzip. Quand on parle de services Web HTTP, il s'agit presque tout le temps d'envoyer et de recevoir du XML. Le XML est du texte et c'est un format verbeux qui se compresse bien. Lorsque nous demandons une ressource par HTTP, nous pouvons demander au serveur, si il a des nouvelles données à nous envoyer, de les envoyer en format compressé. Il suffit d'inclure l'en-tête Accept-encoding: gzip dans notre requête et le serveur, si il implémente la compression, nous enverra des données compressées par gzip en les signalant par un en-tête Content-encoding: gzip.

La bibliothèque URL de Python n'implémente pas la compression gzip en tant que telle, mais nous pouvons ajouter les en-têtes que nous voulons à la requête. Python fournit un module gzip qui a des fonctions nous permettant de décompresser les données nous même.

Notez que notre petit script d'une ligne pour télécharger un fil de syndication n'implémentait aucune de ces fonctionnalités du protocole HTTP. Voyons comment améliorer cela.