Ruby net/http PUT 请求中的流数据

问题描述 投票:0回答:1

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
ruby rest streaming put
1个回答
0
投票

#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=

© www.soinside.com 2019 - 2024. All rights reserved.