##### Notre première requête !

Revenons à notre Telnet. Tu vas émettre une requête au mini-serveur, en saisissant `GET / HTTP/1.1`, et en validant *deux fois* par entrée : ceci équivaut à écrire une ligne vide après la rêquête, ce qui nous permet de signifier au serveur que notre requête est terminée et qu'il peut la traiter.

Tu dois voir s'afficher la réponse brute du serveur :
```text
HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.5.2
Date: Mon, 12 Feb 2018 02:24:43 GMT
Content-type: text/html

Hello world!Connection closed by foreign host.
```

Précision : la partie `Connection closed by foreign host.` à la fin ne fait pas partie de la réponse ! C'est simplement le texte affiché par Telnet quand il quitte parce que la connexion avec le serveur s'est rompue.

En effet, à chaque requête, le client ouvre une nouvelle connexion vers le serveur, et celui-ci la rompt une fois qu'il a fini d'envoyer la réponse. Cela rejoint la notion de protocole sans état.

Ce bout de texte se trouve sur la même ligne, tout simplement parce qu'on n'a pas mis de retour chariot dans la chaîne `"Hello world!"` envoyée par le mini-serveur.

Que contient la réponse ?

- Sur la première ligne : la version de HTTP utilisée par le serveur `HTTP/1.0`, suivie du *code de réponse* numérique 200, suivi de la traduction en langage intelligible par un humain de ce code : OK, tout s'est bien passé.
- Sur les trois lignes suivantes : les *en-têtes de réponse* (*response headers*). Ce sont des paires clé-valeur. Le serveur nous dit qui il est, via l'en-tête `Server`, nous indique la `Date` précise à laquelle il a répondu, et nous indique quel type de contenu il a envoyé : du HTML (encore qu'ici ce soit du texte).
- Puis une ligne vide, puis le *corps de la réponse* (*response body*).

Remarque que :
- le code 200 correspond à ce qui a été spécifié via la ligne `self.send_response(200)` dans le code du serveur.
- l'en-tête `Content-type` correspond aussi à une ligne de code du serveur.
- les autres en-têtes `Server` et `Date` ont été ajoutées automatiquement par le serveur.

##### Une requête incorrecte !

Relance `telnet 127.0.0.1 8081` puis saisis : `ABOULE / HTTP/1.1`, et valide deux fois. Voilà la réponse :
```text
HTTP/1.0 501 Unsupported method ('ABOULE')
Server: BaseHTTP/0.6 Python/3.6.4
Date: Mon, 12 Feb 2018 02:55:20 GMT
Connection: close
Content-Type: text/html;charset=utf-8
Content-Length: 499

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
        <title>Error response</title>
    </head>
    <body>
        <h1>Error response</h1>
        <p>Error code: 501</p>
        <p>Message: Unsupported method ('ABOULE').</p>
        <p>Error code explanation: HTTPStatus.NOT_IMPLEMENTED - Server does not support this operation.</p>
    </body>
</html>
```

Le serveur est beaucoup plus bavard ! Regarde la première ligne : tout code autre que 20x signifie une erreur. Ici c'est simplement une *méthode* HTTP qui n'existe pas. La méthode, c'est souvent un *verbe* qui indique la nature de notre requête au serveur (veut-on simplement retirer - `GET` - ou envoyer - `POST` - des données).

Les *méthodes* sont standardisées, et c'est heureux, à moins de tenir spécialement à ce que le navigateur et le serveur parlent en argot (abouler viendrait de l'occitan *abolar* pour la petite histoire !).

Pourquoi a-t-on plus de contenu ici, que dans la réponse à la requête correcte précédente ? Simplement parce que le serveur a des "modèles de page" tout prêts qu'il utilise dans certains cas d'erreur.

Note qu'on a un nouvel en-tête, `Content-Length`, qui indique le nombre d'octets reçus, en comptant le *corps* de réponse uniquement et pas les en-têtes. Si tu copies/colles la réponse, y compris le retour chariot, dans un éditeur de texte, et que tu sauves dans un fichier, celui-ci fera la taille exacte indiquée par `Content-Length`.


##### Une requête POST

Utilisons maintenant une méthode standard : `POST`.

Relance `telnet 127.0.0.1 8081` puis saisis :
```text
POST /bin/login HTTP/1.1
Content-Length: 37

User=Peter+Lee&pw=123456&action=login
```

&Agrave; nouveau, valide deux fois. La réponse est presque la même qu'avant :

```text
HTTP/1.0 501 Unsupported method ('POST')
Server: BaseHTTP/0.6 Python/3.6.4
Date: Mon, 12 Feb 2018 03:20:10 GMT
Connection: close
Content-Type: text/html;charset=utf-8
Content-Length: 497

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
        <title>Error response</title>
    </head>
    <body>
        <h1>Error response</h1>
        <p>Error code: 501</p>
        <p>Message: Unsupported method ('POST').</p>
        <p>Error code explanation: HTTPStatus.NOT_IMPLEMENTED - Server does not support this operation.</p>
    </body>
</html>
```

Pas si étrange : `POST` est une méthode standard, mais on n'a rien dans notre *handler* pour gérer une requête `POST`. Page suivante, on va l'ajouter !