Ruby のHTTP関連ライブラリ と ストリーミングダウンロード2010/03/01

うーむ。 表題の件で少し悩み中

Net::HTTP / Net::HTTPS

Net::HTTP#request は、ブロックを渡すとストリーミング受信はできるものの、レスポンスは全部メモリに貯まる。

微妙な片手落ち感が……。

Mechanize

Mechanize#get 等はブロックを受け取るものの、ストリーミング受信等はしてくれない。

Mechanize::Page オブジェクトの生成が全て完了してからブロックがyeildされる。 というか、このブロック引数って、何か良いことあるのかな? eachが一つ省略できるぐらい?

HTTPClient

HTTPClient#request は、ブロックを渡すとストリーミング受信をしてくれて、この場合は、responseオブジェクトにはbodyが貯まらない。

この点については一番理想的な実装だけど、信頼できない証明書を使用しているhttpsサイトに接続させてくれないという問題が……。

HTTPClient にモンキーパッチを当てるのが正着なのかなあ……。

と思ったら、 HTTPClient::SSLConfig#verify_mode に OpenSSL::SSL::VERIFY_NONE を設定してやれば証明書の問題はスルーしてくれることが判明。

httpclient = HTTPClient.new
httpclient.get('https://localhost/').status
# OpenSSL::SSL::SSLError が発生
httpclient.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
# => 0
httpclient.get('https://localhost/').status
# => 200

調べてみたら、HTTPClient 2.1.3 からの新機能か。1年前には実装されてたとは……。時の流れは速すぎるぜ。

余談

ちなみに、request bodyをストリーミングできるのは Net::HTTPだけ。

余談の余談

ここで言うストリーミングとは、rewindできないようなIO(要するに$stdin)の状態で取り扱いたいという話で、既にFileオブジェクトになっているようなものを少しずつ送るだけなら、MechanizeやHTTPClientでも問題なく対処できます。