socketry / cool.io

Simple evented I/O for Ruby (but please check out Celluloid::IO instead)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Easier HTTP client for cool.io?

godfat opened this issue · comments

I am a bit tired of em-http-request, so I am looking for alternative HTTP
clients for event-driven architecture, either on eventmachine or cool.io.

However, the built in HTTP client in cool.io doesn't seem very appearing
to me... I am looking for something like rest-client. Would you accept
something like below merged into cool.io?

The usage would be like this:

Client.request(:url => 'http://graph.facebook.com/spellbook'){ |r, h|
  puts "r: #{r}"
  puts "h: #{h}"
}
Coolio::Loop.default.run
puts "DONE"

A quick implementation:

require 'uri'
require 'rest-client'
require 'cool.io'

class Client < Coolio::HttpClient
  def self.request opts={}, &block
    method  = opts[:method]  || opts['method']  || :get
    url     = opts[:url]     || opts['url']
    payload = opts[:payload] || opts['payload'] || {}
    headers = opts[:headers] || opts['headers']
    query   = opts[:query]   || opts['query']   || {}
    loop    = opts[:loop]    || opts['loop']    || Coolio::Loop.default

    uri = URI.parse(url)
    q   = (uri.query || '').split('&').inject({}){ |r, i|
            k, v = i.split('=')
            r[k] = v
            r}.merge(query.inject({}){ |r, (k, v)| r[k.to_s] = v.to_s; r })

    connect(uri.host, uri.port).attach(loop).
      request(method.to_s.upcase, uri.path, :query => q,
             :body => RestClient::Payload.generate(payload).read, &block)
  end

  def initialize socket
    super
    @rc_data = []
  end

  def request method, path, opts={}, &block
    @rc_callback = block
    super
  end

  def on_response_header response_header
    @rc_response_header = response_header
  end

  def on_body_data data
    @rc_data << data
  end

  def on_request_complete
    super
    @rc_callback.call(@rc_data.join, @rc_response_header)
  end
end

Client.request(:url => 'http://graph.facebook.com/spellbook'){ |r, h|
  puts "r: #{r}"
  puts "h: #{h}"
}
Coolio::Loop.default.run
puts "DONE"

This would be used inside rest-core.

I think something like this would probably make more sense as a separate gem than part of cool.io. EventMachine had two HTTP clients packaged as part of its standard library and I found that quite confusing

I agree that's very confusing for EventMachine, and there's also
em-http-request.

Then I'll start writing something like cool.io-http-client or
cool.io-http-request,
thanks!

FYI: https://github.com/godfat/cool.io-http
providing Coolio::Http and Coolio::HttpFiber

Cool :)