是否可以使用Ruby';在请求完成之前,是否要删除HTTPClient gem?
我需要在Rails应用程序中代理请求。我希望我可以用分块代理它(因此,接收一个分块,发送一个分块)。应用程序运行良好,无需分块(将请求加载到内存中,然后传输) 以下是我将区块代理到最终客户端的代码:是否可以使用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
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
),因为这将更紧密地匹配输入流(有效地读取内容)