2012-02-19 24 views
6

Tôi đang cố gắng sử dụng API PowerTrack Gnip, yêu cầu tôi kết nối với luồng JSON JSON bằng auth cơ bản. Tôi cảm thấy như thế này là khá tầm thường vì vậy tôi hy vọng một số rubyist thông minh hơn tôi có thể chỉ ra sai lầm rõ ràng của tôi.luồng em-http với lệnh auth và gzip cơ bản

Dưới đây là phần có liên quan ruby ​​của tôi 1.9.3 mã:

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 

sẽ kết nối dòng (dashboard Gnip My repors một kết nối) nhưng sau đó chỉ cần đệm và không bao giờ kết quả đầu ra bất cứ điều gì. Trong thực tế, có vẻ như nó không bao giờ đi vào khối s.stream do... Lưu ý rằng đây là luồng được mã hóa GZip.

Lưu ý rằng công trình này:

curl --compressed -uusername $GNIP_STREAMING_URL 

EDIT: Tôi chắc chắn đây là kinda ngầm, nhưng tôi không thể đưa ra bất kỳ creds đăng nhập hoặc URL thực tế, vì vậy đừng hỏi;)

EDIT # 2: yajl-ruby có thể hoạt động nếu tôi có thể tìm ra cách mã hóa thông tin đăng nhập cho URL (mã hóa URL đơn giản dường như không hoạt động khi tôi không xác thực với Gnip).

EDIT # 3: @rweald thấy rằng em-http không hỗ trợ phát trực tuyến gzip, tôi đã tạo một vấn đề GitHub tại đây.

EDIT # 4: Tôi đã chia đôi và sửa lỗi này theo yêu cầu em-http, bạn có thể trỏ đến my fork nếu bạn muốn sử dụng em-http theo cách này. Bản vá đã được sáp nhập vào repo của người bảo trì và sẽ làm việc trong bản phát hành tiếp theo.

EDIT # 5: Các bản sửa lỗi của tôi đã được xuất bản trong yêu cầu em-http-yêu cầu 1.0.3, vì vậy điều này sẽ không còn là vấn đề nữa.

Trả lời

2

Vấn đề nằm trong em-http-request. Nếu bạn nhìn vào https://github.com/igrigorik/em-http-request/blob/master/lib/em-http/decoders.rb

Bạn sẽ nhận thấy rằng giải nén GZIP không thể làm trực tuyến giải nén :( https://github.com/igrigorik/em-http-request/blob/master/lib/em-http/decoders.rb#L100

Bạn sẽ cần phải sửa chữa vấn đề luồng gzip nằm bên dưới nếu bạn muốn để có thể đọc một dòng sử dụng em-http-request

+0

Rất dễ tìm!Có lẽ chúng ta sửa đá quý em-http. Nếu không, có cách nào để sử dụng yajl-ruby hoặc lề đường để giữ cho kết nối còn sống và sau đó thử kết nối lại trong một mô hình quay ngược theo hàm mũ không? –

+0

Vâng, vì vậy tôi thực sự tìm thấy một cách giải quyết ngày hôm qua sẽ cho phép streaming jzip json từ GNIP. Tôi đang làm việc để làm sạch mã ngay bây giờ và bạn sẽ có thể nhìn thấy nó trong dự án github của tôi https://github.com/rweald/gnip-stream – rweald

+0

Tôi nghĩ rằng tôi sẽ có thể khái quát hóa các sửa chữa cũng như vậy mà nó có thể được thêm vào dưới dạng bản vá cho em-http-request. Tôi sẽ có một cái nhìn qua cuối tuần. – rweald

0

nó trông giống như sử dụng https://github.com/brianmario/yajl-ruby sẽ giải quyết này độc đáo

+0

Có vẻ đầy hứa hẹn, nhưng tôi không thể tìm ra cách mã hóa tên người dùng và mật khẩu sao cho tôi không gặp lỗi này: "lib/ruby ​​/ 1.9.1/uri/generic.rb: 411 : trong 'check_user ': thành phần xấu (thành phần userinfo hoặc thành phần người dùng mong đợi)" –

+1

Điều này thực sự sẽ không giúp được gì cả. Nếu bạn nhìn vào mã yajl-ruby cho http_request, bạn sẽ thấy rằng nó chỉ hỗ trợ gzip nếu đáp ứng không phải là "Chunked" mà đáp ứng GNIP là. https://github.com/brianmario/yajl-ruby/blob/master/lib/yajl/http_stream.rb#L160 – rweald

0

Gnip đề nghị tôi sử dụng curb và đây là những gì tôi đã đưa ra từ tấm gương của họ:

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 

Mặc dù tôi muốn một cái gì đó sẽ kết nối lại khi kết nối bị ngắt và xử lý các loại thất bại khác nhau một cách duyên dáng.

1

Tôi đã sử dụng một số mã cơ bản của Gist này để kết nối với Gnip console. https://gist.github.com/1468622

+0

Cảm ơn! Có thể đã tiết kiệm rất nhiều thời gian tôi đã tìm thấy rằng trước đó, nhưng tôi có thể có thể vá đá quý gnip-suối bây giờ :) –

Các vấn đề liên quan