Howto curl
- Page de manuel : https://curl.haxx.se/docs/manpage.html
curl est un client HTTP libre en ligne de commande. Il supporte aussi d’autres protocoles (HTTPS, IMAP(S), LDAP(S), POP3(S), SSCP, SFTP, SMB, SMTP(S) etc.). Il est également intégré à de nombreux langages (PHP, Python, Ruby, Perl, etc. sous forme de bibliothèque (libcurl).
Utilisation de base
Pour récupérer et afficher – sur la sortie standard – le contenu d’une ressource :
$ curl https://www.example.com
Pour afficher une version verbeuse de la requête (> Infos envoyées, < Infos reçues, * Infos supplémentaires,notamment des informations sur le certificat SSL) :
$ curl -v https://www.example.com
Pour faire une requête HEAD et donc afficher uniquement les en-têtes de la réponse, utiliser l’option -I
(ou --head
) :
$ curl -I www.example.com
Pour enregistrer la ressource dans un fichier portant le même nom, utiliser l’option -O
(ou --remote-name
) :
$ curl -O https://www.example.com/page.html
Dans le cas d’un protocole s’appuyant sur SSL/TLS, pour ne pas vérifier la validité du certificat on ajoute l’option -k
(ou --insecure
) :
$ curl -k https://www.example.com/
Par défaut, curl ne suit pas les redirections HTTP (follow), il faut l’option -L
(ou --location
) :
$ curl -L http://www.example.com
Pour spécifier un User-Agent, utiliser l’option -A
(ou --user-agent
) :
$ curl -A "Mozilla/5.0 (compatible; evolix; http://evolix.com)" http://example.com
Plus généralement, pour spécifier un en-tête HTTP utiliser l’option -H
(ou --header
) :
$ curl http://www.example.com -H 'Accept: text/plain'
$ curl -H 'Accept-Language: en' https://example.com
Pour envoyer un cookie dans la requête, utiliser l’option -b
(ou --cookie
) :
$ curl http://www.example.com -b 'key=value'
Pour l’utilisation d’un proxy :
$ curl -x http://localhost:8123 http://www.example.com
Forcer la résolution DNS
Lorsque l’on fait des tests, on a souvent besoin de forcer la résolution d’un enregistrement DNS vers une adresse IP spécifique. L’astuce classique est de modifier le fichier HOSTS (/etc/hosts
sous Linux et BSD) mais cela n’est pas très pratique pour diverses raisons (nécessite un accès root, cela change pour toutes les machines, il peut y avoir du cache).
Première astuce possible, modifier l’en-tête Host
:
$ curl http://192.0.2.1:8080/foo/bar -H 'Host: www.example.com'
L’inconvénient est qu’il faut modifier l’URL pour mettre l’adresse IP (ce qui ne permet pas de faire des copier/coller facilement) et que cela ne gère par le SNI (dans le cas de la couche SSL/TLS).
Une seconde astuce est d’utiliser l’option --resolve
(à partir de curl 7.21.3) :
$ curl --resolve www.example.com:443:192.0.2.1 https://www.example.com/foo/bar
Utilisation avancée
Pour envoyer une authentification HTTP, préciser l’option -u
(ou --user
) :
$ curl -u jdoe:PASSWORD https://www.example.com
Pour spécifier la méthode HTTP POST/PUT/DELETE (par défaut GET), cela se fait avec l’option -X
(ou --request
) :
$ curl -X POST https://www.example.com
Attention, cette option se contente de modifier le verbe HTTP indiqué dans l’en-tête de la requête et ne modifie pas du tout le comportement de curl vis-à-vis de la réponse. Pour en savoir plus sur les bons et mauvais usages de cette option : https://daniel.haxx.se/blog/2015/09/11/unnecessary-use-of-curl-x/
Pour afficher les en-têtes et le contenu, utiliser l’option -i
(ou --include
) :
$ curl -i https://www.example.com
En-têtes de requête et de réponse
À placer dans un script, pour faciliter son utilisation.
Note: Ce script permet de ne pas modifier le verbe HTTP employé. En effet, une requête « HEAD » peut-être traitée différemment d’un « GET » par certains services. Il peut être combiné avec toutes les options de Curl.
#!/bin/sh
#
# Based on an original implementation by Ryan Tomayko https://github.com/rtomayko/
# modified by Jérémy Lecour https://github.com/jlecour/
curl -sv "$@" 2>&1 >/dev/null |
grep -v "^\*" |
grep -v "^}" |
grep -v "data]$" |
cut -c3-
$ ~/bin/headers http://www.example.com
GET / HTTP/1.1
User-Agent: curl/7.38.0
Host: www.example.com
Accept: */*
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=604800
Content-Type: text/html
Date: Mon, 27 Mar 2017 12:39:35 GMT
Etag: "359670651"
Expires: Mon, 03 Apr 2017 12:39:35 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Server: ECS (lga/13D5)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1270
[data not shown]
Interactions avec une API REST
Pour tester des interactions avec une API REST, on peut facilement envoyer des structures de données.
En direct :
$ curl -XPUT 'http://localhost:9200/_snapshot/foo' -d '{
"type": "fs",
"settings": {
"location": "/home/backup-elasticsearch",
"compress": true
}
}'
Via un fichier :
$ curl -XPUT 'http://localhost:9200/_snapshot/foo' -d @/path/to/file
Version compressée
Pour obtenir le contenu gzipé (avec un en-tête HTTP forcé) :
$ curl www.example.com -H 'Accept-Encoding:gzip, deflate'
If-(M|Unm)odified-Since : contrainte sur la date de modification
Pour préciser l’en-tête HTTP If-Modified-Since
et récupérer le contenu seulement si celui-ci a été modifié après le 17 Mars 2017, utiliser l’option (-z
ou --time-cond
) :
$ curl -z 17-Mar-17 https://www.example.com
Pour préciser l’en-tête HTTP If-Unmodified-Since
et récupérer le contenu seulement si celui-ci a été modifié avant le 17 Mers 2017 :
$ curl -z -17-Mar-17 https://www.example.com
Exécution silencieuse (cron, script…)
On peut combiner les options --fail
, --silent
et --show-error
pour faire en sorte que l’exécution de curl soit silencieuse, à moins d’une erreur.
$ curl --fail --silent --show-error https://www.example.com > /dev/null
$ echo $?
0
$ curl --fail --silent --show-error https://www.example.com/foo > /dev/null
curl: (22) The requested URL returned error: 404
$ echo $?
22
Si ces commandes sont exécutées en cron ; en cas d’échec le message d’erreur est envoyé par e-mail, mais en cas de succès rien n’est affiché ni envoyé.
Mesurer le temps d’execution d’une requête :
On peut mesurer le temps d’execution d’une requête http, il faut créer un fichier de configuration curl-time.txt comme ceci :
timelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n
Puis faire une requete curl, avec l’option -w, pour utiliser ce fichier de format :
curl -w "@curl-time.txt" -o /dev/null -s "https://www.example.com/"
Autres protocoles
SMTP
Envoyer un email :
$ curl --mail-from foo@example.com --mail-rcpt bar@example.com smtp://example.com/
IMAP(S)
$ curl --url "imaps://mail.example.com" --user "bar@example.com:password"
FTP
Récupérer le fichier Debian.iso via FTP :
$ curl -u jdoe:PASSWORD -O ftp://ftp.example.com/foo/bar/Debian.iso
Lister le contenu d’un dossier :
$ curl ftp://ftp.example.com/foo/bar/
Envoyer des fichiers :
$ curl -u jdoe:PASSWORD -T fichier ftp://ftp.example.com/
$ curl -u jdoe:PASSWORD -T "{fichier1,fichier2}" ftp://ftp.example.com/
FAQ
Récupérer des requêtes pour curl via un navigateur
Dans Firefox et Chrome/Chromium (et probablement d’autres) il est possible de récupérer une commande curl reprenant exactement la requête que le navigateur a faite. C’est particulièrement pratique si on veut reproduire la requête et faire un débogage plus fin. Il faut ouvrir le navigateur, dans la partie « réseau » et avec un clic-droit sur la ressource voulue, le menu déroulant proposera « Copy as curl » (ou similaire).
curl VS cURL
cURL, ou see URL (« voir URL »), est le nom général du projet, qui englobe l’outil curl et la bibliothèque libcurl comme indiqué sur https://daniel.haxx.se/docs/curl-vs-libcurl.html. Mais Daniel Steinberg, le principal auteur de curl, a dit qu’on pouvait utiliser ce qu’on veut !.
Erreur 23 : Failed writing body
Dans certains cas, lorsqu’on récupère la sortie de “curl” dans un autre programme — exemple curl http://example.com | grep foo
— l’erreur (23) Failed writing body
est renvoyée. Dans ce cas, “grep” interrompt la sortie standard dès qu’il a trouvé ce qu’il cherche, “curl” n’a alors plus d’emplacement où écrire ses données.
On désactive alors le buffer de “curl” avec l’option -N
(ou --no-buffer
) afin de récupérer toute la réponse avant de la transmettre à la sortie standard : curl -N http://example.com | grep foo
.
Erreur 141A318A SSL routines:tls_process_ske_dhe:dh key too small
Selon la version de l’OS où de la clé DH qui a été généré, il se peut qu’on ai une erreur “SSL routines:tls_process_ske_dhe:dh key too small” en faisant une requêtes curl.
Si vous souhaitez bypasser la vérification clé DH on peu utilisé l’option –cipher comme ceci :
# curl --ciphers 'DEFAULT:!DH'
On peux également utilisé l’option –cipher pour désactivé d’autres cipher lors de la requetes curl, ou de la limité seulement a certains cipher par exemple :
# curl --ciphers 'ECDHE-RSA-AES128-GCM-SHA256'
ou rajouter l’option --ciphers ECDHE-RSA-AES128-GCM-SHA256
dans le fichier .curlrc