tarcieri/cool.io — Issue #20: Easier HTTP client for cool.io?
Author: godfat
Created: 2011-12-31 13:56:48+00:00
State: open

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?

[rest-client]: https://github.com/archiloque/rest-client

The usage would be like this:

``` ruby
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:

``` ruby

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][].

[rest-core]: https://github.com/cardinalblue/rest-core