0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WordPress.org の Plugin API を curl で叩くと「bad range in URL」になります。角かっこを、zsh と curl の両方が読んでいました【実測】

0
Posted at

WordPress.org の Plugin API は、request[slug]= のように、URL のクエリに角かっこを使います。この URL を curl にそのまま渡すと、シェルと curl のどちらかが角かっこを読んでしまい、リクエストが届かないか、届いても中身が足りなくなります。

curl 8.5.0、zsh 5.9、bash 5.2 で、手元に立てた HTTP サーバーに向けて試しました。サーバーのログで、実際に届いたリクエストも見ています。

書き方 zsh bash
URL を引用符で囲まない no matches found で、curl が動かない curl が bad range in URL で止まる
引用符で囲まない、& を含む URL 上と同じ & から後ろが届かない。エラーも出ない
引用符で囲む curl が bad range in URL で止まる 同じ
引用符で囲み、curl -g 届く 届く
角かっこを %5B %5D にする 届く 届く

引用符で囲むと、シェルの問題は消えます。それでも curl が角かっこを読むので、-g か、角かっこのエンコードが要ります。

先に断っておくと、zsh が一致するファイルのないグロブをエラーにすること(NOMATCH)も、curl が URL の [ ] と { } を範囲指定として読み、-g(--globoff)で止められることも、それぞれのマニュアルに書かれています。ここで書くのは、WordPress.org の API の URL で、その2つが重なったときに何が起きるかを、1つずつ確かめた結果です。

zsh:curl が動く前に止まる

zsh は、? と [slug] をファイル名のパターンとして読みます。一致するファイルがないので、curl を動かす前にエラーにします。

$ curl -s http://127.0.0.1:18900/x?request[slug]=a
zsh:1: no matches found: http://127.0.0.1:18900/x?request[slug]=a

URL に & が入っていると、そこでコマンドが切れて、後ろの request[slug]=rapls-sitemap を変数への代入として読もうとし、もう1つエラーが出ました。

zsh:1: no matches found: http://127.0.0.1:18900/plugins/info/1.2/?action=plugin_information
zsh:1: request: assignment to invalid subscript range

bash:エラーなしで、半分だけ届く

bash は、一致するファイルがないパターンを、そのまま残して渡します。& を含まない URL なら、curl まで届いて、curl のほうで止まります(次の節)。

困るのは、& を含む URL です。

curl -sS -o /dev/null http://127.0.0.1:18902/plugins/info/1.2/?action=plugin_information&request[slug]=rapls-sitemap

bash は & でコマンドを切り、curl を後ろで動かします。サーバーに届いたのは、& の手前まででした。

"GET /plugins/info/1.2/?action=plugin_information HTTP/1.1"

request[slug]=rapls-sitemap のほうは、bash の配列への代入として、黙って実行されていました。

$ declare -p request
declare -a request=([0]="rapls-sitemap")

エラーは1行も出ません。API には、どのプラグインかを伝える slug が届いていないので、返ってくる中身は、頼んだものとは別物になります。

curl:引用符で囲んでも止まる

URL を引用符で囲めば、シェルは角かっこにも & にも触りません。それでも、今度は curl が [slug] を範囲指定([1-10] のような)として読み、止まります。

$ curl -sS -o /dev/null 'http://127.0.0.1:18900/plugins/info/1.2/?action=plugin_information&request[slug]=rapls-sitemap'
curl: (3) bad range in URL position 76:
http://127.0.0.1:18900/plugins/info/1.2/?action=plugin_information&request[slug]=rapls-sitemap
                                                                           ^

-s だけを付けていると、このエラーも表示されず、終了コード 3 で終わるだけです。-sS にしておくと、エラーだけは表示されます。

zsh の noglob を前に付けても、シェルの展開が止まるだけで、curl のほうは同じエラーでした。

届く書き方

引用符で囲んで、-g を付けます。

curl -g -sS 'https://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request[slug]=rapls-sitemap'

角かっこをエンコードしても届きます。

curl -sS 'https://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request%5Bslug%5D=rapls-sitemap'

-G と --data-urlencode でクエリを組み立てる方法もあります。この場合、curl は渡したデータを範囲指定として読まないので、角かっこはそのまま届きました。

curl -sS -G https://api.wordpress.org/plugins/info/1.2/ \
  --data-urlencode 'action=plugin_information' \
  --data-urlencode 'request[slug]=rapls-sitemap'

サーバーのログでは、-g を付けた書き方で、&request[slug]=rapls-sitemap まで届いていました。

"GET /plugins/info/1.2/?action=plugin_information&request[slug]=rapls-sitemap HTTP/1.1"

角かっこの入った URL を curl に渡すとき

  • URL は、必ず引用符で囲む。zsh はエラーで止まり、bash は & で黙って切る
  • 引用符で囲んでも、curl が [ ] を範囲指定として読む。-g を付けるか、%5B %5D にする
  • -s だけだと、curl のエラーが見えない。-sS にする
  • クエリが長いなら、-G と --data-urlencode で組み立てる

あなたのスクリプトの curl は、角かっこの入った URL を、どの書き方で渡していますか。

手元で試すコマンド

Python の HTTP サーバーを立てて、届いたリクエストをログで見ます。

python3 -m http.server 18902 > hs.log 2>&1 &
bash -c 'curl -sS -o /dev/null http://127.0.0.1:18902/plugins/info/1.2/?action=plugin_information&request[slug]=rapls-sitemap; sleep 1'
curl -g -sS -o /dev/null 'http://127.0.0.1:18902/plugins/info/1.2/?action=plugin_information&request[slug]=rapls-sitemap'
grep GET hs.log

ふだんはraplsworks.comで、WordPressプラグイン開発やClaude Codeまわりのことを書いています。
https://raplsworks.com/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?