在 Ruby-doc Net/HTTP 中有一个流式响应主体的详细示例 - 当您尝试下载大文件时它适用。
我正在寻找等效的代码片段来通过 PUT 上传文件。花了相当多的时间试图让代码工作但没有运气。我想我需要实现一个特定的接口并将其传递给
request.body_stream
我需要streaming,因为我想在上传文件时更改文件的内容,因此我想在上传时访问缓冲的块。只要我可以使用流媒体,我很乐意使用像 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”的对象。值得庆幸的是,File
已经是其中之一了。下面调整您的示例以分块流式传输文件。即使对于可用内存不适合的大文件,这也适用。请注意,调用 file
时,#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('test.txt') 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'
如果您要流式传输非文件,请在 IO#read
对象上实现
#body_stream=
。