Powershell の curl でHTTPリクエストをしてみる(GET/POST/PUT/DELETE)

先日WindowsでもLinuxコマンドが使用できることを知りました。今回はこれを活用する方法を記事にします。WindowsのPowersellからcurlコマンドで HTTPリクエストをしてみます。

Powershell で curl、ls、crontab が使えるか
私はプロジェクトではアプリを担当することが多いのですが、今回のプロジェクトではインフラを担当することになりました。 管理ターゲットのO...

これにより、コマンドでHTTPリクエストを投げることが出来ます。ブラウザよりもコマンドの方が動作が軽快ですし、ブラウザから実施することが出来るHTTPリクエストはGETだけですので有用ですね。実際にcurlを使ってHTTPリクエストを投げてみます。宛先はGoogleにしてみます。

Googleへ

GET

> curl https://www.google.com/

StatusCode        : 200
StatusDescription : OK
Content           : <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="世界中のあらゆる情報を検索するためのツールを提供しています。
                    さまざまな検索機能を活用して、お探しの情報を見つけてください。" name="description"><meta content="n...
RawContent        : HTTP/1.1 200 OK
                    X-XSS-Protection: 1; mode=block
                    X-Frame-Options: SAMEORIGIN
                    Cache-Control: private, max-age=0
                    Content-Type: text/html; charset=UTF-8
                    Date: Sat, 13 Oct 2018 14:27:38 GMT
                    Expires: ...
Forms             : {f}
Headers           : {[X-XSS-Protection, 1; mode=block], [X-Frame-Options, SAMEORIGIN], [Cache-Control, private, max-age=0], [Content-Type, text/html; charset=UTF-8]...}
Images            : {@{innerHTML=; innerText=; outerHTML=<IMG id=hplogo onload=window.lol&amp;&amp;lol() style="PADDING-BOTTOM: 14px; PADDING-TOP: 28px; PADDING-LEFT: 0px; PADDING-RI
                    GHT: 0px" alt=Google src="/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png" width=272 height=92>; outerText=; tagName=IMG; id=hplogo;
                     onload=window.lol&amp;&amp;lol(); style=PADDING-BOTTOM: 14px; PADDING-TOP: 28px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; alt=Google; src=/images/branding/googlelo
                    go/1x/googlelogo_white_background_color_272x92dp.png; width=272; height=92}}
InputFields       : {@{innerHTML=; innerText=; outerHTML=<INPUT type=hidden value=ja name=hl>; outerText=; tagName=INPUT; type=hidden; value=ja; name=hl}, @{innerHTML=; innerText=; o
                    uterHTML=<INPUT type=hidden value=hp name=source>; outerText=; tagName=INPUT; type=hidden; value=hp; name=source}, @{innerHTML=; innerText=; outerHTML=<INPUT type
                    =hidden name=biw>; outerText=; tagName=INPUT; type=hidden; name=biw}, @{innerHTML=; innerText=; outerHTML=<INPUT type=hidden name=bih>; outerText=; tagName=INPUT;
                     type=hidden; name=bih}...}
