よくわからなくなるのでメモ
- curl
- 主に7.3で確認
- PowerShell
- 主にversion5(Windows10)で確認 (Windows7標準のver2はInvoke-WebRequestはない)
更新履歴
- 2019.02.13: リダイレクトについて追加
- 2019.02.08: 暗号化プロトコルの指定について追記
- 2018.09.26: HTTPS通信時の証明書の検証を無視する場合を追加
GETする(基本)
- curl
curl https://www.google.com
- PowerShell
Invoke-WebRequest https://www.google.com
GETの結果をファイル出力
- curl
curl https://www.google.com -o output.log
- ファイル名まであるURLで、保存するファイル名も同じでよければ
-O
も使えるcurl -O https://ftp.gnu.org/gnu/wget/wget-1.19.5.tar.gz
- PowerShell
Invoke-WebRequest https://www.google.com -OutFile output.txt
Invoke-WebRequest
で https://ftp.gnu.org への接続がエラーになる件は後述
リダイレクト制御
-
curl
- curlはデフォルトではリダイレクトせずにレスポンス302等が返って終了する
- ファイルのダウンロードなどでリダイレクトも処理してほしい場合は
-L
を使う curl -LO https://github.com/zaki-lknr/javaee-memoapp2/archive/v1.0.0.tar.gz
-
PowerShell
- curlと違ってPowerShellではリダイレクトは勝手に処理される
- リダイレクトを制限したい場合は
-MaximumRedirection
に最大リダイレクト数をセットする(禁止するには0・デフォルトは5) Invoke-WebRequest http://www.jp-z.jp/perlmemo -MaximumRedirection 0
- ただし「既定の数を超えたリダイレクトのレスポンスがあった」という状態になるため、エラー表示となる
-
powershell curl and WebRequest both follow redirects - Stack Overflow
進捗の非表示
-
curl
curl -s http://www.example.org/
-
-s
(--silent
)を使うとエラーの表示も出なくなるため-S
(--show-error
)を併用すると良いcurl -sS http://www.example.org/
-
PowerShell
-
オプションとしてはない
$progressPreference = 'silentlyContinue' # progress表示のoff Invoke-WebRequest http://www.example.org/ $progressPreference = 'Continue' # progress表示のon
-
HTTPのリクエストヘッダとレスポンスヘッダを確認する
- curl
curl -i https://www.example.org
-
curl -v https://www.example.org
でも見れる
- PowerShell
-
Invoke-WebRequest
の戻り値がオブジェクトなのでHeaders
メンバを参照する$resp = Invoke-WebRequest https://www.example.org $resp.Headers
-
リクエストヘッダはないかも
-
エラー応答の確認・ハンドリング
-
curl
-
-f
(--fail
)を使う% curl -sSf -O https://ftp.gnu.org/gnu/wget/wget-1.19.5.tar.g curl: (22) The requested URL returned error: 404 Not Found % echo $? 22
-
-f
無しだとHTTP上のエラーが発生してもcurlコマンド自体は正しく動作しているということで戻り値0になってしまう
-
-
PowerShell
-
HTTPエラーが発生すると例外がthrowされる
-
catch
していなくても、直近の例外は$error[0]
にセットされるPS > Invoke-WebRequest http://ftp.gnu.org/gnu/wget/wget-1.19.5.tar.g Invoke-WebRequest : Not Found The requested URL /gnu/wget/wget-1.19.5.tar.g was not found on this server. Apache/2.4.7 (Trisquel_GNU/Linux) Server at ftp.gnu.org Port 80 発生場所 行:1 文字:1 + Invoke-WebRequest http://ftp.gnu.org/gnu/wget/wget-1.19.5.tar.g + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest]、WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand PS> $error[0].Exception.Message リモート サーバーがエラーを返しました: (404) 見つかりません PS> $error[0].Exception.Response.StatusCode.value__ 404 PS> $error[0].Exception.Response.StatusDescription Not Found
-
サーバの応答によってはレスポンスを参照できる
PS > Invoke-WebRequest https://api.chatwork.com/v2/rooms Invoke-WebRequest : {"errors":["Invalid API Token"]} 発生場所 行:1 文字:1 + Invoke-WebRequest https://api.chatwork.com/v2/rooms + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest]、WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand PS > $error[0].ErrorDetails.Message {"errors":["Invalid API Token"]} PS > $error[0].Exception.Response.StatusCode.value__ 401
-
任意のHTTPリクエストヘッダを付加
- curl
-
-H "HeaderKey: HeaderValue"
を付加 - 複数ある場合は
-H
を複数回付加する curl -H "Authorization: Bearer foobar" -H "X-Header: hogehoge" http://www.example.org
-
- PowerShell
- 連想配列にしたヘッダ情報を引数に
-Headers $hashTable
を付加 Invoke-WebRequest http://www.example.org -Headers @{Authorization: "Bearer foobar"; X-Header: "hogehoge"}
- 連想配列にしたヘッダ情報を引数に
POSTする
key=valueなパラメタでPOST
- curl
-
-d
(--data
)を使うcurl -XPOST -d 'key1=value1&key2=value2' http://www.example.org
-
-d
を複数回使っても良いcurl -XPOST -d 'key1=value1' -d 'key2=value2' http://www.example.org
-
-d
(--data
)の替わりに--data-urlencode
を使えば、パラメタ文字列のURLエンコードをcurlがやってくれる-
curl -XPOST -d 'key1=value1' --data-urlencode 'key2=/e/' http://www.example.or
- サーバには
key1=value1&key2=%2Fe%2F
が送られる -
--data-urlencode 'key1=value1&key2=/e/'
と書くと、&
もエンコードされてkey1=value1%26key2%3D%2Fe%2F
になるので注意
- サーバには
-
-
- PowerShell
Invoke-WebRequest -Method Post -Body 'key1=value1&key2=value2' http://www.example.org
- 連想配列にしても可
Invoke-WebRequest -Method Post -Body @{key1="value1"; key2="value2"} http://www.example.org
- 文字列を指定する場合はURLエンコードは自前で処理する必要があるが、連想配列の場合は勝手にやってくれる
-
Invoke-WebRequest -Method Post -Body @{key1="value1"; key2="/e/"} http://www.example.org
- サーバへは
key1=value1&key2=%2Fe%2F
がPOSTされる
- サーバへは
-
JSONなどの任意のBody用文字列丸ごとPOST
前述のkey=valueの場合とやることは同じ
- curl
curl -XPOST -d '{ "key": { "subkey":"value" } }' http://www.example.org
- PowerShell
Invoke-WebRequest -Method Post -Body '{ "album": { "title":"create by api" } }' http://www.example.org
外部ファイルをBodyとして丸ごとPOST
バイナリファイルを送信する場合など。
ファイル指定できるのでそれでPOSTする。
以下、カレントディレクトリから見てPictures/photo.jpg
にPostしたいファイルがあるとする。
- curl
curl -XPOST --data-binary @Pictures/photo.jpg http://www.example.org
- PowerShell
Invoke-WebRequest -Method Post -InFile Pictures\photo.jpg http://www.example.org
HTTPS
証明書の検証(エラー)を無視する
テスト環境などでちゃんとした証明書を使ってなかったりDNS設定がない場合など
- curl
-
-k
オプションを使う curl -k https://192.168.0.11
-
- PowerShell
-
オプションだけでは実現できなさげ
-
.NET内の検証処理をオーバーライドするコードを追加すれば通る
-
PowershellのInvoke-RestMethodをhttpsに実施すると失敗する - suusan2号の戯れを参照
add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy Invoke-WebRequest https://192.168.0.11
-
暗号化プロトコルを指定してTLS1.2でアクセス
冒頭の例の https://ftp.gnu.org とか、あと https://qiita.com/ とかも、TLS1.2対応しており、Win10標準のPowerShell 5.1だと(デフォルトでは)対応していない。
PS C:\Users\zaki> Invoke-WebRequest https://ftp.gnu.org/
Invoke-WebRequest : 要求は中止されました: SSL/TLS のセキュリティで保護されているチャネルを作成できませんでした
発生場所 行:1 文字:1
+ Invoke-WebRequest https://ftp.gnu.org/
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest]、WebExce
ption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
PS C:\Users\zaki> Invoke-WebRequest http://qiita.com/
Invoke-WebRequest : 接続が切断されました: 送信時に、予期しないエラーが発生しました。。
発生場所 行:1 文字:1
+ Invoke-WebRequest http://qiita.com/
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest]、WebExce
ption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
現在の暗号化プロトコルの対応状態を表示(SSL3とTLSしか使えない)
PS C:\Users\zaki> [Net.ServicePointManager]::SecurityProtocol
Ssl3, Tls
ただし、設定で追加はできる。追加できるプロトコルはこの通り。
PS C:\Users\zaki> [enum]::GetNames([Net.SecurityProtocolType])
SystemDefault
Ssl3
Tls
Tls11
Tls12
TLS1.2を追加するには「既存設定にTLS1.2の項目を追加」してやる
PS C:\Users\zaki> [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
これでInvoke-WebRequest https://ftp.gnu.org/
やInvoke-WebRequest http://qiita.com/
すればHTTPアクセスできる。
サイトの暗号化プロトコルの種類を確認するには、Chromeならデベロッパーツールで。
参考: Windows PowerShellとTLS 1.2 - しばたテックブログ
ちなみにGitHubはTLS1.2を加えてもアクセスできない(反応がない)。
ただしGitHubは-UseBasicParsing
を付加して「HTTPアクセスして得られたレスポンスを IEコンポーネントを使って DOM解析を行う」オプションをオフにすればOKだった。
PS C:\Users\zaki> Invoke-WebRequest https://github.com/ -UseBasicParsing
StatusCode : 200
StatusDescription : OK
Content :
:
:
ただしこのオプションは、PowerShell 6でdeprecatedになっている。
curlの場合はcurl本体のバージョンやOpenSSLに依存する模様。
超古いサーバーからhttpsにcurlする時 - yamaguchi.txt
オプションとしては次のようなものがある。(curl -h
で確認できる)
--sslv2
--sslv3
--tlsv1.2
--tlsv1.3