Plateforme Edge Cloud de Fastly

Solutions numériques innovantes

Revenir au blog

Follow and Subscribe

Utilisation de cURL pour tester les réponses du serveur d’origine

Matt Torrisi

Senior Manager, Sales Engineering - Enterprise, Fastly

Publié initialement en août 2021. Mis à jour en mai 2025.

Réponse rapide : Pour utiliser cURL, ouvrez un terminal et saisissez cURL, suivi de l'URL à laquelle vous souhaitez envoyer une requête, par exemple, cURL https://www.fastly.com/. Cela envoie une requête HTTP et affiche la réponse directement à l'écran.

Principaux enseignements :

  • Utilisez cURL -svo /dev/null pour inspecter les détails de connexion, la négociation TLS, les en-têtes de requête et les en-têtes de réponse sans le bruit d'un corps de réponse.

  • Utilisez -H "host: ..." pour tester la manière dont un serveur répond à différents en-têtes host.

  • Utilisez --resolve pour ignorer le DNS et envoyer des requêtes vers une adresse IP spécifique.

  • Utilisez --connect-to pour rediriger les connexions tout en préservant le nom d'hôte de la requête d'origine.

  • La combinaison de ces options facilite le dépannage des problèmes de routage, de DNS, de TLS et de serveur d'origine.

Avez-vous déjà vécu des semaines qui n’ont qu’un thème ? En tant qu’ingénieur commercial, je travaille avec nos clients pour créer et déployer des systèmes, et la semaine dernière, j’ai clairement vu un thème.

J’ai rencontré ce que je pensais être un cas d’utilisation de niche dans lequel j’ai utilisé un outil spécifique (cURL) d’une manière bien précise pour tester la façon dont un serveur d’origine répond (utile, par exemple, pour tester lorsqu’une application répond avec un message d’erreur étrange). Et ça n’arrêtait pas de revenir ! J’ai expliqué le processus à quelques collègues qui étaient novices en la matière, ainsi qu’à quelques clients qui corrigeaient des déploiements, et j’ai pensé que cela ferait un bon article de blog. C’est parti.

Présentation rapide de cURL

Client URL (également connu sous le nom de cURL ou curl) a été publié en 1997 par Daniel Stenberg, qui maintient le projet avec diligence depuis. Il a été initialement créé pour automatiser la récupération du taux de change des devises pour les utilisateurs IRC, mais est depuis devenu plus largement utilisé pour toutes les formes de récupération d'URL. Depuis sa création, Daniel a continué à développer et à ajouter des fonctionnalités au projet, celui-ci étant devenu l'épine dorsale d'autres projets. Un héros absolu.

cURL est un outil de ligne de commande qui vous permet d'envoyer des requêtes HTTP vers une URL et de recevoir le résultat. Par défaut, cURL envoie une requête HTTP GET, ce qui le rend utile pour tester des sites web, des API et des serveurs d'origine. Il est installé par défaut sur des systèmes d'exploitation comme MacOS et de nombreuses distributions Linux. De plus, comme une grande partie d'Internet est axée sur le HTTP, c'est un excellent outil pour accéder à des pages web, à des API ou à tout autre outil doté d'une interface HTTP.

Pour notre démo, nous utiliserons cURL pour simuler l’expérience du navigateur lors de la requête d’une page web. Cela nous permet d’avoir un contrôle total sur la requête, ce qui facilite grandement la résolution des problèmes.

Vous trouverez ci-dessous une simple commande cURL que j’ai exécutée à partir du terminal de mon MacBook. Celui-ci demande la page d’accueil de Fastly.com et affiche l’intégralité du HTML. Une mise en garde : il s’agit d’une sortie bruyante que nous nettoierons plus tard.

$ curl https://www.fastly.com/

Options cURL courantes pour le dépannage

  • -s : mode silencieux

  • -v : sortie détaillée affichant les détails de la requête et de la réponse

  • -o : écrire la sortie dans un fichier

  • -I : renvoyer uniquement les en-têtes de réponse

  • -H : ajouter un en-tête HTTP personnalisé

  • --resolve : ignorer la résolution DNS pour un nom d'hôte

  • --connect-to : se connecter à un autre hôte ou à une autre adresse IP

