带有基本auth和gzip的em-http流挂起



我正在尝试使用Gnip PowerTrack API,这需要我使用基本身份验证连接到JSON的HTTPS流。我觉得这应该是相当琐碎的,所以我希望一些比我聪明的卢布爱好者能指出我明显的错误。

以下是我的ruby 1.9.3代码的相关部分:

require 'eventmachine'
require 'em-http'
require 'json'
usage = "#{$0} <user> <password>"
abort usage unless user = ARGV.shift
abort usage unless password = ARGV.shift
GNIP_STREAMING_URL = 'https://stream.gnip.com:443/foo/bar/prod.json'
http = EM::HttpRequest.new(GNIP_STREAMING_URL)
EventMachine.run do
  s = http.get(:head => { 'Authorization' => [user, password], 'accept' => 'application/json', 'Accept-Encoding' => 'gzip,deflate' }, :keepalive => true, :connect_timeout => 0, :inactivity_timeout => 0)
  buffer = ""
  s.stream do |chunk|
    buffer << chunk
    while line = buffer.slice!(/.+r?n/)
      puts JSON.parse(line)
    end
  end
end

流连接(我的Gnip仪表板报告连接),但只是缓冲,从不输出任何内容。事实上,它似乎从未进入s.stream do..块。请注意,这是一个GZip编码的流。

注意,这是有效的:

curl --compressed -uusername $GNIP_STREAMING_URL

编辑:我相信这有点隐含,但我不能给出任何登录凭据或实际URL,所以不要问;)

编辑#2:如果我能弄清楚如何为URL编码凭据,yajl ruby可能会工作(简单的URL编码似乎不起作用,因为我无法通过Gnip身份验证)。

第三版:@rweald发现em-http不支持流式gzip,我在这里创建了一个GitHub问题。

编辑#4:我已经在emhttp请求中分叉并修复了这个问题,如果你想以这种方式使用emhttp,你可以指向我的分叉。该补丁已被合并到维护人员的repo中,并将在下一个版本中运行。

编辑#5:我的修复程序已经在emhttp请求1.0.3中发布,所以这应该不再是一个问题。

问题出在em-http请求中。如果你看https://github.com/igrigorik/em-http-request/blob/master/lib/em-http/decoders.rb

您会注意到GZIP解压缩器无法进行流式解压缩:(https://github.com/igrigorik/em-http-request/blob/master/lib/em-http/decoders.rb#L100

如果您希望能够使用em-http-request

读取流,则需要修复底层的流gzip问题

我一直在使用这个Gist的一些代码库来连接到Gnip控制台。https://gist.github.com/1468622

它看起来像使用https://github.com/brianmario/yajl-ruby会很好地解决这个问题

Gnip建议我使用curb,下面是我从他们的例子中得到的:

require 'rubygems'
require 'curb'
# Usage: <script> username password url
# prints data to stdout.
usage = "#{$0} <user> <password> <url>"
username, password, url = ARGV.first 3
Curl::Easy.http_get url do |c|
  c.http_auth_types = :basic
  c.username = username
  c.password = password
  c.encoding = 'gzip'
  c.on_body do |data|
    puts data
    data.size # required by curl's api.
  end
end

尽管我希望在断开连接时能够重新连接,并优雅地处理不同类型的故障。

最新更新