¡Esta es una revisión vieja del documento!
Curl
curl significa “cliente para URL”. Es una cliente para lograr transferencias de datos por medio de Internet.
Una transferencia de internet es una carga o descarga empleando un protocolo específico (curl soporta varios de ellos), mientras que su punto final resulta identificado por medio de una URL.
Soporta una gran cantidad de protocolos, desde HTTP, FTP y TELNET a IMAP, LDAP, y GOPHER. Operae en 92 sistemas operativos en cuenta con más de 20 mil millones de instalaciones en todo el mundo. Curl está liberado bajo una licencia MIT ligeramente modificada.
curl comenzó originalmente en 1996 como un proyecto llamado httpget, de Rafael Sagula, quien luego transfirió el control del mismo a Daniel Stenberg. Daniel lo renombró a curl en 1998, y en 2000 dividió la funcionalidad de red de datos para colocarla en la biblioteca libcurl. Por lo cual curl en sí se trasnformó en un envolvedor para la línea de comandos alrededor de dicha biblioteca.
En total, Curl+libcurl cuentan con unas 160.000 líneas de código. Curl se actualiza cada 8 semanas y cuenta con unas 250 versiones (agosto de 2023).
Ciclo de Lanzamientos
Luego del lanzamiento, hay 10 días de espera, seguido por una ventana de 21 días para presentar funcionalidades nuevas, seguidas por un período de congelado de 25 días.
Curl cuenta con una extensa documentación de referencia. Puede verse una versión corta en línea con
curl –help
Para ver la versión completa, puedes probar con curl –manual | less
Opciones de la línea de Comando
Curl se utiliza para realizar transferencias en Internet, donde actúa como cliente, cargando y descargando datos desde un servidor remoto. Los datos pueden ser de cualquier tipo: texto, imágenes, audio, video, etcétera.
Curl soporta tanto protocolos no autenticados (como HTTP o FTP), como sus contrapartes autenticados (como HTTPS o SFTP). Los datos transferidos sobre un protocolo no autenticado pueden ser intereceptados y utilizados, de manera que siempre es mejor usar los autenticados. Curl puede desactivar la verificación de servidor con la opción –insecure, pero es mejor no hacer esto por seguridad.
Curl actualmente cuenta con unas 250 opciones.
Existen versiones cortas (con un guión)
curl -V
…y opciones largas (con guión doble):
curl --version
Todas las opciones están disponibles en el formato “largo”, pero las más usadas son las que usan la versión “corta”.
Opciones de Línea de Comandos
Algunas opciones son del tipo booleano. Podremos activarlas con
curl --silent http://httpbin/uuid
o apagarlas:
curl --no-silent http://httpbin/uuid
Algunas opciones aceptan argumentos
curl --output /tmp/uuid.json http://httpbin/uuid
Los argumentos que contienen espacios deben ir entrecomillados:
curl -o /dev/null --write-out "type: %{content_type}" http://httpbin/uuid
URLs
Curl soporta URLs (en realidad, URIs) de manera similar a lo que define la RFC 3986:
scheme:user:password@host:port/path?query#fragment
scheme defines a protocol (like https or ftp). If omitted, curl will try to guess one.
user and password are authentication credentials (passing credentials in URLs is generally not used anymore for the security reasons).
host is the hostname, domain name or IP address of the server.
port is the port number. If omitted, curl will use the default port associated with the scheme (such as 80 for http or 443 for https).
path is the path to the resource on the server.
query is usually a sequence of name=value pairs separated by &.
Para curl, todo lo que comience con - o – es una opción, y todo lo demás es una URL.
====Solicitud====
Si debemos pasar un montón de parámetros de URL, la parte de la solicitud puede ser bastante larga. La opción –url-query permite especificar las partes a solicitar de forma separada:
<code bash>
curl http://httpbin/get –url-query “name=Alice” –url-query “age=25”
</code>
====URL Múltiples====
Curl acepta cualquier número de URLs, cada una de las cuales requiere un destino (ya sea un fichero o stdout). Por ejemplo, este comando guardará la primer UUID en /tmp/uuid1.json y la segunda UUID como /tmp/uuid.json:
<code bash>
curl
-o /tmp/uuid1.json http://httpbin/uuid
-o /tmp/uuid2.json http://httpbin/uuid
&& cat /tmp/uuid1.json
&& cat /tmp/uuid2.json
</code>
(de aquí en mas, en ocasiones mostraré comandos multilíoneas a modo ilustrativo. En realidad curl espera una única línea o a lo sumo líneas divididas conm \)
La opción -O deriva el nombre de fichero desde la URL:
<code bash>
curl –output-dir /tmp
-O http://httpbin/anything/one
-O http://httpbin/anything/two
&& ls /tmp
</code>
Para guardar ambas respuestas en el mismo fichero, podemos usar la redirección:
<code bash>
curl http://httpbin/uuid http://httpbin/uuid > /tmp/uuid.json
&& cat /tmp/uuid.json
</code>
===Englobado de URL===
Curl expande automáticamente las expresiones englobadas en URLs a múltiples URLs específicas.
Pore ejemplo, este comando solicita tres rutas distintas (al, bt, gm), cada una con dos parámetros distintos (num=1 y num=2), para totalizar seis URLs:
<code bash>
curl –output-dir /tmp -o “salida_#1_#2.txt”
http://httpbin/anything/{al,bt,gm}?num=[1-2]
&& ls /tmp
</code>
Podremos desactivar el englobado si usamos la opción –globoff si existen caracteres válidos []{} en las URLs indicadas. Luego Curl los tratará de manera literal.
====Transferencias en paralelo====
Es posible usar –parallel (-Z) para indicarle a Curl procesar las URLs de forma concurrente.
====Fichero de Configuración====
En la medida que se incrementa el número de opciones, el comando Curl se volverá más difícil de descifrar. Para hacerlo más legible, podremos preparar un fichero de configuración que liste una opción por línea (el – es opcional):
Config file
output-dir /tmp
show-error
silent
Por defecto, Curl lee el fichero de configuración desde $HOME/.curlrc, pero puede cambiar esto indicándolo con la opción –config (-K):
<code bash>
curl –config /sandbox/.curlrc http://httpbin/uuid
</code>
====Medidores de Progreso====
Curl cuenta con dos medidores de progreso. Por defecto es verboso:
<code bash>
curl –no-silent http://httpbin/uuid
</code>
El otro es compacto:
<code bash>
curl –no-silent –progress-bar http://httpbin/uuid
</code>
La opción –silent apaga completamente el medidor:
<code bash>
curl –silent http://httpbin/uuid
</code>
====Reseteo de estado====
Cuando configuras opciones, se aplican a todas las URLs que procesa Curl. Por ejemplo, aquí ambos encabezados se envían a ambas URLs:
<code bash>
curl
-H “x-num: one” http://httpbin/headers?1
-H “x-num: two” http://httpbin/headers?2
</code>
A veces esto no es lo que se desea. Para resetear el estado entre las llamadas a URLS, se usa la opción –next:
<code bash>
curl
-H “x-num: one” http://httpbin/headers?1
–next
-H “x-num: two” http://httpbin/headers?2
</code>
====Curl Básico====
Ahora que entendemos cómo funciona Curl y sus opciones, podremos ver sus opciones específicas.
–version (-V) explica todo sobre la versión instalada de curl:
<code bash>
curl -V
</code>
Lista linea a línea las versiones de Curl en sí y sus dependencias, la fecha de lanzamiento, los protocolos disponibles, y las características activadas.
–verbose (-v) hace que Curl sea verboso, lo que puede ser útil en depuración:
<code bash>
curl -v http://httpbin/uuid
</code>
Si –verbose es insuficiente podrías intentar con –trace (el - envía la salida de trace a stdout):
<code bash>
curl –trace - http://httpbin/uuid
</code>
o bien –trace-ascii:
</code bash>
curl –trace-ascii - http://httpbin/uuid
</code>
Usa –write-out (-w) para extraer información específica sobre la respuestas. Soporta más de 50 variables. Por ejemplo, aquí extraemos el código de status y la respuesta del tipo de contenido:
<code bash>
curl
-w “\nstatus: %{response_code}\ntype: %{content_type}”
http://httpbin/status/429
</code>
…o algunos encabezados de la respuesta:
<code bash>
curl
-w “\ndate: %header{date}\nlength: %header{content-length}”
http://httpbin/status/429
</code>
====Descargas====
–remote-name (-O) le dice a curl que guarde la salida a un fichero especificado por la URL, (específicamente, por la parte que sigue a la última / de ésta). A menudo se usa en conjunto con –output-dir, lo que le dice a Curl donde poner exactamente el fichero a guardar:
<code bash>
curl –output-dir /tmp -O http://httpbin/uuid
&& cat /tmp/uuid
</code>
Si dicho directorio fuese inexistente, –output-dir no lo creará por tí. Usa –create-dirs para que esto suceda:
<code bash>
curl –output-dir /tmp/alguna/ruta –create-dirs
-O http://httpbin/uuid
&& cat /tmp/some/place/uuid
</code>
Puedes usar –max-filesize (en bytes) para limitar el tamaño de respuesta permitido, pero a menudo no lo sabe por adelantado, de modo que podría fallar.
====Reintentar====
A veces puede que el huésped remoto no esté disponible. Para hacer caso a estas situaciones, Curl provee la opción –retry [num]. Si la solicitud falla, Curl reintentará pero no más de la cantidad de veces indicada num:
<code bash>
curl -i –retry 3 http://httpbin/unstable
</code>
(esta URL falla el 50% de las veces)
Podrás indicar la cantidad máxima de tiempo con la que Curl reintentará la solicitud con la opción –retry-max-time (en segundos) o el retrato entre reintentos con –retry-delay (también en segundos):
<code bash>
curl -i –retry 3 http://httpbin/unstable
–retry-max-time 2
–retry-delay 1
</code>
Para Curl, “request failed” significa alguno de los códigos HHTP: 408, 429, 500, 502, 503 o 504. Si la solicitud falla con un error de “connection refused”, Curl no reintentará. Pero puede cambiarse esto con –retry-connrefused, o incluso activar los reintentos para todo tipo de problemas con –retry-all-errors.
====Subidas====
Curl a menudo se usa para bajar información (descargar) del servidor, pero también puede subirla. Para ello use la opción –upload-file (-T):
<code bash>
echo hola > /tmp/hola.txt &&
curl -T /tmp/hola.txt http://httpbin/put
</code>
Para cargas HTTP, Curl usa el método PUT.
===Controles de Transferencia===
Para detener descargas lentas, configure la velocidad de descarga mínima permitida (en bytes por segundo) con –speed-limit. Por defecto, Curl revisa la velocidad en intervalos de 30 segunods, pero esto puede cambiarse con –speed-time.
Por ejemplo, para permitir no menos de 10 bytes/segundo durante un intervalo de 3 segundos:
<code bash>
curl -v –speed-limit 10 –speed-time 3 http://httpbin/get
</code>
Para limitar el uso de ancho de banda, utilice –limit-rate. Acepta cualquier cantidad, desde bytes a petabytes:
<code bash>
curl –limit-rate 3 http://httpbin/get
curl –limit-rate 3k http://httpbin/get
curl –limit-rate 3m http://httpbin/get
curl –limit-rate 3g http://httpbin/get
curl –limit-rate 3t http://httpbin/get
curl –limit-rate 3p http://httpbin/get
</code>
Otra cosa para limitar es el número de solicitudes concurrentes (ej, si descargas muchos ficheros). Usa –rate para tal cosa. Acepta segundos, minutos, horas o días:
<code bash>
curl –rate 3/s http://httpbin/anything/[1-9].txt
curl –rate 3/m http://httpbin/anything/[1-9].txt
curl –rate 3/h http://httpbin/anything/[1-9].txt
curl –rate 3/d http://httpbin/anything/[1-9].txt
</code>
===Resolución de nombre===
Por defecto, curl usa tu servidor DNS para resolver los nombres de host a direcciones IP. Pero puedes forzarlo a resolver una IP específica con –resolve:
<code bash>
curl –resolve httpbingo.org:8080:127.0.0.1
http://httpbingo.org:8080/get</code>
(este falla porque nadie escucha en 127.0.0.1)
O puedes incluso mapear un par hostname:puerto a otro par hostname:puerto con –connect-to:
<code bash>
curl –connect-to httpbingo.org:8080:httpbin:80
http://httpbingo.org:8080/get
</code>
(este funcionará bien)
====Opciones a nivel conexión====
También existen configuraciones a nivel conexión.
===timeouts===
Para limitar la cantidad de tiempo que curl se pasa interactuando con una única URL, usa –max-time (en fraccionales de segundo):
<code bash>curl –max-time 0.5 http:/httpbin/delay/1</code>
(este falla)
En lugar de limitar el tiempo total, puedes usar –connect-timeout para limitar sólo el tiempo que toma establecer la conexión en la red:
<code bash>curl –connect-timeout 0.5 http:/httpbin/delay/1</code>
(este funciona bien)
===Credentiales===
Casi nunca querrás pasar nombre de usuario y contraseña en el comando de curl en s{i. Una forma de evitarlo es usar el fichero ~/netrc. Especifica los nombres de host y credenciales para accederlos:
<code>
machine httpbin
login pedro
password chori
machine ejemplo.com
login pablo
password pan
</code>
Pasa la opción –netrc para usar el fichero $HOME/.netrc, o –netrc-file para usar uno específico:
<code bash>echo -e “machine httpbin\nlogin alice\npassword cheese” > /tmp/netrc &&
curl –netrc-file /tmp/netrc
http://httpbin/basic-auth/alice/cheese
</code>
