是否可以使用Ruby';在请求完成之前,是否要删除HTTPClient gem?

是否可以使用Ruby';在请求完成之前,是否要删除HTTPClient gem?,ruby,httpclient,ruby-on-rails-4,Ruby,Httpclient,Ruby On Rails 4,我需要在Rails应用程序中代理请求。我希望我可以用分块代理它(因此,接收一个分块,发送一个分块)。应用程序运行良好,无需分块(将请求加载到内存中,然后传输) 以下是我将区块代理到最终客户端的代码: self.response.headers['Last-Modified'] = Time.now.ctime.to_s self.response_body = Enumerator.new do |y| client = HTTPClient.new http_response = cl

我需要在Rails应用程序中代理请求。我希望我可以用分块代理它(因此,接收一个分块,发送一个分块)。应用程序运行良好,无需分块(将请求加载到内存中,然后传输)

以下是我将区块代理到最终客户端的代码:

self.response.headers['Last-Modified'] = Time.now.ctime.to_s
self.response_body = Enumerator.new do |y|
  client = HTTPClient.new
  http_response = client.get(proxy_url, nil, headers) do |chunk|
    y << chunk
  end
end
self.response.headers['Last-Modified']=Time.now.ctime.to\s
self.response_body=Enumerator.new do|y|
client=HTTPClient.new
http_response=client.get(proxy_url,nil,headers)do| chunk|

y更新

我有一个解决办法给你

如果改为调用
get\u async
,它将立即使用
HTTPClient::Connection
对象重新运行,该对象在收到后立即用头信息更新。这段代码示例演示了

HTTPClient::Connection
的补丁对您几乎肯定不是必需的,但它允许您编写
conn.queue.size?
conn.queue.empty?
之类的内容

conn.pop
阻塞,直到异步线程将响应(或异常)推送到队列,然后返回正常的
HTTP::Message
对象。(请注意,如果您使用的是monkey补丁,则可以使用
conn.queue.empty?
查看
pop
是否将被阻止。)

resp.content
返回一个
IO
对象,该对象是管道读取端点,只要返回
pop
hs即可调用。另一端在数据到达时由异步线程写入,您可以一次读取整个内容,也可以使用
read
读取任意大小的块

require 'httpclient'

class HTTPClient::Connection
  attr_reader :queue
end

client = HTTPClient.new

conn = client.get_async 'http://en.wikipedia.org/wiki/Ruby_(programming_language)'

resp = conn.pop
resp.header.all.each { |name, val| puts "#{name}=#{val}" }
puts
pipe = resp.content
while chunk = pipe.read(8192)
  print chunk
end

您可以解析收到的第一个块来提取标题,但我建议您首先调用
head
来获取标题信息。然后执行
get


(已更新-第一个块包含内容的开头,因此无法使用。)

更新

我有一个解决办法给你

如果改为调用
get\u async
,它将立即使用
HTTPClient::Connection
对象重新运行,该对象在收到后立即用头信息更新。这段代码示例演示了

HTTPClient::Connection
的补丁对您几乎肯定不是必需的,但它允许您编写
conn.queue.size?
conn.queue.empty?
之类的内容

conn.pop
阻塞,直到异步线程将响应(或异常)推送到队列,然后返回正常的
HTTP::Message
对象。(请注意,如果您使用的是monkey补丁,则可以使用
conn.queue.empty?
查看
pop
是否将被阻止。)

resp.content
返回一个
IO
对象,该对象是管道读取端点,只要返回
pop
hs即可调用。另一端在数据到达时由异步线程写入,您可以一次读取整个内容,也可以使用
read
读取任意大小的块

require 'httpclient'

class HTTPClient::Connection
  attr_reader :queue
end

client = HTTPClient.new

conn = client.get_async 'http://en.wikipedia.org/wiki/Ruby_(programming_language)'

resp = conn.pop
resp.header.all.each { |name, val| puts "#{name}=#{val}" }
puts
pipe = resp.content
while chunk = pipe.read(8192)
  print chunk
end

您可以解析收到的第一个块来提取标题,但我建议您首先调用
head
来获取标题信息。然后执行
get


(已更新-第一个区块保留内容的开头,因此这不起作用。)

我不想这样做,因为这意味着两个HTTP请求,这可能会抵消我试图通过传递区块获得的性能提升。我知道HTTPClient(根据HTTP协议)已经收到了头文件,我想我只是因为HTTPClient API的限制而无法访问它们(除非我错过了什么)。@WilliamDenniss:很公平。我自己也不认为这是一个很好的答案!我一直在查看
HTTPClient
的源代码,我想我已经找到了您想要的。看一看我的更新。@Bordin,谢谢你的回答,很高兴有一个
get\u async
的工作示例。但是,它不适用于二进制请求!将答案中的url替换为
http://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png
它将挂起(ruby 2.0.0,httpclient 2.3.4.1)。你能想出任何原因吗,或者这是一个API错误?我假设是后者,并将其记录在这里:顺便说一句。一个优化是将
read
切换到
readpartial
(并添加
rescue-eoferor
),因为这将更紧密地匹配输入流(有效地读取任何数据)。@WilliamDenniss:我说不出原因,但是,如果您使用
sysread
而不是
readpartial
:),这就很好了。我不想这样做,因为这意味着2个HTTP请求,这可能会抵消我试图通过传递分块获得的性能提升。我知道HTTPClient(根据HTTP协议)已经收到了头文件,我想我只是因为HTTPClient API的限制而无法访问它们(除非我错过了什么)。@WilliamDenniss:很公平。我自己也不认为这是一个很好的答案!我一直在查看
HTTPClient
的源代码,我想我已经找到了您想要的。看一看我的更新。@Bordin,谢谢你的回答,很高兴有一个
get\u async
的工作示例。但是,它不适用于二进制请求!将答案中的url替换为
http://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png
它将挂起(ruby 2.0.0,httpclient 2.3.4.1)。你能想出任何原因吗,或者这是一个API错误?我假设了后者,并将其记录在这里:顺便说一句,一个优化是将
读取
切换到
读取部分
(并添加
rescue EOFEROR
),因为这将更紧密地匹配输入流(有效地读取内容)