HTTPのリクエストボディをストリームで指定する。
リクエストボディをストリームで指定するには、Net::HTTPRequest#body_stream=()を使用します。
何がうれしいか
ストリームを使うと、ボディを文字列で指定する場合に比べ、メモリ消費を抑えられるというメリットがあります。
- ボディを文字列で指定する
- 送信データを一度にメモリに読み込む必要があるため、データサイズが大きい場合それだけメモリを消費する。
- ストリームの場合
- 必要な分のみ随時メモリに読み込んで送信を行うため、メモリ消費を抑えられる。
body_stream=()の使い方
- ストリームにはIO オブジェクトなどを設定できます。read(size) メソッドが定義されていればOKとのこと。
- ストリームで指定する場合、HTTPヘッダで転送データサイズを指定するか、チャンク形式での転送を行う必要があります。
サンプル。
require "net/http" host = .. # ホスト port = .. # ポート path = .. # パス Net::HTTP.version_1_2 http = Net::HTTP.new( host, port ) http.start { |http| # ストリームをリクエストボディで指定する場合、http.post()などのユーティリティは使えない。 # Net::HTTP::Postを使う。 req = Net::HTTP::Post.new(path) # ファイルを開く。 File.open( "./data.txt" ) {|f| req.body_stream = f # リクエストボディにストリームを指定。 # HTTPヘッダで転送データサイズを指定するか、チャンク形式での転送を行う必要がある。 req[ "Content-Length" ] = f.lstat.size.to_s # データサイズを指定する場合 # サーバー側がチャンク形式での転送をサポートしていれば、それを使用することも可能。 # この場合、サイズの指定は不要。 #req[ "Transfer-Encoding" ] = "chunked" puts http.request(req).body } }
"./data.txt" が
hogehoge
の場合、POSTされるデータは次のようになります。
POST /xxxxxx HTTP/1.1 Accept: */* Host: xxxxxx:80 Content-Length: 8 hogehoge
参考: