Client HTTP en Perl

Le but de ce TP est de programmer client qui se connecte à un serveur WEB par le protocole HTTP.

On utilisera le langage Perl pour ses capacités de traitement de textes (expressions rationnelles, etc.).

Le protocole HTTP

Le protocole HTTP est utilisé pour transférer des pages WEB entre un serveur (distant) et un client (votre programme). On utilisera la version 1.1 du protocole (c'est la dernière en date). La description présentée ici est très partielle mais devrait suffire pour le TP. Voir la partie documentations de référence pour tout complément d'information.

Requête HTTP

Pour demander une page http://www.di.ens.fr/~mine/enseignement/syst2006/index.html, le client doit ouvrir une connection TCP sur le port 80 vers www.di.ens.fr et envoyer les lignes de texte suivantes:

GET /~mine/enseignement/syst2006/index.html HTTP/1.1
Host: www.di.ens.fr
User-Agent: Mon Super Script v0.01
Connection: close
ligne vide

Ces lignes ont la signification suivante:

En réalité, la ligne de requête peut être suivie de nombreuses autres lignes d'en-tête, toujours sous la forme XXX: YYY. Notez que le nom de l'en-tête XXX est insensible à la casse. Seule l'en-tête Host: est obligatoire. (Voir la partie 14 de la RFC 2616 pour la liste des en-têtes.)

Note importante: dans tous les protocoles textes d'Internet, les fins de ligne sont matérialisées par la séquence \r\n.

Réponse positive

Une réponse du serveur à notre requête ressemblerait à ceci:

HTTP/1.1 200 OK
Content-type: text/html
ligne vide
<html><head>
...
</body></html>

Cette réponse consiste en trois parties:

La fin de la page WEB est indiquée par la fermeture de la connection de la part du serveur.

Réponse d'erreur

Si la page WEB n'existe pas, la réponse ressemblera à:

HTTP/1.1 404 Not Found
Content-type: text/html
ligne vide
<html><head><title>Not Found</title></head><body>
Sorry, the object you requested was not found.
</body><html>

Cette fois, le code est 404 qui signifie: page non trouvée. Notez que le serveur nous envoie tout de même une page WEB qu'un navigateur pourra choisir d'afficher. Ceci permet à l'administrateur du site de configurer la manière dont le message d'erreur est présenté à l'utilisateur. (La liste complète des codes de statu se trouve dans la partie 10 de la RFC 2616.)

Autres réponses intéressantes

Dans certains cas, le serveur indique que la page a été déplacée temporairement ou définitivement (codes 301, 302, 303, 305 et 307) à une autre adresse. Celle-ci est indiquée par une en-tête de la forme Location: nouvelle adresse.

Exercices

Dialogues interactifs

Avant de se lancer dans la programmation d'un script Perl, on va se familiariser avec le protocole HTTP grâce au logiciel interactif telnet. Celui-ci est normalement prévu pour se connecter à un serveur en utilisant le protocole TELNET, mais il est facile de le détourner en spécifiant le port 80 au lieu du port 23 pris par défaut. Une alternative est le programme netcat (parfois appelé nc).

1) Utilisez la commande telnet www.ens.fr 80 pour dialoguer avec le serveur WEB de l'ENS et télécharger quelques pages. Essayez la même chose avec Google.com (www.google.com).

J'ai lancé un serveur WEB Apache sur le port 8080 de brick où vous pouvez vous connecter (depuis l'ENS uniquement: 129.199.x.x). J'ai en particulier placé les fichiers de logs ~mine/fedora/logs/error_log et ~mine/fedora/logs/access_log en lecture autorisée ce qui vous permet de savoir comment Apache a interprété vos requêtes.

Enfin, vous pouvez prendre le rôle du serveur WEB et interagir avec un client existant. Utilisez la commande netcat -l -p 8080 dans un terminal et demandez l'adresse http://localhost:8080/truc/machin dans votre navigateur préféré.

Récupérer une page WEB en Perl

2) Faites un script Perl httpget qui télécharge une page WEB (dont l'adresse est donnée en argument) et affiche son contenu (hors en-têtes) à l'écran. L'adresse de la page web est donnée sous la forme d'une URL protocole://serveur:port/cheminprotocole vaut toujours http, serveur est une adresse texte ou numérique, la partie :port est facultative (la valeur par défaut 80 sera utilisée si le port est omis) et chemin indique le chemin de la page sur le serveur (le séparateur de répertoire est /). Votre script devra donc commencer par décomposer l'URL afin de déterminer le serveur, le port et le chemin, avant de contacter le serveur. Prenez soin à rapporter à l'utilisateur les erreurs rencontrées (serveur inexistant, connection refusée, page non trouvée, etc.).

Les fonctions Perl suivantes seront utiles (voir le manuel de référence Perl sur les fonctions et les modules standards):

Correction) httpget.pl.

Vérificateur de liens

Une page WEB peut contenir des liens vers d'autres pages grâce à la construction href="lien" (trouvée, par exemple, dans les balises <a>) ou src="lien" (balises <img>). Un tel lien peut prendre une des formes suivantes:

On note de plus que . et .. ont la même signification que dans les chemins Unix.

Enfin, un lien peut contenir un suffixe #ancre indiquant une position particulière dans la page référencée (ce suffixe, utile uniquement pour le navigateur, ne doit donc pas être inclus dans la requête au serveur).

3) Écrivez une fonction Perl urlcat qui prend en argument l'URL complète d'une page WEB ainsi qu'un lien et les 'concatène' pour retourner l'URL complète de la page liée. Par exemple:

Essayez de rendre l'URL la plus canonique possible (e.g., supprimez les morceaux de chemins inutiles de la forme /toto/../ ou /./).

Correction) urlcat.pl.

4) Faites un script Perl qui, en partant d'une URL donnée en argument, suit tous les liens de la page, récursivement, et donne la liste des pages (ou images ou autres) liées mais introuvables. On prendra particulièrement soin à:

Correction) followlink.pl.

Bibliothèques Perl prédéfinies

Normalement, pour réaliser une application WEB, on ne programme pas tout à la main comme nous venons de le faire. On utilise plutôt une des nombreuses bibliothèques Perl prédéfinies. Elles utilisent souvent le système d'objets de Perl. Citons, entre autres:

Il n'est toutefois pas mauvais de tout reprogrammer une fois dans sa vie afin de bien comprendre comment tout cela fonctionne!

Documentations de référence

Par soucis de complétion, voici des pointeurs sur les documentations officielles qui décrivent tous les aspects de HTTP et du HTML.




Antoine Miné