Accueil > Master 1 > Applications Web > TP1 Applications web M1 Miage 2011-2012 : étude du protocole HTTP

TP1 Applications web M1 Miage 2011-2012 : étude du protocole HTTP

De $1

Introduction

Ce TP a pour but de vous faire comprendre la nature du dialogue entre un navigateur et un serveur web. Le langage d'échange est le protocole HTTP. Il est très simple d'écrire un serveur web minimaliste, vous allez vous en rendre compte en simulant ce qu'envoie un navigateur web à un serveur à l'aide de divers outils tels que telnet ou netcat (commande "nc" de unix).

Il s'agit d'un TP à rendre, en binome !

Attention : les réponses à ce TP + le serveur HTTP sont à rendre pour la semaine suivante, ce sera noté. Modalités de rendu : pendant la prochaine séance vous rendrez :

  • Une archive portant le nom TD1_HTTP_nom1_nom2.zip ou .rar,
  • Dedans : un fichier texte ou doc contenant les réponses à toutes les questions,
  • Un projet netbeans ou eclipse contenant les sources du serveur HTTP que vous devez développer.
  • Un fichier Readme expliquant ce que vous avez fait dans ce serveur,
  • Le code doit être documenté !
  • L'archive contiendra aussi les pages html de test que vous aurez utilisées.

Lors de la prochaine séance de TP, vous ferez une démonstration à l'enseignant de TP de votre serveur et vous lui remettrez (il aura une clé USB) l'archive de votre projet.

Outils nécessaires à ce TP

Les commandes nc, telnet, ssh, etc, cygwin pour windows

Si vous êtes sous Linux ou sous Mac, vous n'avez théoriquement besoin de rien, toutes les commandes que nous allons utiliser sont disponibles.

Si vous êtes sous windows, vous commencerez par installer le package Cygwin, qui pertmet d'installer sur une machine Windows un shell unix ainsi qu'une grande partie des commandes disponibles sous ce système. Cygwin est non seulement une formidable boîte à outils mais il vous permettra également de vous faire la main avec les commandes Unix que vous n'avez généralement pas l'habitude d'utiliser et qui sont pourtant beaucoup plus puissantes que ce que propose l'ancêtre DOS. Ajoutons que la maîtrise des commandes Unix fait partie des prérequis pour certains stages et embauches (parlez-en aux M2 qui sont partis en stage chez Google à New-York cette année, ou aux stagiaires IBM/SAP).

