# Howto HTTP Le procotole HTTP (HyperText Transfer Protocol) est un protocole client/serveur de niveau 7 s'appuyant par convention sur la couche de transport TCP et le port 80. Sa version sécurisée est HTTPS qui ajoute la couche [SSL/TLS](HowtoSSL). ## Comprendre les différentes versions de HTTP grâce à telnet ### HTTP/1.0 La version la plus simple, l'entête `Host:` est facultatif : ~~~ $ telnet www.debian.org 80 Trying 5.153.231.4... Connected to www.debian.org. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.1 200 OK Date: Wed, 05 Oct 2016 02:09:37 GMT Server: Apache Last-Modified: Fri, 08 Jan 2016 22:27:31 GMT ETag: "1d8-528da17d9b160" Accept-Ranges: bytes Content-Length: 472 Vary: Accept-Encoding X-Clacks-Overhead: GNU Terry Pratchett Connection: close Content-Type: text/html [...] Connection closed by foreign host. ~~~ ### HTTP/1.1 L'entête `Host:` est obligatoire : ~~~ $ telnet www.debian.org 80 Trying 5.153.231.4... Connected to www.debian.org. Escape character is '^]'. GET / HTTP/1.1 Host: www.debian.org HTTP/1.1 200 OK Date: Wed, 05 Oct 2016 02:11:37 GMT Server: Apache Content-Location: index.en.html Vary: negotiate,accept-language,Accept-Encoding TCN: choice Last-Modified: Tue, 04 Oct 2016 15:27:56 GMT ETag: "3baf-53e0bb4711c9f" Accept-Ranges: bytes Content-Length: 15279 Cache-Control: max-age=86400 Expires: Thu, 06 Oct 2016 02:11:37 GMT X-Clacks-Overhead: GNU Terry Pratchett Connection: close Content-Type: text/html Content-Language: en [...] Connection closed by foreign host. ~~~ #### HTTP/1.1 100 Continue Avec le protocole HTTP/1.1, il y a une utilisation spécifique pour pour l'envoi « décalé » d'un gros payload. Par exemple un client va envoyer un : ~~~ POST /callback Content-Type: application/pdf Content-Length: 123456 Expect: 100-continue ~~~ Le serveur va alors lui répondre `HTTP/1.1 100 Continue` et ensuite seulement le client enverra le contenu du PDF puis le serveur enverra la réponse finale `HTTP/1.1 200 OK`. Plus d'infos sur : * * Voici une commande `curl` pour reproduire cela : ~~~ $ curl --http1.1 -v -H "Expect: 100-continue" -F person=anonymous -F secret=@/tmp/foo.bin https://www.example.com/callback * Connected to ... > POST /callback HTTP/1.1 > Host: www.example.com > Accept: */* > Expect: 100-continue > Content-Length: 309 > Content-Type: multipart/form-data; boundary=------------------------d5c85d941a76e4fa > * TLSv1.3 (IN) ... < HTTP/1.1 100 Continue * We are completely uploaded and fine * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < content-type: text/html; charset=UTF-8 < transfer-encoding: chunked < Hello World * Connection #0 to host ... ~~~ ### HTTPS On gère le tunnel SSL avec `openssl` puis tout est en clair : ~~~ $ echo -e "GET / HTTP/1.1\r\nHost: www.debian.org\r\n\r\n" | openssl s_client -host www.debian.org -port 443 -quiet -servername www.debian.org CONNECTED(00000003) depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root verify return:1 depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority verify return:1 depth=1 C = FR, ST = Paris, L = Paris, O = Gandi, CN = Gandi Standard SSL CA 2 verify return:1 depth=0 OU = Domain Control Validated, OU = Gandi Standard SSL, CN = debian.org verify return:1 --- Certificate chain 0 s:/OU=Domain Control Validated/OU=Gandi Standard SSL/CN=debian.org i:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2 1 s:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2 [...] Start Time: 1475633567 Timeout : 300 (sec) Verify return code: 0 (ok) --- HTTP/1.1 200 OK Date: Wed, 11 Oct 2023 14:52:22 GMT Server: Apache [...] ~~~ ### HTTP/2.0 Voir ## Outils HTTP ### Commandes HEAD/GET/POST Il s'agit de commandes HEAD, GET, POST faisant partie de la bibliothèque LWP (WWW Library for Perl) : ~~~ # apt install libwww-perl ~~~ Utilisation : ~~~ $ HEAD www.evolix.fr 200 OK Connection: close Date: Tue, 28 Dec 2010 20:08:35 GMT Server: Apache Vary: Accept-Encoding Content-Type: text/html Client-Date: Tue, 28 Dec 2010 20:08:44 GMT Client-Peer: 85.31.205.43:80 Client-Response-Num: 1 $ GET -Sd evolix.fr GET http://evolix.fr 301 Moved Permanently GET http://www.evolix.fr/ 301 Moved Permanently GET http://evolix.com/ 200 OK $ HEAD -U -H "User-Agent: Mozilla/4.8 [en] (Windows NT 5.1; fr; rv:BlogByGcolpart)" \ -H "Referer: http://www.evolix.fr/" www.evolix.fr/serv/infogerance.html HEAD http://www.evolix.fr/serv/infogerance.html Referer: http://www.evolix.fr/ User-Agent: Mozilla/4.8 [en] (Windows NT 5.1; fr; rv:BlogByGcolpart) 200 OK Connection: close Date: Thu, 13 Jan 2011 23:14:13 GMT Server: Apache Vary: Accept-Encoding Content-Type: text/html Client-Date: Thu, 13 Jan 2011 23:14:13 GMT Client-Peer: 85.31.205.43:80 Client-Response-Num: 1 $ GET -dUe google.fr GET http://www.google.fr/ User-Agent: lwp-request/6.03 libwww-perl/6.08 200 OK Cache-Control: private, max-age=0 Connection: close Date: Thu, 18 May 2017 12:00:13 GMT Accept-Ranges: none Server: gws Vary: Accept-Encoding Content-Type: text/html; charset=ISO-8859-1 Expires: -1 Client-Date: Thu, 18 May 2017 12:00:13 GMT Client-Peer: 216.58.210.195:80 Client-Response-Num: 1 Link: ; rel="shortcut icon" P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info." Set-Cookie: NID=103=UEe-aKr4jwguVRZw_irgQQo6WviJ2ZArnM9iCouDcPzBV_RZk4YiR4I13Kn1JSO-Gbcowcw5W1BtUTCd7pQt7H6_zKK6zf8EVb2GG5Yb_ariD0aWeAJxHFf2sRMkZXTi; expires=Fri, 17-Nov-2017 12:00:13 GMT; path=/; domain=.google.fr; HttpOnly Title: Google X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block $ GET http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.36.2.tar.bz2 > linux-2.6.36.2.tar.bz2 $ GET google.fr | grep charset= | sed 's@^.*charset=\([-a-Z0-9]*\)".*$@\1@' ISO-8859-1 $ POST http://www.evolix.fr/contacts.html Please enter content (application/x-www-form-urlencoded) to be POSTed: from=jdoe%40example.com&contenu=Coucou&validation=nospam&soumettre=ok Ctrl+d $ echo -n "from=jdoe%40example.com&contenu=Coucou&validation=nospam&soumettre=ok" > /tmp/POST-DATA.txt $ POST http://www.evolix.fr/contacts.html < /tmp/POST-DATA.txt $ GET -dUe -H 'Cookie: foo="bar"' https://marsactus.fr/ GET https://marsactu.fr/ User-Agent: lwp-request/6.36 libwww-perl/6.36 200 OK Cache-Control: max-age=3600 Connection: close Date: Tue, 11 Feb 2020 [...] ~~~ Note : Attention, pour envoyer interactivement des données en POST, il faut ensuite les valider avec Ctrl+d Voici les différentes options possibles : * `-U` : affiche les entêtes envoyés * `-e` : affiche les entêtes reçus (s'utilise avec GET/POST car c'est le défaut pour HEAD) * `-d` : ne pas afficher la réponse (à utiliser avec `-dUe` ou `-dS` par exemple) * `-H` : envoyer un entête HTTP particulier * `-S` : affiche les redirections HTTP suivies ### Wget [Wget](https://www.gnu.org/software/wget/) est un client HTTP en ligne de commande. Voir [HowtoWget]() ### cURL [cURL](https://curl.haxx.se/) est aussi un client HTTP en ligne de commande. Voir [HowtocURL]() ### ab : apache bench ~~~ # apt install apache2-utils ~~~ Utilisation : ~~~ $ ab -n 1000 -c 100 -H "User-Agent: EvolixBench" -l http://127.0.0.1/helloworld.txt ~~~ * `-n` : nombre de requêtes * `-c` : nombre de requêtes effectuées en simultané * `-H` : change les entêtes HTTP * `-l` : option importante qui tolère la variation de la réponse du serveur (si non, les requêtes seront notées en *Failed requests*) * `-k` : active le HTTP KeepAlive ### Tsung Voir [HowtoTsung]()