如何在 Ruby 中从内存中 HTTP 发送流数据?

发布于 2024-11-07 20:53:51 字数 286 浏览 4 评论 0原文

我想上传在 Ruby 中运行时生成的数据,就像从块中提供上传数据一样。

我发现的所有示例仅显示如何在请求之前流式传输必须位于磁盘上的文件,但我不想缓冲该文件。

除了滚动我自己的套接字连接之外,最好的解决方案是什么?

这是一个伪代码示例:

post_stream('127.0.0.1', '/stream/') do |body|
  generate_xml do |segment|
    body << segment
  end
end

I would like to upload data I generated at runtime in Ruby, something like feeding the upload from a block.

All examples I found only show how to stream a file that must be on disk prior to the request but I do not want to buffer the file.

What is the best solution besides rolling my own socket connection?

This a pseudocode example:

post_stream('127.0.0.1', '/stream/') do |body|
  generate_xml do |segment|
    body << segment
  end
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空名 2024-11-14 20:53:52

有效的代码。

    require 'thread'
    require 'net/http'
    require 'base64'
    require 'openssl'

    class Producer
      def initialize
       @mutex = Mutex.new
       @body = ''
       @eof = false
      end

      def eof!()
        @eof = true
      end

      def eof?()
        @eof
      end

      def read(size)
        @mutex.synchronize {
          @body.slice!(0,size)
        }
      end

      def produce(str)
        if @body.empty? && @eof
          nil
        else
          @mutex.synchronize { @body.slice!(0,size) }
        end
      end
    end

    data = "--60079\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test.file\"\r\nContent-Type: application/x-ruby\r\n\r\nthis is just a test\r\n--60079--\r\n"

    req = Net::HTTP::Post.new('/')
    producer = Producer.new
    req.body_stream = producer
    req.content_length = data.length
    req.content_type = "multipart/form-data; boundary=60079"

    t1 = Thread.new do
      producer.produce(data)
      producer.eof!
    end

    res = Net::HTTP.new('127.0.0.1', 9000).start {|http| http.request(req) }
    puts res

Code that works.

    require 'thread'
    require 'net/http'
    require 'base64'
    require 'openssl'

    class Producer
      def initialize
       @mutex = Mutex.new
       @body = ''
       @eof = false
      end

      def eof!()
        @eof = true
      end

      def eof?()
        @eof
      end

      def read(size)
        @mutex.synchronize {
          @body.slice!(0,size)
        }
      end

      def produce(str)
        if @body.empty? && @eof
          nil
        else
          @mutex.synchronize { @body.slice!(0,size) }
        end
      end
    end

    data = "--60079\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test.file\"\r\nContent-Type: application/x-ruby\r\n\r\nthis is just a test\r\n--60079--\r\n"

    req = Net::HTTP::Post.new('/')
    producer = Producer.new
    req.body_stream = producer
    req.content_length = data.length
    req.content_type = "multipart/form-data; boundary=60079"

    t1 = Thread.new do
      producer.produce(data)
      producer.eof!
    end

    res = Net::HTTP.new('127.0.0.1', 9000).start {|http| http.request(req) }
    puts res
孤蝉 2024-11-14 20:53:52

有一个 Net::HTTPGenericRequest#body_stream=( obj.should respond_to?(:read) )

您或多或少像这样使用它:


class Producer
  def initialize
   @mutex = Mutex.new
   @body = ''
  end

  def read(size)
    @mutex.synchronize {
      @body.slice!(0,size)
    }
  end

  def produce(str)
    @mutex.synchronize {
      @body << str
    }
  end
end

# Create a producer thread

req = Net::HTTP::Post.new(url.path)
req.body_stream = producer
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }

There's a Net::HTTPGenericRequest#body_stream=( obj.should respond_to?(:read) )

You use it more or less like this:


class Producer
  def initialize
   @mutex = Mutex.new
   @body = ''
  end

  def read(size)
    @mutex.synchronize {
      @body.slice!(0,size)
    }
  end

  def produce(str)
    @mutex.synchronize {
      @body << str
    }
  end
end

# Create a producer thread

req = Net::HTTP::Post.new(url.path)
req.body_stream = producer
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文