Pasar una URL con corchetes para curl
Si intento pasar una URL a curl que contiene corchetes, falla y aparece un error:
$ curl 'http://www.google.com/?TEST[]=1'
curl: (3) [globbing] illegal character in range specification at pos 29
Sin embargo, si escapo de ambos corchetes, parece funcionar:
$ curl 'http://www.google.com/?TEST\[\]=1'
¿Cómo puedo solucionar esto? ¿Existe algún argumento que escape las URL automáticamente o una descripción de los caracteres que deben escaparse antes de pasar a curl?
Agregue -g
a su comando:
-g, --globoff
This option switches off the "URL globbing parser". When you set this option, you can
specify URLs that contain the letters {}[] without having curl itself interpret them.
Note that these letters are not normal legal URL contents but they should be encoded
according to the URI standard.
Example:
curl -g "https://example.com/{[]}}}}"
curl.se/docs/manpage.html#-g
El globbing utiliza corchetes, de ahí la necesidad de escapar de ellos con una barra \
. Alternativamente, el siguiente modificador de línea de comando deshabilitará el globbing:
--globoff
(o la versión de opción corta -g
:)
Ex:
curl --globoff https://www.google.com?test[]=1
En la documentación está escrito:
letras globosas
La herramienta de línea de comando curl admite la "globbing" de URL. Significa que puedes crear rangos y listas usando secuencias [NM] y {uno,dos,tres}. Las letras utilizadas para esto ([]{}) están reservadas en RFC 3986 y, por lo tanto, no pueden formar parte legítimamente de dicha URL.
Sin embargo, no están reservados ni son especiales en la especificación WHATWG, por lo que el globbing puede estropear dichas URL. El globbing se puede desactivar en tales ocasiones (usando --globoff).
Significa que debe realizar una codificación porcentual para los caracteres reservados/especiales ( :/?#[]@!$&'()*+,;=
) para evitar su interpretación especial. Para hacerlo, coloque el signo de porcentaje ( %
) y el valor hexadecimal del carácter en la tabla ASCII . Por ejemplo:
Símbolo | Valor codificado |
---|---|
[ |
%5B |
] |
%5D |
{ |
%7B |
} |
%7D |
curl
no espera caracteres reservados/especiales en la URL y estos cuatro símbolos se utilizan para generar múltiples URL ( operación global ):
$ curl http://localhost:8080/?TEST[a-c]=1
será equivalente a
$ curl http://localhost:8080/?TESTa=1
$ curl http://localhost:8080/?TESTb=1
$ curl http://localhost:8080/?TESTc=1
y
$ curl http://localhost:8080/?TEST{a,c,e}=1
será equivalente a
$ curl http://localhost:8080/?TESTa=1
$ curl http://localhost:8080/?TESTc=1
$ curl http://localhost:8080/?TESTe=1
Si desea desactivar la operación global:
codificarlos:
$ curl http://localhost:8080/?TEST%5Ba-c%5D=1 $ curl http://localhost:8080/?TEST%7Ba,c,e%7d=1
Para (shell predeterminado en Mac OS X) también
zsh
debes escapar .?
Así, tanto parabash
laszsh
conchas como:$ curl http://localhost:8080/\?TEST%5Ba-c%5D=1 $ curl http://localhost:8080/\?TEST%7Ba,c,e%7d=1
o usar
-g
/--globoff
opción:$ curl -g http://localhost:8080/?TEST[a-c]=1 $ curl -g http://localhost:8080/?TEST{a,c,e}=1 # not enough, see note below
☝ En el último ejemplo hay una advertencia: el globbing puede realizarse mediante
bash
yzsh
shell. Para evitar el globbing por shell:ya sea caracteres de escape poniendo barra invertida (
\
) (no se olvide de escapar?
parazsh
shell):$ curl -g http://localhost:8080/\?TEST\[a-c\]=1 $ curl -g http://localhost:8080/\?TEST\{a,c,e\}=1
o poner la URL entre comillas (simples o dobles):
$ curl -g 'http://localhost:8080/?TEST[a-c]=1' $ curl -g 'http://localhost:8080/?TEST{a,c,e}=1'
☝ También tenga en cuenta que los corchetes vacíos ( []
) no llevan a incluir curl
:
$ curl 'http://localhost:8080/?TEST[]=1'
solicitará /?TEST[]=1
.
Esto no es cierto para las llaves vacías ( {}
):
$ curl 'http://localhost:8080/?TEST{}=1'
curl: (3) empty string within braces in URL position 29:
http://localhost:8080/?TEST{}=1
^
deben contener al menos una cadena.
PD: Puedes realizar la prueba docker
(presiona Ctrl+C
para salir):
$ docker run --rm -p 8080:80 -it nginx
y ejecutarlo curl
en una terminal separada:
$ curl http://localhost:8080/?TEST[a-c]=1
En los registros debería ver generar URL para solicitud:
172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTa=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"
172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTb=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"
172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTc=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"
Ninguna de las respuestas anteriores funcionó para mí, tengo que reemplazar todos los corchetes de apertura/cierre con %5B
y %5D
.
[ ---> %5B
y para
] ---> %5D
Mi URL inicial de curl era así
https://test.com/computer/agent1/api/json?pretty=true&tree=executors[currentExecutable[url]]
Ahora estoy usando así
https://test.com/computer/agent1/api/json?pretty=true&tree=executors%5BcurrentExecutable%5Burl%5D%5D
Recibí este error aunque no había corchetes (obvios) en mi URL y, en mi situación, el comando --globoff no resolverá el problema.
Por ejemplo (haciendo esto en mac en iTerm2):
for endpoint in $(grep some_string output.txt); do curl "http://1.2.3.4/api/v1/${endpoint}" ; done
Tengo grep con el alias "grep --color=always". Como resultado, el comando anterior generará este error, con some_string resaltado en cualquier color en el que haya configurado grep:
curl: (3) bad range in URL position 31:
http://1.2.3.4/api/v1/lalalasome_stringlalala
El terminal estaba traduciendo de forma transparente [color\códigos]alguna_cadena[color\códigos] a la URL esperada sin caracteres especiales cuando se veía en el terminal, pero detrás de escena los códigos de color se enviaban en la URL pasada a curl, lo que resultaba en corchetes en su URL.
La solución es no utilizar resaltado de coincidencias.