Installation de cygwin sous windows :

  1. Aller sur cygwin.com, localisez le lien vers setup.exe (pour les plus fainéants : http://cygwin.com/setup.exe),
  2. Dans les packages proposés, il faut impérativement sélectionner : inetutils, netcat, openssh, wget (cherchez-les et cliquer sur "skip" pour qu'ils soient installés,
  3. Terminez l'installation.
  4. Ouvrez une fenêtre cygwin (vous devriez avoir l'icône sur le bureau), et vérifiez que les commandes telnet, netcat, ssh, wget sont bien installées.

L'extension firefox FireBug

  • Pour firefox, récupérer et installer cette extension depuis le site http://getfirebug.com/
  • Pour vérifier que vous avez bien installé cette extension, appuyez sur F12.

La console de debug de Chrome

  • Normalement elle est pré-installée : ctrl-shift-i sous Chrome (windows) ou ctrl-shift-j (Mac)

Le site web http://web-sniffer.net

  • A vous de voir quand il pourra vous être utile...

Jouons au client HTTP avec la commande telnet

Vous allez envoyer des requetes entièrement écrites à la main au serveur, en d'autres termes vous allez simuler un client HTTP. Pendant cette séance vos références principales seront les RFCs du protocole HTTP:

Pour réaliser cette première étape, vous aurez besoin d'un terminal (xterm, gnome-terminal ou konsole sous Linux, cygwin sous windows). Lancez le terminal de votre choix et au prompt taper la commande :

telnet www.unice.fr 80

Le serveur vous répondra :

# telnet www.unice.fr 80
Trying 134.59.204.1...
Connected to www.unice.fr.
Escape character is '^]'.

Vous pouvez alors commencer à envoyer des requêtes au serveur, par exemple :

GET / HTTP/1.0
Accept: text/html

 Terminez en tapant deux fois sur la touche Entrée (c'est ainsi qu'on termine une requête HTTP).

REMARQUE : si vous êtes sous cygwin et que vous ne voyez pas le haut de la réponse, vous pouvez soit augmenter la taille de l'historique du shell cygwin (cf google), soit taper la commande :

telnet www.unice.fr 80 > log.txt

Puis copier/coller ou taper la requête, et terminer par deux fois "entrée". Vous pourrez consulter la réponse avec la commande :

less log.txt

Le serveur vous va vous retourner une réponse et se déconnecter. Pour envoyer d'autres commandes, vous devez vous reconnecter avec telnet. Le protocole HTTP est par défaut un protocole "non connecté", je te parle, tu réponds, fin de transmission !

Question 1 Quelles informations tirez-vous de la première réponse du serveur?

Question 2 Essayez la requête suivante sur unice.fr (par telnet sur le port 80) :

GET / HTTP/1.0
Accept: text/html

Hmmm la réponse est bizarre non ?

On veut afficher comme réponse telnet le contenu HTML de la home page du portail de l'université ! Trouvez une requête HTTP qui permet d'avoir ce qu'on veut en vous aidant:

Question 3 Quelles sont les caractéristiques du serveur web de l'université ?

Question 4 Est-ce que le navigateur web fait le même travail que vous venez de faire lorsqu'il interroge www.unice.fr ? (pensez à utiliser FireBug ou la console debug de Chrome)

Question 5 Décrire le comportement attendu d'un navigateur lors de l'appel HTTP GET suivant sur www.unice.fr (par telnet sur le port 80):

GET /formations HTTP/1.1
Host: unice.fr
Accept: text/html

Question 6 Décrire le comportement attendu d'un navigateur lors de l'appel HTTP GET suivant sur unice.fr (par telnet sur le port 80):

GET /formations HTTP/1.1
Host: unice.fr
Accept: text/html

 

Jouons au serveur HTTP maintenant avec la commande nc

On va maintenant changer de rôle et jouer au serveur HTTP, pour cela on va utiliser la commande nc (nc pour netcat: un cat sur le réseau. Pour plus d'informations sur cette commande, sous Linux, taper "man netcat", ou la version en ligne : http://www.manpagez.com/man/1/nc/) :

usage: nc [-46DdhklnrStUuvzC] [-i interval] [-p source_port]
          [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_version]
          [-x proxy_address[:port]] [hostname] [port[s]]

Nc vous permet de simuler un serveur en utilisant l'option -l, par exemple pour lancer un serveur qui écoutera sur le port 12345, vous pouvez utiliser la commande suivante:

nc -l localhost 12345 (sous linux) ou
nc -l -p 12345 localhost (sous windows/cygwin)

... et pour vous connectez à ce serveur vous pouvez utiliser (dans une autre fenêtre) la commande:

telnet localhost 12345

Maintenant que vos deux fenêtres sont ouvertes, dans la fenêtre telnet, tapez des trucs et terminez par Entrée. Que voyez-vous dans la fenêtre "serveur", celle où la commande nc a été utilisée ?

Bon, si tout va bien vous devriez voir l'echo de ce que vous avez envoyé. Telnet est un "client" qui parle à nc qui est un "serveur".

Voyons maintenant ce qui se passe lorsque le client est un navigateur web !

Question 7 : Arrêtez le serveur avec ctrl-c (cygwin) ou ctrl-d (unix), puis relancez-le, et connectez-vous au serveur en utilisant le navigateur de votre choix, quelles sont les informations que votre navigateur envoie aux serveurs web sur lesquels vous vous connectez ?

Question 8 : Répondez à la requête du navigateur de sorte à afficher dans la page du navigateur "bonjour". Vous pouvez répondre comme un sauvage en tapant <html>Bonjour</html> et terminez par ctrl-c (cygwin) ou ctrl-d (unix). Ce type de réponse n'est pas vraiment correcte, même si les navigateurs acceptent des réponses mal formées.

Relisez le support de cours ou regardez un exemple de réponse dans les précédentes questions de ce tp pour trouver des exemples de réponses HTTP "bien formées" et essayez de répondre "à la main" correctement. N'oubliez pas de commencer la réponse en précisant le protocole, le code de status etc, puis on entre l'en-tête de réponse (qui peut être vide), puis on saute une ligne (obligatoire) puis on tape la réponse, puis on termine par ctrl-d (unix) ou ctrl-c (cygwin).

Question 9 : Positionnez un Cookie sur le client dans votre réponse suivante (c.f., http://en.wikipedia.org/wiki/HTTP_cookie#Implementation). Vous vérifierez avec firefox par exemple, que le cookie a bien été positionné (menu outils/options/vie privée/supprimer des cookies spécifiques). Vous pourrez faire un copier/coller d'un exemple de réponse avec cookie que vous pouvez espionner à l'aide de l'extension firebug pour firefox (prendre sur getfirebug.org et touche F12) ou de la console de développement de Chrome (ctrl-shift-i).

Question 10 : Envoyez des erreurs avec différents codes de status au client (http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1)...

Clients et Serveurs HTTP en Java

On vous donne une archive incomplète d'un mini serveur HTTP écrit en Java. Il manque peu de choses pour en faire un "vrai" serveur HTTP complet, mais ne vous inquiétez pas, c'est ce qu'on vous demande de faire et la semaine prochaine à n'en pas douter vous nous rendrez un serveur complet. L'archive contient un serveur qui accepte plusieurs connexions/requêtes en parallèle car il est multi-thread.

Les fichiers Client.java, Connection.java et Server.java, qui vous sont fournis implémentent un client et un serveur HTTP simples. Récupérez l'archive et créez un projet netbeans ou eclipse (de type "application java") dans lequel vous allez ajouter ces sources.

Question 11 Etudiez les sources. Compilez et testez ces programmes. Une fois le serveur lancé, vous lancerez le client java mais aussi un navigateur web sur l'adresse localhost:8080, par défaut le body de la réponse du serveur est l'echo de la requête reçue. Si vous voulez-voir la réponse complète, ce n'est possible qu'avec le client java, le navigateur web n'affichant dans sa page que le body de la réponse.

Question 12 Ajoutez une fonctionnalité permettant de positionner des Cookies. Vous vérifierez avec firefox par exemple, que le cookie a bien été positionné (menu outils/options/vie privée/supprimer des cookies spécifiques)

Question 13 Ajoutez une fonctionnalité permettant de renvoyer des codes d'erreurs.

Question 14 Ajoutez une fonctionnalité qui fait que le serveur ne répond qu'à des requêtes de votre navigateur préféré.

Question 15 : Modifiez le code du serveur pour qu'il puisse renvoyer des pages HTML. Par exemple si on tape dans le navigateur "http://localhost:8080/toto.html" et que la page toto.html est à la racine du projet eclipse ou netbeans, le serveur doit renvoyer le bon en-tête et le contenu HTML de la page toto.html dans le body de la réponse, afin que le navigateur web puisse l'afficher correctement.

Question 16 (pour les meilleurs) : gestion des types mime, des URLs relatifs.

Il s'agit maintenant de faire "un vrai serveur web", capable de gérer une page HTML qui inclut des CSS, des images, du javascript, des vidéos, qui contient un lien vers un mp3 local que vous voudrez streamer, etc. Pour cela, il faudra :

  • Gérer les fichiers dans des sous-répertoires, soit en d'autres termes, gérer les URLs relatifs. Ce n'est pas compliqué, il faudra pouvoir répondre à une requête de type GET /toto.html mais aussi, si toto.html contient une images avec SRC=images/toto.jpg être capable de répondre à une requête GET /images/toto.jpg HTTP/1.0
  • Gérer une page d'accueil par défaut localhost:8080 ou localhost:8080/ devra afficher localhost:8080/index.html,
  • Gérer les types mime. En fonction du suffixe du fichier à servir, il faudra renvoyer le bon content-type et aussi servir différemment une resource texte et une resource binaire comme une image, une vidéo ou un fichier audio.
  • On donne ce fichier mime.types qui pourra vous aider : mime.types

Ici un exemple de méthode qui lit un fichier binaire (on pourra utiliser pour images, audio, vidéo). Le premier paramètre est le descripteur du fichier à envoyer et le second le flux de sortie. On pourrait améliorer cette fonction en renvoyant la taille du fichier (pourrait servir au champs content-length de la réponse HTTP.

void sendBinaryFileStream(File f,PrintStream out) {
    FileInputStream fis;
        try {
            fis = new FileInputStream(f);
            BufferedInputStream bis= new BufferedInputStream(fis);
            int s;
                        
            while((s = bis.read()) != -1) {
                // Là, ça streame la réponse ! Si le fichier est audio
                // ou vidéo ça va streamer vraiment !
		out.write((char)s);
	    }
	} catch (FileNotFoundException e) {
		// envoyer code erreur not found
	} catch (IOException e) {
		// envoyer code erreur serveur
	}
}

 

 

Mots clés:
FichierTailleDateAttaché par 
 mime.types
Aucune description
44.41 Ko09:00, 7 Fév 2012MichelBuffaActions
 TP1_MiniServeurHTTP.rar
Aucune description
2.7 Ko10:32, 1 Fév 2011MichelBuffaActions
 TP1_MiniServeurHTTP (1).zip
Aucune description
3.05 Ko11:06, 10 Fév 2011GuillaumeHussonActions
Images (0)
 
Commentaires (0)
Vous devez être connecté pour poster un commentaire.