Windowsのcurlエスケープ問題

curlに限った問題ではないが、コマンドのエスケープで悩まされてしまった。
発生した問題
Spring BootのAPIに対して、Windows環境のcurlで動作確認をしていたが正しく動かない。同じコマンドをMac環境のcurlで動作確認すると問題なく動作する。利用したコマンドは以下。
curl -X POST http://localhost:8080/path/to/api -H 'Content-Type: application/json' --data '{"name":"gorou"}'
エラーログは以下だった。
Unexpected character ('n'(code 110)): was expecting double-quote to start field name
結論
Windowsのcurlは、ダブルクォーテーションを¥
もしくは""(ダブルクォーテーション2つ)
でエスケープする必要がある。
PowerShellだと以下コマンドで問題なく動く。/path/to/api
はjsonを受け取るAPIとする。
curl -X POST http://localhost:8080/path/to/api -H 'Content-Type: application/json' --data '{¥"name¥":¥"gorou¥"}'
curl -X POST http://localhost:8080/path/to/api -H 'Content-Type: application/json' --data '{"""name""":"""gorou"""}'
ちなみにWindowsのコマンドプロンプトだと、文字列はダブルクォーテーションで括る必要があるので以下になる
curl -X POST http://localhost:8080/path/to/api -H "Content-Type: application/json" --data "{¥"name¥":¥"gorou¥"}"
curlではなくInvoke-WebRequestを使う
PowerShellには、Invoke-WebRequest
コマンドがありcurlのようなコマンドがある。
Invoke-WebRequest
コマンドを利用したほうがエスケープを気にしなくて済むので若干楽である。
Invoke-WebRequest http://localhost:8080/path/to/api -Method "POST" -Headers @{"Content-Type"="application/json"} -Body '{"name":"gorou"}'
PowerShellはjsonへの変換コマンドもあるため、上のように直接jsonを書かなくてもできたりする。
まとめ
今回のcurlのエスケープ問題に直面したときにエラーを調べると出てくる情報として「PowerShellのcurlはInvoke-WebRequestコマンドのエイリアス」という情報が出てきたため、「WindowsとMacのcurlは違うものなのでは」と勘違いしそうになった。
曖昧に放置したくなかったのでしっかり調査するとパラメータのエスケープ不備だった。Windows10からcurlコマンドは標準インストールされているようです(下の参考URLを参照)。
正直なところPostmanを使ったほうが断然楽だと思う。保存できるし編集もしやすい。とはいえかんたんなリクエストはcurlでサクッと動かしたいとは思うので覚えていて損はなさそう。
駄文
3年ぶりくらいにランニングを再開した。著しく体力が落ちた気がしたため。基礎代謝上げていく。ここ半年くらいで子どもたちが自分たちで遊べるようになったため、走ったり新しいことを勉強したり、ブログを書いたりできる様になった。嬉しい。
子育て中の方々、お子様が5歳くらいになるまで自分の時間を確保するのとても厳しいと思うので、振り切って「今しかできない子どもとの遊び」を楽しんだほうがよいと個人的に思います。
参考URL
- How to send double quote in -d parameter for curl.exe? - Local Coder
- curl man page – option -d
- curl/PowerShellでHTTPアクセスいろいろ - Qiita
- curlとInvoke-webRequestコマンドの使い方とオプション比較 - Zenn
- Tar and Curl Come to Windows! - Windows Command Line