La vraie puissance de cURL réside dans la possibilité de manipuler la requête en utilisant des options. Par exemple, ajouter -I limite la réponse affichée aux seuls en-têtes du serveur distant, et non au contenu.

Les options que j’utilise sur presque toutes mes commandes cURL sont -svo, qui lit en mode silencieux (s), verbose (v), écrivant dans un fichier (o), que j’écris dans dev/null.

La commande cURL complète est curl -svo /dev/null https://www.fastly.com. Cela me permet de me concentrer sur les détails de la requête sans me laisser distraire par un corps de réponse bruyant. Les en-têtes disposent d’une super option pour indiquer s’ils ont été envoyés ou reçus, et la négociation SSL est affichée avant la requête principale.

Ci-dessous, vous pouvez voir la commande telle qu’elle est écrite ($), la connexion et la négociation SSL (*), la requête (>) et la réponse (<).

$ curl -svo /dev/null https://www.fastly.com/
*   Trying 199.232.77.57...
* TCP_NODELAY set
* Connected to www.fastly.com (199.232.77.57) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [228 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [102 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2828 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [300 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Fastly, Inc.; CN=www.fastly.com
*  start date: Mar  3 21:56:03 2021 GMT
*  expire date: Apr  4 21:56:03 2022 GMT
*  subjectAltName: host "www.fastly.com" matched cert's "www.fastly.com"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fe1f980aa00)
> GET / HTTP/2
> Host: www.fastly.com
> User-Agent: curl/7.64.1
> Accept: */*

* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200 
< alt-svc: h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
< etag: "5c770df920f8c90e4c4532c32aea6ec3"
< content-type: text/html
< accept-ranges: bytes
< date: Mon, 09 Aug 2021 15:38:35 GMT
< x-served-by: cache-pwk4963-PWK
< x-cache: HIT
< x-cache-hits: 2
< x-timer: S1628523515.208976,VS0,VE0
< vary: Accept-Encoding
< x-xss-protection: 1; mode=block
< x-frame-options: DENY
< x-content-type-options: nosniff
< cache-control: max-age=0, private, must-revalidate
< server: Artisanal bits
< strict-transport-security: max-age=31536000
< content-length: 777219

{ [1113 bytes data]
* Connection #0 to host www.fastly.com left intact
* Closing connection 0

Comment cURL utilise l'URL et le nom SSL

Le scénario ci-dessus montre une situation où le nom du certificat SSL, l’en-tête de l’hôte et le nom DNS ont tous la même valeur www.fastly.com. Parfois, c’est tout ce dont vous avez besoin ! Maintenant, nous allons séparer ces éléments, ce qui nous permettra d’inspecter différents aspects selon les objectifs de résolution.

Développez des applications modernes et livrez des expériences en périphérie.

Voir le webinaire

L’utilisation actuelle de https://www.fastly.com/ affiche l’URL demandée. Le nom d’hôte utilisé dans l’URL (par exemple www.fastly.com) sera la valeur curl utilisée pour effectuer la requête et vérifier le nom du certificat SSL. C’est important pour vérifier que le protocole TLS fonctionne comme prévu et que votre site est sécurisé par le certificat attendu. Observez l’exemple ci-dessous :


$ curl -svo /dev/null https://www.fastly.com/
*   Trying 199.232.77.57...
* TCP_NODELAY set
* Connected to www.fastly.com (199.232.77.57) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [228 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [102 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2828 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [300 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Fastly, Inc.; CN=www.fastly.com
*  start date: Mar  3 21:56:03 2021 GMT
*  expire date: Apr  4 21:56:03 2022 GMT
*  subjectAltName: host "www.fastly.com" matched cert’s "www.fastly.com"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
*  SSL certificate verify ok.
--->{Truncated for readability}<---

Comment spécifier un chemin dans cURL

Les deux autres éléments qui restent dans l’URL d’origine sont le schéma, par exemple HTTP ou HTTPS, et le chemin d’accès à la ressource spécifique demandée. J’aime voir l’URL comme l’objectif, tout le reste n’étant que la manière ou le lieu où nous le demandons.

L'URL définit également le schéma (par exemple HTTP ou HTTPS) et le chemin d'accès à la ressource demandée.

Pour spécifier un chemin dans cURL, incluez-le directement dans l'URL : cURL https://www.fastly.com/blog/

Cela demande la ressource `/blog/` tout en conservant l'hôte, la validation du certificat et le comportement de routage.

Comment définir les en-têtes d'hôte avec cURL

Les en-têtes HTTP permettent aux clients d'envoyer des informations supplémentaires avec une requête. Avec cURL, des en-têtes peuvent être ajoutés à l'aide de l'option `-H` ou `--header`. L'un des en-têtes les plus utiles pour le dépannage est l'en-tête Host, qui indique à un serveur web le nom d'hôte que vous demandez. Un serveur web typique peut héberger plusieurs sites avec différents noms de domaine, comme blog.exemple.com ou docs.exemple.com. Bien que les sites puissent se trouver sur le même système, le code source et/ou le chemin de l'URL peuvent être différents.

Si nous voulons changer l’en-tête host, nous pouvons le faire en définissant explicitement l’en-tête dans curl. Les en-têtes peuvent être déclarés soit avec l’option --header ou, en abrégé, avec l’option -H. Ensuite, la valeur est placée entre guillemets et le nom de l’en-tête est défini. La commande curl ressemble à ceci :

$ curl -svo /dev/null https://www.fastly.com/ -H “host: blog.fastly.com”

Cette requête demande l’hôte de blog.fastly.com, en utilisant le certificat et l’emplacement de www.fastly.com. C’est particulièrement utile lorsque vous souhaitez vérifier la différence entre l’apex d’un domaine, par exemple fastly.com et www.fastly.com. Ici, nous voyons qu’il fournit correctement un chemin 301 à www.


$ curl -svo /dev/null https://www.fastly.com/ -H "host: fastly.com"
*   Trying 199.232.77.57...
* TCP_NODELAY set
* Connected to www.fastly.com (199.232.77.57) port 443 (#0)
--->{Truncated for readability}<---
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fa15480aa00)
> GET / HTTP/2
> Host: fastly.com
> User-Agent: curl/7.64.1
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 301
< retry-after: 0
< accept-ranges: bytes
< date: Mon, 09 Aug 2021 16:26:07 GMT
< x-served-by: cache-pwk4938-PWK
< x-cache: HIT
< x-cache-hits: 0
< cache-control: max-age=0, private, must-revalidate
< server: Artisanal bits
< strict-transport-security: max-age=31536000
< location: https://www.fastly.com/
< content-length: 0
< 
{ [0 bytes data]
* Connection #0 to host www.fastly.com left intact
* Closing connection 0

Comment utiliser l'option cURL --resolve pour ignorer le DNS

De toutes les options cURL, --resolve est probablement la plus sous-estimée. Cette technique est particulièrement utile pour résoudre les problèmes de routage des requêtes. En ignorant la résolution DNS, vous pouvez tester la réponse d'un serveur d'origine spécifique avant de mettre à jour le DNS public, vérifier un nouveau déploiement ou isoler les problèmes au sein d'une chaîne de proxys et d'équilibreurs de charge. Notez qu'au tout début de chaque commande cURL montrée ci-dessus, vous verrez Trying X.X.X.X comme adresse IP, résolvant le nom de domaine à partir du DNS. Parfois, le nom DNS n'est pas la cible réelle que vous souhaitez atteindre. Il peut s'agir d'un déploiement initial quelque part, et nous vérifions que le service répond correctement avant de changer le DNS pour diffuser ce changement. Il peut aussi exister une chaîne de reverse proxies, dans laquelle le DNS public ne résout qu'au tout début de la chaîne, mais nous voulons savoir comment l'origine elle-même réagit.

Pour contourner ces difficultés, nous pouvons résoudre nous-mêmes le nom de domaine de curl et fournir l’adresse IP de notre choix. Il existe un processus en deux étapes pour y parvenir :

1. Sauf si vous connaissez déjà l’adresse IP à cibler, il peut être nécessaire d’effectuer une résolution DNS de l’hôte pour obtenir l’adresse IP. J’aime utiliser Dig, un autre outil standard qui effectue cette requête DNS depuis la ligne de commande.

$ dig www.fastly.com +short
prod.www-fastly-com.map.fastly.net.
151.101.185.57

2. Ensuite, nous pouvons attribuer cette adresse IP à utiliser par curl lors de la création de la requête HTTP en utilisant l’option --resolve, ainsi que le nom de domaine à remplacer, le port et l’adresse IP à utiliser. En voici le résultat :


$ curl -svo /dev/null https://www.fastly.com/ -H "host: fastly.com" --resolve www.fastly.com:443:151.101.185.57
* Added www.fastly.com:443:151.101.185.57 to DNS cache
* Hostname www.fastly.com was found in DNS cache
*   Trying 151.101.185.57...
* TCP_NODELAY set
* Connected to www.fastly.com (151.101.185.57) port 443 (#0)
--->{Truncated for readability}<---

Alternative connect-to

Comme alternative à la fonction de résolution ci-dessus, vous pouvez également utiliser --connect-to et passer soit une adresse IP, soit un hôte pour vous connecter. C’est une méthode plus facile, mais il y a une mise en garde concernant la précision lors de l’utilisation d’un hôte. Connect-to effectuera une résolution DNS pour vous, mais vous serez ensuite à la merci de cette résolution DNS pour obtenir la bonne adresse IP. Ce n’est pas un problème si vous savez avec certitude qu’il existe une correspondance parfaite entre l’hôte et l’adresse IP. Cependant, il arrive que vous ayez plusieurs enregistrements A et que vous souhaitiez tester toutes les adresses IP. Parfois encore, l’hôte dispose d’un équilibrage de charge basé sur DNS, c’est pourquoi différents emplacements ou différentes tentatives peuvent donner des résultats différents. En utilisant la fonction --resolve ou --connect-to avec une adresse IP, vous pouvez être explicite. Cela signifie qu’un collègue avec qui vous partagez cette commande curl aura plus de chances de reproduire vos résultats.

Un petit avantage de l’utilisation de la fonction connect-to est qu’elle vous permet de ne pas définir explicitement le nom de domaine pour lequel vous cherchez à définir le DNS comme dans resolve, ainsi que le port. Vous verrez donc ::151.101.185.57, mais vous pouvez aussi utiliser ::target.host.fastly.com.

$ curl -svo /dev/null https://www.fastly.com/ -H "host: fastly.com" --connect-to ::151.101.185.57
* Connecting to hostname: 151.101.185.57
*   Trying 151.101.185.57...
* TCP_NODELAY set
* Connected to 151.101.185.57 (151.101.185.57) port 443 (#0)
--->{Truncated for readability}<---

Combiner les options cURL, les en-têtes et le routage

Il est important de souligner qu’il existe de nombreuses techniques pour effectuer une requête HTTP. curl propose différentes méthodes, chacune avec ses avantages et ses inconvénients : chaque utilisateur semble avoir sa propre méthode préférée. Celle-ci, c’est la mienne.

Pour récapituler, cURL peut être utilisé pour envoyer des requêtes HTTP GET, inspecter les en-têtes de requête et de réponse, manipuler les en-têtes d'hôte et ignorer la résolution DNS. En combinant des options telles que `-s`, `-v`, `-H`, `--resolve` et `--connect-to`, vous pouvez déterminer précisément où une requête est envoyée, comment elle est acheminée, quel certificat de sécurité de la couche de transport est présenté et comment un serveur répond. Cela facilite le dépannage et, je l'espère, vous évitera d'innombrables heures de frustration. Essayez-le dès aujourd'hui !

L’extrait ci-dessous présente la forme complète, colorisée pour plus de simplicité :

curl -svo /dev/null https://www.certificate-name.com/path/to/resource/ -H "host: www.expected-host.com" --resolve www.certificate-name.com:443:1.2.3.4

Commencez sans plus attendre et créez l’avenir d’Internet.

Essayez Fastly gratuitement

Prêt à commencer ?

Contactez-nous dès aujourd’hui