Ruby で net/http を使ってファイルなどを multipart で POST する
今回は、自分用の覚え書きです。
net/http を用いた multipart の POST
Ruby で HTTP クライアントを書いていると、しばしばファイルなどを POST したいことがあります。
この場合、 multipart なデータを POST することになります。
この機能は、標準ライブラリである net/http のみを用いて、割と簡単に実現できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | require( "net/http" ) require( "uri" ) binary_file = File .open( "binary_file_path.bin" , "rb" ) image_file = File .open( "image_file_path.png" , "rb" ) begin data = [ # 通常のパラメータ # <input type="text" name="name1" value="value1"> のような値 [ "name1" , "value1" ], # ファイルを指定する場合 # <input type="file" name="binary_file"> のような場合に相当する [ "binary_file" , binary_file, { filename: "binary_file_path.bin" } ], # content_type も指定できる。 [ "image_file" , image_file, { filename: "image_file_path.png" , content_type: "image/png" } ] ] req = Net:: HTTP ::Post. new (url.path) req.set_form(data, "multipart/form-data" ) res = Net:: HTTP . new (url.host, url.port).start do |http| http.request(req) end ensure binary_file.close image_file.close end |
よくネットで見つけられる set_form_data
ではなく、set_form
を使うのがポイントです。
set_form(params, enctype="application/x-www-form-urlencoded", formopt={})
の引数
params
set_form
の一つ目の引数である params
には、配列の配列を渡します。
それぞれの配列は、以下の形式になります。
[ (パラメータ名), (値 or ファイルオブジェクト), (オプションのハッシュ) ]
上の使用例を見れば簡単に理解できると思いますが、オプションのハッシュを指定することで、ファイル名や種類を指定することができます。
これらの値の組を配列として指定することで、送信するデータを決められます。
enctype
二つ目の引数である enctype
には、 "multipart/form-data"
を指定します。
デフォルトは "application/x-www-form-urlencoded"
なので、ファイル送信するときは、必ず指定する必要があります。
formopt
三つ目の引数である formopt
には、 :charset
や :boundary
を指定することができます。
:boundary
は、指定しなければランダムで URL-safe な文字列が生成されて使われます。
そのため、通常は特に指定する必要はないでしょう。
以上のような引数を指定し、 set_form
を使うことで、簡単にファイルなどを multipart で送信することができます。
なぜか日本語のリファレンスから漏れており、(そのせいか) 日本語の記事があまりないようなので、メモとして書いておきます。
暇があったらリファレンスに載せてもらうようにお願いする予定です。