14 KiB
% Introduction au HTTP % Sylvain Eliade — S.C.O.P. Cadoles % Mai 2019
Introduction au HTTP
- HyperText Transport Protocol
- Protocole texte
- Client-serveur
- En général sur TCP, port 80
- Stateless, aucun état n'est conservé entre les requêtes
- Très simple
- Requêtes toujours initiées par le client
À quoi ça ressemble ?
Un simple telnet
permet de faire des requêtes HTTP !
% telnet sylvain.eliade.net 80
Trying 91.121.181.110...
Connected to eliade.net.
Escape character is '^]'.
GET /resume/ HTTP/1.1
Host: sylvain.eliade.net
Le serveur nous répond :
HTTP/1.1 200 OK
Date: Mon, 13 May 2019 10:02:02 GMT
Server: Apache
Last-Modified: Fri, 19 Apr 2019 07:36:32 GMT
ETag: "2abb-586dd2d7c21de"
Accept-Ranges: bytes
Content-Length: 10939
Vary: Accept-Encoding
Content-Type: text/html
Connection: close
<!DOCTYPE html>
<html>
…
Un outil plus pratique est quand même curl
!
% curl -v http://sylvain.eliade.net/resume/
Structure d'une requête
Première ligne : MÉTHODE RESSOURCE PROTOCOLE
- Méthode (ou verbe) HTTP = action que l'on souhaite utiliser (
GET
,DELETE
,POST
, etc.) - Ressource sur laquelle on souhaite effectuer l'action
- Version du protocole :
HTTP/1.0
ouHTTP/1.1
(il existe encore des clients HTTP/0.9 mais bon…)
Lignes suivantes : les entêtes. Puis : une ligne vide.
Puis éventuellement (méthodes POST
, PUT
, PATCH
, etc.) : corps (contenu) de la requête.
Méthodes HTTP
- GET : la plus courante, renvoie la ressource demandée (exemple : visualiser une page web)
- POST : envoyer des données liées à la ressource (exemple : envoyer un formulaire web)
Les méthodes suivantes sont rarements utilisées par les navigateurs mais souvent dans les API :
- HEAD : obtenir des infos sur la ressource. En pratique c'est souvent pareil que GET, mais ça ne renvoie que les entêtes et pas le corps.
- PUT : ajouter / remplacer une ressource
- OPTIONS : savoir quelles sont les méthodes supportées par le serveur pour une ressource
Structure d'une réponse
Première ligne : PROTOCOLE CODE MESSAGE
- Code = code de réponse du serveur (200 = OK, 404 = Not Found, etc.)
- Message = message de réponse associé au code
Lignes suivantes : les entêtes de réponse.
Puis : une ligne vide.
Puis éventuellement (tout le temps sauf avec requête HEAD
) : corps de la réponse.
Codes de réponses HTTP
Le premier chiffre indique le type de code :
- 1xx = requête reçue mais son exécution n'est pas terminée
- 2xx = succès
- 3xx = redirection
- 4xx = erreur du client
- 5xx = erreur du serveur
Codes courants
- 200 OK = la plus courante
- 301 Moved Permanently = ressource déplacée définitivement (voir l'entête
Location
pour la nouvelle adresse) - 302 Found = ressource déplacée temporairement
- 400 Bad Request = erreur dans la requête du client
- 401 Unauthorized = le client n'a pas accès, il lui faut s'authentifier
- 403 Forbidden = accès refusé (par exemple mauvais login/mot de passe)
- 404 Not Found = ressource non trouvée
- 500 Internal Server Error
- 503 Service Unavailable = serveur surchargé
Entêtes
Host: sylvain.eliade.net
User-Agent: telnet/1.0
Chaque entête est une clé (en général avec une majuscule au début de chaque mot, les mots étant séparés par des tirets), suivi de deux points :
, d'un espace et de la valeur de l'entête.
Liste des entêtes : https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
Entêtes courants pour les requêtes
Host
: pour indiquer le nom de domaine que l'on essaye d'atteindre (car le serveur HTTP ne sais pas quelle requête DNS on a fait pour le contacter)Accept-Language
: indique les langues préférées du client (fr-BE, fr, en-AU, en
)Accept
: les formats de fichier gérés par le client (text/html, image/jpeg…
)Connection
: pour garder la connexion TCP ouverte pour faire plusieurs requêtes de suiteUser-Agent
: nom du client utiliséCookie
: contenu d'un cookieAuthorization
: identifiants de connexion HTTP (accès par mot de passe)
Entêtes courants pour les réponses
Connection
: état de la connexion TCPDate
: date de réponseContent-Type
: type du contenu (text/html; charset=utf-8
)Location
: nouvelle adresse du contenu quand il a changé d'adresseServer
: nom du serveurSet-Cookie
: le client doit enregistrer ce cookieWWW-Authenticate
: demande d'authentification
Aparté : les URLs
Uniform Resource Locator (interchangeable avec URI, Uniform Resource Identifier)
protocol://[user[:password]@]host[:port]path[?query][#fragment]
Entre crochets les parties facultatives.
- protocol : http ou https
- user[:password] : nom d'utilisateur (et éventuellement mot de passe), pour l'authentification HTTP
- host : nom de domaine (ou adresse IP, pour une IPv6 elle doit être entre crochets, exemple :
http://[::1]/page
) - port : numéro de port optionnel
- path : chemin de la ressource
- query (ou query string) : liste de clés et valeurs, séparées par des
&
- fragment : identifiant d'une sous-ressource à l'intérieur de la ressource (en pratique, utilisé pour se rendre à une point particulier de la page web, ou en javascript)
https://catalogue.cesi.fr/recherche/?domaine=informatique&niveau=bac4#type
- protocol:
https
- host:
catalogue.cesi.fr
- path:
/recherche/
- query:
domaine=informatique&niveau=bac4
- fragment:
type
Les serveurs HTTP les plus courants
- Apache (29% des serveurs)
- nginx (29%) : plus rapide qu'Apache sur les fichiers statiques, même performance sur le contenu dynamique (PHP)
- Microsoft IIS (19%)
Apache est le plus courant, historiquement le plus utilisé, mais on trouve de plus en plus du nginx aussi. La configuration de nginx est un peu plus lisible que celle d'Apache.
Apache et ses MPM
Apache possède plusieurs MPM (multi-processing module) qui ont des comportements différents :
- prefork : moins performant (sans threads), chaque processus ne peut traiter qu'une seule requête à la fois
- worker ou event : plus performant, chaque processus a plusieurs threads, et peut donc traiter plusieurs requêtes à la fois
Quel MPM choisir ? En production on utilisera worker ou event, car plus rapides, mais pour tester des trucs rapidement avec PHP on peut utiliser prefork qui est plus simple à metter en place.
Un mot sur l'utilisateur www-data
Par défaut Apache est lancé avec l'utilisateur www-data
. Ça va si on n'a qu'un seul site hébergé sur la machine.
Si on veut héberger plusieurs sites, il vaut mieux pouvoir avoir un utilisateur par site, pour pas qu'un site puisse aller modifier les fichiers d'un autre site.
Pour cela une version de prefork appelée ITK (apt install libapache2-mpm-itk
) permet d'avoir des processus Apache qui se lancent avec les droits d'utilisateurs différents.
Installation Apache sous Debian
- Installer le serveur :
apt install apache2
- Statut du serveur :
apache2ctl status
(permet de voir les requêtes traitées en ce moment, le nombre de workers etc.) - Tester si la config n'a pas d'erreur :
apache2ctl configtest
- Recharger la configuration après modification :
apache2ctl graceful
Gérer les modules Apache sous Debian
- Activer un module :
a2enmod NOM_DU_MODULE
(exemple :a2enmod rewrite
) - L'outil préviendra s'il y a un conflit entre deux modules incompatibles :)
- Désactiver :
a2dismod NOM_DU_MODULE
- Même chose pour les MPM :
a2dismod mpm_prefork
puisa2enmod mpm_worker
Astuce : lancer a2enmod
sans argument liste les modules disponibles.
La configuration du module est dans le fichier /etc/apache2/mods-available/NOM_DU_MODULE.conf
Configuration Apache
Syntaxe simple. Ce n'est pas du XML !
Listen 80
KeepAlive Off # Ne pas autoriser les connexions persistantes
<Directory /var/www/monsite>
Require all granted
Options -Indexes
</Directory>
VirtualHost
Apache permet d'héberger plusieurs sites sur le même serveur avec des hôtes virtuels. L'hôte est reconnu avec l'entête "Host". Pour cela on utilise des hôtes virtuels.
<VirtualHost *:80>
ServerName cadoles.com
DocumentRoot /var/www/monsite
</VirtualHost>
<VirtualHost *:80>
ServerName mail.cadoles.com
DocumentRoot /var/www/roundcube
</VirtualHost>
Le premier vhost de la liste sera utilisé comme vhost "par défaut" si aucun vhost n'est trouvé pour l'hôte demandé.
VirtualHost dans Debian/Ubuntu
Les vhost disponibles sont séparés par fichiers dans /etc/apache2/sites-available
, triés par ordre alpha-numérique.
Ensuite : a2ensite nomduvhost
pour activer, ou a2dissite nomduvhost
pour désactiver.
Ne pas oublier de tester la config et recharger ensuite !
Astuce : lancer a2ensite
ou a2dissite
sans argument liste les sites disponibles.
Fichiers .htaccess
Apache permet de configurer des options pour un répertoire donné à l'aide d'un fichier .htaccess
(en UNIX, les fichiers avec un point au début sont des fichiers "cachés").
C'est pratique, mais attention, cela veut dire qu'Apache sera beaucoup plus lent, car il va chercher ce fichier dans tous les sous-répertoires à chaque requête !
Donc il est recommandé de désactiver ce comportement par défaut, et de ne l'activer que pour les sites qui en ont besoin. Tant que possible il vaut mieux mettre toute la configuration dans les fichiers de configuration Apache du vhost.
<Directory />
AllowOverride None
</Directory>
<Directory /var/www/wordpress>
AllowOverride All
</Directory>
AllowOverride permet de configurer le type de directive autorisée dans le fichier .htaccess
.
None = aucune directive autorisée = Apache ne va même pas lire les fichier .htaccess
Restriction d'accès
Un exemple courant de .htaccess
est la restriction d'accès par mot de passe. Pour cela il faut dire à Apache de n'autoriser que les utilisateurs connectés avec Require valid-user
:
Require valid-user
AuthType basic
AuthName "Accès restreint"
AuthUserFile /var/www/monsite/secret/.htpasswd
Fichier htpasswd
Pour créer le fichier .htpasswd
qui contiendra la liste de nos utilisateurs autorisés et leurs mots de passe nous devons utiliser l'outil htpasswd
.
A installer avec apt install apache2-utils
.
- Créer le fichier avec
htpasswd -c /var/www/monsite/secret/.htpasswd NOM_UTILISATEUR
(-c
comme Création du fichier) - L'outil demande de taper, puis re-taper le mot de passe
- Pour ajouter un utilisateur ou modifier son mot de passe, simplement :
htpasswd /var/www/monsite/secret/.htpasswd NOM_UTILISATEUR
(sans le-c
donc)
sylvain:$apr1$vfxnPOnt$gI7MkAizYirxT/CrUfCqU0
Exercice 1
Faire une requête avec curl
sur http://www.cesi.fr/
. Quel est le code HTTP retourné ? Quel est le serveur web utilisé ?
Exercice 2
Installation de Apache2. Faire une requête sur http://localhost/
pour voir si ça fonctionne.
Puis essayer d'accéder à l'IP de la VM depuis un navigateur de la machine hôte pour voir si ça fonctionne bien.
(Pour obtenir l'IP : ip addr
depuis la console)
Exercice 3
Prérequis : créer un répertoire /var/www/cesi.test
et un fichier /var/www/cesi.test/index.html
avec :
mkdir /var/www/cesi.test
echo "Hello monde !" > /var/www/cesi.test/index.html
Exercice : Mettre en place un VirtualHost cesi.test
proprement, l'activer.
Pour vérifier son fonctionnement, ajouter la ligne suivante dans /etc/hosts
: 127.0.0.1 cesi.test
. Puis faire curl http://cesi.test/
, le message "Hello monde" devrait apparaître.
Exercice 4
Prérequis : créer un répertoire /var/www/cesi.test/secret
: mkdir /var/www/cesi.test/secret
Désactiver les vhosts existants, sauf celui de cesi.test
. Recharger apache.
Mettre en place une protection par mot de passe du répertoire /var/www/cesi.test/secret
avec un fichier .htaccess
.
Vérifier que ça marche correctement en utilisant le navigateur de la machine hôte sur l'IP de la VM.
Exercice 5 (facultatif)
Tester la charge du serveur avec ApacheBench :
- installer
ab
:apt install apache2-utils
- dans une première console, lancer
watch -d -n 0.1 sudo apache2ctl status
- lancer dans une seconde console
ab -n 5000 -c 100 http://localhost/
(va lancer 5000 requêtes, par vagues de 100 en même temps) - observer l'évolution du nombre de workers, et de la charger serveur (Server load)
Exercice 6 (facultatif)
Changer de MPM, passer de prefork (celui utilisé par défaut normalement) à event.
Répéter le test de l'exercice 5 et observer les différences.
Exercice 7 (facultatif)
On nous demande de faire de la réécriture d'adresse.
Faire en sorte que http://cesi.test/etu
redirige vers http://localhost/infos-etudiant
en utilisant la directive Redirect
dans le vhost créé précédemment (voir la documentation de Redirect pour un exemple).
Pour cela il faudra activer le module alias
.
Il est courant d'utiliser RewriteRule
pour faire cela (module rewrite
), mais il est plus lent et complexe (Documentation), mais permet plus de possibilités.
Exercice 8 (facultatif)
Installer nginx
et créer un virtualhost cesi.test
.
Un exemple de configuration de virtualhost est dispo dans /etc/nginx/sites-available/default
.
Pour créer le vhost, créer un fichier /etc/nginx/sites-available/cesi.test
.
Pour l'activer exécuter ln -s /etc/nginx/sites-available/cesi.test /etc/nginx/sites-enabled/cesi.test
, cela va créer un lien symbolique (pas de commande comme avec Apache type a2ensite
).
Puis nginx -t
pour vérifier la configuration et service nginx reload
pour recharger.