Links             : {@{innerHTML=<SPAN class=gbtb2></SPAN><SPAN class=gbts>検索</SPAN>; innerText=検索; outerHTML=<A onclick=gbar.logger.il(1,{t:1}); id=gb_1 class="gbzt gbz0l gbp1"
                    href="https://www.google.co.jp/webhp?tab=ww"><SPAN class=gbtb2></SPAN><SPAN class=gbts>検索</SPAN></A>; outerText=検索; tagName=A; onclick=gbar.logger.il(1,{t:1})
                    ;; id=gb_1; class=gbzt gbz0l gbp1; href=https://www.google.co.jp/webhp?tab=ww}, @{innerHTML=<SPAN class=gbtb2></SPAN><SPAN class=gbts>画像</SPAN>; innerText=画像;
                     outerHTML=<A onclick=gbar.logger.il(1,{t:2}); id=gb_2 class=gbzt href="https://www.google.co.jp/imghp?hl=ja&amp;tab=wi"><SPAN class=gbtb2></SPAN><SPAN class=gbts
                    >画像</SPAN></A>; outerText=画像; tagName=A; onclick=gbar.logger.il(1,{t:2});; id=gb_2; class=gbzt; href=https://www.google.co.jp/imghp?hl=ja&amp;tab=wi}, @{inner
                    HTML=<SPAN class=gbtb2></SPAN><SPAN class=gbts>マップ</SPAN>; innerText=マップ; outerHTML=<A onclick=gbar.logger.il(1,{t:8}); id=gb_8 class=gbzt href="https://map
                    s.google.co.jp/maps?hl=ja&amp;tab=wl"><SPAN class=gbtb2></SPAN><SPAN class=gbts>マップ</SPAN></A>; outerText=マップ; tagName=A; onclick=gbar.logger.il(1,{t:8});;
                    id=gb_8; class=gbzt; href=https://maps.google.co.jp/maps?hl=ja&amp;tab=wl}, @{innerHTML=<SPAN class=gbtb2></SPAN><SPAN class=gbts>Play</SPAN>; innerText=Play; out
                    erHTML=<A onclick=gbar.logger.il(1,{t:78}); id=gb_78 class=gbzt href="https://play.google.com/?hl=ja&amp;tab=w8"><SPAN class=gbtb2></SPAN><SPAN class=gbts>Play</S
                    PAN></A>; outerText=Play; tagName=A; onclick=gbar.logger.il(1,{t:78});; id=gb_78; class=gbzt; href=https://play.google.com/?hl=ja&amp;tab=w8}...}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 47156

Status Code : 200 が返却されその他詳細にいついても返却されることが確認できましたね。しかし、非常に見ずらいですしContentが省略されていますね。Powersellのcurlは簡易的にStatus Codeを確認するために使用するにとどめる方が良さそうです。

簡易的に疎通確認を出来るだけでも有用です。疎通確認などは開発(try)と試験(error)を繰り返すことが多いので、手軽に実行できることが重要です。

自作のテストサービスへ

上記ではGoogleに対してGETでHTTPリクエストを送りました。その他のHTTPリクエストもPowersellのcurlコマンドで送ることが出来るか実験してます。

SpringBootの@RestControllerでGET/POST/PUT/DELETEのHTTPリクエストを受け付ける簡易なサービスを作成しましたので、そのサービスに向けてPowersellのcurlコマンドでHTTPリクエストを投げてみます。

GET

いざ実験。まずはGET

> curl http://localhost:8080

StatusCode        : 200
StatusDescription :
Content           : Hello HttpRequest GET
RawContent        : HTTP/1.1 200
                    Content-Length: 21
                    Content-Type: text/plain;charset=UTF-8
                    Date: Sun, 14 Oct 2018 07:04:55 GMT
                    Hello HttpRequest GET
Forms             : {}
Headers           : {[Content-Length, 21], [Content-Type, text/plain;charset=UTF-8], [Date, Sun, 14 Oct 2018 07:04:55 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 21

無事にできました。

POST

続いてPOST

> curl -X POST http://localhost:8080/
Invoke-WebRequest : パラメーター名 'X' に一致するパラメーターが見つかりません。
発生場所 行:1 文字:6
+ curl -X POST http://localhost:8080/
+      ~~
    + CategoryInfo          : InvalidArgument: (:) [Invoke-WebRequest]、ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

出来ませんね。エラー内容を見てみると使用していないはずのInvoke-WebRequestの文字があります。なぜだろうと調査してみるとAliasで内部的に処理しているようでした。

> Get-Alias curl

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           curl -> Invoke-WebRequest

なのでPowershellでは、Invoke-WebRequestの引数を指定してcurlを使うと上手くいきそうです。再度POSTの実験をしてみます。

> curl -Method POST http://localhost:8080


StatusCode        : 200
StatusDescription :
Content           : Hello HttpRequest POST
RawContent        : HTTP/1.1 200
                    Content-Length: 22
                    Content-Type: text/plain;charset=UTF-8
                    Date: Sun, 14 Oct 2018 06:48:27 GMT

                    Hello HttpRequest POST
Forms             : {}
Headers           : {[Content-Length, 22], [Content-Type, text/plain;charset=UTF-8], [Date, Sun, 14 Oct 2018 06:48:27 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 22

出来ました。

PUT

続いて、PUT/DELETEと続けていきます。

> curl -Method PUT http://localhost:8080


StatusCode        : 200
StatusDescription :
Content           : Hello HttpRequest PUT
RawContent        : HTTP/1.1 200
                    Content-Length: 21
                    Content-Type: text/plain;charset=UTF-8
                    Date: Sun, 14 Oct 2018 06:47:42 GMT

                    Hello HttpRequest PUT
Forms             : {}
Headers           : {[Content-Length, 21], [Content-Type, text/plain;charset=UTF-8], [Date, Sun, 14 Oct 2018 06:47:42 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 21

DELETE

> curl -Method DELETE http://localhost:8080


StatusCode        : 200
StatusDescription :
Content           : Hello HttpRequest DELETE
RawContent        : HTTP/1.1 200
                    Content-Length: 24
                    Content-Type: text/plain;charset=UTF-8
                    Date: Sun, 14 Oct 2018 06:48:10 GMT

                    Hello HttpRequest DELETE
Forms             : {}
Headers           : {[Content-Length, 24], [Content-Type, text/plain;charset=UTF-8], [Date, Sun, 14 Oct 2018 06:48:10 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 24

出来ました。

以上、Powershell’s curlでHTTPリクエストをしてみるでした。