Передача URL в квадратных скобках для скручивания
Если я пытаюсь передать URL в curl, который содержит квадратные скобки, произойдет сбой с ошибкой:
$ curl 'http://www.google.com/?TEST[]=1'
curl: (3) [globbing] illegal character in range specification at pos 29
Тем не менее, если я уберу обе скобки, это будет работать:
$ curl 'http://www.google.com/?TEST\[\]=1'
Интересно, что я использую обратную косую черту, чтобы экранировать только первую скобку, которую он молча завершает с кодом ошибки 20497:
$ curl 'http://www.google.com/?TEST\[]=1'
$ echo $!
20497
Мой вопрос, как это исправить в общих случаях? Есть ли аргумент, который будет автоматически экранировать URL-адреса, или описание символов, которые должны быть экранированы перед переходом к curl?
5 ответов
Неважно, я нашел это в документах:
-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 them being interpreted by curl
itself. Note that these letters are not normal legal URL contents but they should be
encoded according to the URI standard.
В Globbing используются скобки, поэтому их нужно экранировать с помощью косой черты.\
. В качестве альтернативы следующий переключатель командной строки отключит подстановку:
--globoff
(или версия с коротким вариантом: -g
)
Пример:
curl --globoff https://www.google.com?test[]=1
В документации написано:
круглые буквы
Инструмент командной строки curl поддерживает «подстановку» URL-адресов. Это означает, что вы можете создавать диапазоны и списки, используя последовательности [NM] и {one,two,three}. Буквы, используемые для этого ([]{}), зарезервированы в RFC 3986 и поэтому не могут законно быть частью такого URL.
Однако они не являются зарезервированными или специальными в спецификации WHATWG, поэтому подстановка может испортить такие URL-адреса. Для таких случаев подстановку можно отключить (используя --globoff).
Это означает, что вы должны использовать процентное кодирование для зарезервированных/специальных символов (:/?#[]@!$&'()*+,;=
), чтобы избежать их специальной интерпретации. Для этого ставится знак процента (%
) и шестнадцатеричное значение символа в таблице ASCII . Например:
не ожидает зарезервированных/специальных символов в URL-адресе, и эти четыре символа используются для создания нескольких URL-адресов ( операция подстановки ):
будет эквивалентно
$ curl http://localhost:8080/?TESTa=1
$ curl http://localhost:8080/?TESTb=1
$ curl http://localhost:8080/?TESTc=1
и
$ curl http://localhost:8080/?TEST{a,c,e}=1
будет эквивалентно
$ curl http://localhost:8080/?TESTa=1
$ curl http://localhost:8080/?TESTc=1
$ curl http://localhost:8080/?TESTe=1
Если вы хотите отключить операцию подстановки:
закодировать их:
$ curl http://localhost:8080/?TEST%5Ba-c%5D=1 $ curl http://localhost:8080/?TEST%7Ba,c,e%7d=1
Для (оболочка по умолчанию в Mac OS X) вы также должны выйти. Таким образом, для обоих и оболочек:
$ curl http://localhost:8080/\?TEST%5Ba-c%5D=1 $ curl http://localhost:8080/\?TEST%7Ba,c,e%7d=1
или использовать
-g
/--globoff
вариант:$ curl -g http://localhost:8080/?TEST[a-c]=1 $ curl -g http://localhost:8080/?TEST{a,c,e}=1 # not enough, see note below
☝ В последнем примере есть оговорка: подстановку можно выполнить
bash
и оболочка. Чтобы избежать подстановки оболочкой:либо escape-символы, ставящие обратную косую черту (
\
) (не забудьте об экранировании?
дляzsh
оболочка):$ curl -g http://localhost:8080/\?TEST\[a-c\]=1 $ curl -g http://localhost:8080/\?TEST\{a,c,e\}=1
или поместите URL в кавычки (одинарные или двойные):
$ curl -g 'http://localhost:8080/?TEST[a-c]=1' $ curl -g 'http://localhost:8080/?TEST{a,c,e}=1'
☝ Также имейте в виду, что пустые квадратные скобки ([]
) не приводит к подстановке:
$ curl 'http://localhost:8080/?TEST[]=1'
запросит/?TEST[]=1
.
Это неверно для пустых фигурных скобок ({}
):
$ curl 'http://localhost:8080/?TEST{}=1'
curl: (3) empty string within braces in URL position 29:
http://localhost:8080/?TEST{}=1
^
они должны содержать хотя бы одну строку.
PS Вы можете проверить наdocker
(нажиматьCtrl+C
бросить):
$ docker run --rm -p 8080:80 -it nginx
и бегиcurl
против него в отдельном терминале:
$ curl http://localhost:8080/?TEST[a-c]=1
В логах вы должны увидеть URL генерации для запроса:
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" "-"
Ни один из приведенных выше ответов не помог мне, я должен заменить все открывающие/закрывающие скобки на
%5B
а также
%5D
.
[ ---> %5B
и для
] ---> %5D
Мой первоначальный URL-адрес завитка был таким
https://test.com/computer/agent1/api/json?pretty=true&tree=executors[currentExecutable[url]]
Сейчас пользуюсь таким
https://test.com/computer/agent1/api/json?pretty=true&tree=executors%5BcurrentExecutable%5Burl%5D%5D
Я получал эту ошибку, хотя в моем URL-адресе не было (очевидных) квадратных скобок, и в моей ситуации команда --globoff не решит проблему.
Например (делая это на Mac в iTerm2):
for endpoint in $(grep some_string output.txt); do curl "http://1.2.3.4/api/v1/${endpoint}" ; done
У меня есть псевдоним grep "grep --color=always". В результате приведенная выше команда приведет к этой ошибке, при этом some_string будет выделена любым цветом, который вы установили для grep:
curl: (3) bad range in URL position 31:
http://1.2.3.4/api/v1/lalalasome_stringlalala
Терминал прозрачно переводил [color\codes]some_string[color\codes] в ожидаемый URL-адрес без специальных символов при просмотре в терминале, но за кулисами коды цветов отправлялись в URL-адресе, переданном curl, что приводило к скобки в вашем URL.
Решение состоит в том, чтобы не использовать подсветку совпадений.