поток em-http с базовой аутентификацией и зависанием gzip - PullRequest
6 голосов
/ 19 февраля 2012

Я пытаюсь использовать Gnip PowerTrack API, который требует от меня подключения к HTTPS-потоку JSON с базовой аутентификацией. Я чувствую, что это должно быть довольно тривиально, поэтому я надеюсь, что какой-нибудь рубин, умнее меня, сможет указать на мою очевидную ошибку.

Вот соответствующие части мой код 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

Поток подключается (My Gnip dashboard сообщает о подключении), но затем просто буферизируется и никогда ничего не выводит. На самом деле кажется, что он никогда не входит в блок s.stream do... Обратите внимание, что это GZip-кодированный поток.

Обратите внимание, что это работает:

curl --compressed -uusername $GNIP_STREAMING_URL

РЕДАКТИРОВАТЬ: Я уверен, что это своего рода неявное, но я не могу выдать кредиты для входа или фактический URL, так что не спрашивайте;)

РЕДАКТИРОВАТЬ # 2: yajl-ruby, вероятно, будет работать, если бы я мог выяснить, как кодировать учетные данные для URL (простое кодирование URL, кажется, не работает, поскольку я не могу аутентификации с Gnip).

РЕДАКТИРОВАТЬ # 3: @rweald обнаружил, что em-http не поддерживает потоковый gzip, я создал проблему GitHub здесь.

РЕДАКТИРОВАТЬ # 4: я разветвлял и исправлял это в em-http-запросе, вы можете указать мой форк , если вы хотите использовать em-http таким образом. Патч был объединен с репозиторием сопровождающего и будет работать в следующем выпуске.

РЕДАКТИРОВАТЬ # 5: Мои исправления были опубликованы в em-http-request 1.0.3, поэтому это больше не должно быть проблемой.

Ответы [ 4 ]

2 голосов
/ 22 февраля 2012

Проблема заключается в 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

Вам нужно будет решить проблему с потоковым gzip, если вы хотите иметь возможность читать поток с помощью em-http-request

1 голос
/ 06 марта 2012

Я использовал некоторую кодовую базу из этого Gist для подключения к консоли Gnip. https://gist.github.com/1468622

0 голосов
/ 26 февраля 2012

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

Хотя мне бы хотелось что-то, что будет переподключено при разрыве соединения и изящно обрабатывать различные типы сбоев.

0 голосов
/ 22 февраля 2012

похоже, что использование https://github.com/brianmario/yajl-ruby решило бы это хорошо

...