Передача 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.

Решение состоит в том, чтобы не использовать подсветку совпадений.

Другие вопросы по тегам