curl のような wget のような httping のようなウェブクライアント webGetter.jar

---
### アーキテクチャ

Java の[java.net.HttpURLConnectionクラス](http://docs.oracle.com/javase/jp/6/api/java/net/HttpURLConnection.html)、または[javax.net.ssl.HttpsURLConnectionクラス](http://docs.oracle.com/javase/jp/6/api/javax/net/ssl/HttpsURLConnection.html)を使った Web クライアントです。

---
### 使い方(ダウンロードとインストール)

[webGetter.jar (Java による汎用 HTTP クライアント)](http://rocketeer.dip.jp/sanaki/free/jfree15.htm) からwebGetter.lzhをダウンロードして、ZoneIDを削除して、解凍すれば、使える。

---
### usage

<pre>C:\&gt;webGetter.bat
usage: java webGetter url [options]
     -ProxyHost &lt;&lt;Hostname&gt;&gt;
     -ProxyPort &lt;&lt;proxyPort&gt;&gt;
         default:No_Proxy
     -ProxyType [socks|http](default:http)
     -Header &lt;&lt;string(aaa:bbb)&gt;&gt;
     -Method &lt;&lt;string{GET/POST/HEAD/OPTIONS/PUT/DELETE/TRACE (default:GET)}&gt;&gt;
     -ReadTimeout &lt;&lt;milliSeconds&gt;&gt;
     -NoReadTimeout
     -ConnectTimeout &lt;&lt;milliSeconds&gt;&gt;
     -NoConnectTimeout
     -Timeout &lt;&lt;milliSeconds&gt;&gt; // Read&amp;ConnectTimeout Set
     -NoTimeout                // Read&amp;ConnectTimeout Set
     -BufferSize               // BufferSize (Default 4096byte
     -PostFile &lt;&lt;filePath&gt;&gt; // HTTPRequestBody from File
     -StdIn                 // HTTPRequestBody from STDIN
     -CharSet &lt;&lt;string&gt;&gt;
     -AutoCharSetDetect
     -AutoRedirect
     -CertCheck
     -UseWeakAlgorithm // JDK7
     -DisableTLSSNI    // JDK7 TLS-SNI
     -UseSSL2          // use SSL2/3/TLS
     -UseSSL3          // use SSL3/TLS
     -UseTLS1          // use TLS1.0/1.1/1.2
     -UseTLS1.1        // use TLS1.1/1.2
     -UseTLS1.2        // use TLS1.2
     -OutputHeader                // Choose at least one
     -OutputBody                  // Choose at least one
     -OutputBodyFile &lt;&lt;filePath&gt;&gt; // Choose at least one
     -OutputTime                  // Choose at least one
                       default: -OutputHeader &amp; -OutputBody
     -GuessContentType
     -Debugmode
     -SleepTime &lt;&lt;Seconds&gt;&gt; : Sleep before Exit
     -GUI    : Load GUI

           ver2.3 and Create by activewindow.goukaku.com

0</pre>

---
### バッチファイルの中身

基本的に

webGetter.bat
⇔
java.exe -cp webGetter.jar

は同義。

---
### 普通の Web クライアント(curl とか wget とか)

-OutputHeader と -OutputBody を使えば、HTTP レスポンス・ヘッダと、HTTPレスポンス・ボディが返る

`webGetter.bat http://www.example.com/ -OutputHeader -OutputBody`
⇔
`HTTPCurl.bat http://www.example.com/`

疎通確認としてヘッダだけ欲しいなら

`webGetter.bat http://www.example.com/ -OutputHeader`

でもよいよね。

HTTP の HEAD メソッド使うなら

`webGetter.bat http://www.example.com/ -OutputHeader -Method HEAD`

とすると、通信量的に効率的かと思う。

---
#### 普通の Web クライアント(文字コード)

Content-Type ヘッダに文字コードが明示されていれば、-AutoCharSetDetect オプションで、認識してくれるかも(文字化けしなくなるかも)
または、**「-CharSet 文字コード」**オプションによって、文字コードを明示すれば、HTTPレスポンス・ボディの文字化け問題はなくなるよ。

---
### ウェブ・ダウンローダー

-OutputBodyFile オプションを使う

例えば、

`webGetter.bat http://www.example.com/install.iso -OutputBodyFile install.iso`
⇔
`HTTPDownloader.bat install.iso http://www.example.com/install.iso`

な感じにすれば、http://www.example.com/install.iso をダウンロードして install.iso を作れる。

保存先に install.iso があれば、(Webサーバ側が対応していれば)Rangeヘッダを使って差分ダウンロードを実施する。
また、ダウンロードが途中で切れた場合、終了コードが「0」以外になるはずなので(バッチファイルの場合は、環境変数 ERRORLEVEL)それを見て、再試行するようなバッチファイルを書いてあげれば、最後までダウンロードができると思うよ。
(ver2.3から終了コードはHTTPステータスコードになったので、最後までダウンロードが完了した際には「200」または「206」が返るはず{ver2.3前後での仕様変更のため追記})
その際に-SleepTime オプションで、インターバルを挟むとよいと思う。

さらに「-Timeout 300000」(タイムアウトは5分)とかのオプションもあった方がいいね。

---
### ウェブ・ダウンローダー(レジューム対応)

-OutputBodyFile と -Timeout オプションを使って、エラーレベルが「1」の時だけ、ループすればいいと思う。

という事で、
`HTTPDownloaderResume.bat 保存ファイル名 タイムアウト(秒) URL`
⇔
`HTTPDownloaderResume.bat install.iso 300 http://www.example.com/install.iso`
みたいなバッチを作った。(ver2.4以降)

HTTPDownloaderResume.bat の第二引数は「秒」なので、「300」という事は「300秒=5分」という事にした。

---
### httping

-OutputTime で、通信時間が表示される

`webGetter.bat http://www.example.com/ -OutputTime`
⇔
`HTTPPing.bat http://www.example.com/`

後は、数秒間スリープするプログラムと、これを繰り返すバッチファイルを用意すれば、Webサーバの死活確認をし続けることができる。
たとえば、デバグや検証などで、対象Webサーバの死活確認をし続けたい場合などにお勧め。

さらに、-SleepTime オプションで、スリープする事ができようにしたので、
上記の数秒間スリープするプログラムは不要になったよ。

通信して、通信時間を表示して、3秒間スリープする
`webGetter.bat http://www.example.com/ -OutputTime -SleepTime 3`

通信して、通信時間を表示して、3秒間スリープする、を100回実行
`FOR /L %i IN (1,1,100) DO webGetter.bat http://www.example.com/ -OutputTime -SleepTime 3`

---
### HTTPPing.bat と HTTPPing1.bat

ver2.3 からHTTPPing1.bat も添付に追加した。

- HTTPPing.bat は無限ループで ping する(ping.exe -t のようなもの)。
- HTTPPing1.bat は一回だけ ping する(ping.exe -n 1 のようなもの)。

---
### httping の例

大体10:00から18:00ぐらいまで15分おきに死活監視するバッチファイル

> SET URL=https://www.example.com/top.cgi
> :Asa
> FOR /F "usebackq delims=:" %%i IN (\`time /t\`) DO IF %%i GEQ 10 GOTO Loop
> cscript.exe sleep.vbs
> GOTO Asa
> :Loop
> FOR /F "usebackq delims=:" %%i IN (\`time /t\`) DO IF %%i GEQ 18 GOTO :EOF
> CALL HTTPPing1.bat %URL% -OutputTime -OutputHeader -SleepTime 900
> GOTO Loop

sleep.vbsは ↓
[一定時間待機する(sleep)](https://qiita.com/tomoki0sanaki/items/0deef304ac0bb0761315)

---
### httptraceroute

HTTPメソッドに「TRACE」を指定して、「Max-Forwards」ヘッダを指定すると、多段のリバースプロキシサーバに対して、TRACEROUTEのようなことができるよ。

`webGetter.bat http://www.example.com/ -Header "Max-Forwards: 0" -Method TRACE -OutputHeader`

これの Max-Forwards の値をインクリメントするようなバッチファイルを書いてあげれば、tracerouteのようなことができるよ、
⇔
`HTTPTRace.bat 4 http://www.example.com/`

これは、4階層まで、調査する。ということになる

---
### オプションの説明

<dl>
 <dt>-ProxyHost と -ProxyPort と -ProxyType
  <dd>HTTPプロキシの指定
 <dt>-Header
  <dd>HTTPヘッダを指定する。基本認証とか、User-Agentとか Refererを指定すればいいさ
 <dt>-Method
  <dd>HTTPメソッドの指定
 <dt>-ReadTimeout と -NoReadTimeout と -ConnectTimeout と -NoConnectTimeout と -Timeout と -NoTimeout 
  <dd>使っている HttpURLConnectionクラスに二つのタイムアウト指定があるので、ソレ。TimeOut/NoTimeout は両方
 <dt>-BufferSize
  <dd>HTTPレスポンス・ボディは、ストリームなので、whileする際のバッファサイズ
 <dt>-PostFile と -StdIn
  <dd>HTTPリクエスト・ボディをファイルから読み込む/標準入力から読み込む
 <dt>-AutoRedirect
  <dd>30xの場合、内部でリダイレクトしてさらに先の応答を求めるかどうかなんだけど、使用している HttpURLConnectionクラスのプロパティなので、それに応じた制限があるよ(http→httpsへリダイレクトしないとか)
 <dt>-CertCheck と -UseWeakAlgorithm と -DisableTLSSNI と -UseSSL2 と -UseSSL3 と -UseTLS1 と -UseTLS1.1 と -UseTLS1.2
  <dd>対象が https の場合の設定。このツールは基本的にデバグ用ツールなので、既定は証明書チェックをしないようにしていますので、サーバ証明書をチェックする必要がある場合は、-CertCheck オプションを付与してね。-UseWeakAlgorithm と -DisableTLSSNI は JavaVM のバージョンによる制限なので、必要なら付与してくれ
 <dt>-SleepTime
  <dd>httping 用に終了時にスリープするようにした。そのオプション
 <dt>-GuessContentType
  <dd>使用している HttpURLConnectionクラスにあるプロパティなんだけど、動作していないような気がする
 <dt>-CharSet
  <dd>HTTPレスポンス・ボディの文字コードを明示
 <dt>-AutoCharSetDetect
  <dd>HTTPレスポンス・ボディの文字コードを推定する
 <dt>-OutputHeader
  <dd>画面に HTTP レスポンス・ヘッダを出力する
 <dt>-OutputBody
  <dd>画面に HTTP レスポンス・ボディを出力する
 <dt>-OutputBodyFile
  <dd>HTTP レスポンス・ボディをファイルに保存する
 <dt>-OutputTime
  <dd>画面に通信時間を表示する
 <dt>-Debugmode
  <dd>デバグモードで動作させる
</dl>

---
### 終了コード

ver2.3から基本的にHTTPステータスコードを返すようにした。

|終了コード|意味|
|:-----------------|:-----------------|
|0|通信の処理を実施するまでのエラー|
|1|ボディが全て到着する前に切断された(ver2.2 までは 254)|
|2|通信エラー(ver2.2 までは 255)|
|その他|HTTPステータスコード|

---
### ver2.4

- HTTPDownloaderResume.bat の添付
- Rengeヘッダを使った際に、既にコンテンツをダウンロードしきった場合、ファイルが壊れてしまう(406? だかの Rangeの値がおかしいエラーのレスポンスボディに置き換わってしまう)バグの修正


---
### StreamRelay.jar

機能的には劣るけどStreamRelay.jarもURIなパスに対応してみた。

[curl のような wget のようなウェブクライアントの代替としてのStreamRelay.jar](https://qiita.com/tomoki0sanaki/items/d3288cfad06de3bf52a3)