Ruby-doc Net/HTTP には、ストリーミング応答本文の詳細な例が記載されています。これは、大きなファイルをダウンロードしようとするときに適用されます。
PUT 経由でファイルをアップロードするための同等のコード スニペットを探しています。コードを機能させるためにかなりの時間を費やしましたが、うまくいきませんでした。特定のインターフェイスを実装し、それを request.body_stream に渡す必要があると思います
ストリーミングが必要なのは、ファイルのアップロード中にファイルの内容を変更するため、アップロード中にバッファリングされたチャンクにアクセスできるようにしたいためです。ストリーミングを使用できる限り、http.rb やrest-client などのライブラリを喜んで使用します。
前もって感謝します! 参考までに、動作する非ストリーミングバージョンを以下に示します。
uri = URI("http://localhost:1234/upload")
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Put.new uri
File.open("/home/files/somefile") do |f|
request.body = f.read()
end
# Ideally I would need to use **request.body_stream** instead of **body** to get streaming
http.request request do |response|
response.read_body do |result|
# display the operation result
puts result
end
end
end
#body_stream= は「IO のような」オブジェクトを期待します。ありがたいことに、ファイルはすでに 1 つです。以下は、ファイルをチャンクでストリーミングするように例を適応させています。これは、使用可能なメモリに収まらない大きなファイルでも機能します。 #request を呼び出すときは、ファイルがまだ開いている必要があることに注意してください。
require 'net/http'
uri = URI("http://localhost:1234/upload")
response = Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Put.new uri
File.open('/home/files/somefile') do |file|
request['Content-Length'] = file.size
request.body_stream = file
http.request(request)
end
end
puts response.body
サーバーは解析をどこで停止するかを認識する必要があるため、プロトコルにはアップフロント長またはチャンク転送エンコーディングのいずれかが必要です。事前に長さがわからない場合は、Content-Length を次のものに置き換えます。 Net::HTTP はチャンク化を自動的に処理します。
request['Transfer-Encoding'] = 'chunked'
ファイル以外をストリーミングする場合は、#body_stream= オブジェクトに IO#read を実装します。