lib/em-http/request.rb in em-http-request-0.3.0 vs lib/em-http/request.rb in em-http-request-1.0.0.beta.1

- old
+ new

@@ -1,77 +1,44 @@ module EventMachine - - # EventMachine based HTTP request class with support for streaming consumption - # of the response. Response is parsed with a Ragel-generated whitelist parser - # which supports chunked HTTP encoding. - # - # == Example - # - # EventMachine.run { - # http = EventMachine::HttpRequest.new('http://127.0.0.1/').get :query => {'keyname' => 'value'} - # - # http.callback { - # p http.response_header.status - # p http.response_header - # p http.response - # - # EventMachine.stop - # } - # } - # - class HttpRequest + @middleware = [] - attr_reader :options, :method + def self.new(uri, options={}) + begin + req = HttpOptions.new(uri, options) - def initialize(host) - @uri = host.kind_of?(Addressable::URI) ? host : Addressable::URI::parse(host.to_s) - end + EventMachine.connect(req.host, req.port, HttpConnection) do |c| + c.opts = req - # Send an HTTP request and consume the response. Supported options: - # - # head: {Key: Value} - # Specify an HTTP header, e.g. {'Connection': 'close'} - # - # query: {Key: Value} - # Specify query string parameters (auto-escaped) - # - # body: String - # Specify the request body (you must encode it for now) - # - # on_response: Proc - # Called for each response body chunk (you may assume HTTP 200 - # OK then) - # + c.pending_connect_timeout = req.options[:connect_timeout] + c.comm_inactivity_timeout = req.options[:inactivity_timeout] + end - def get options = {}, &blk; setup_request(:get, options, &blk); end - def head options = {}, &blk; setup_request(:head, options, &blk); end - def delete options = {}, &blk; setup_request(:delete,options, &blk); end - def put options = {}, &blk; setup_request(:put, options, &blk); end - def post options = {}, &blk; setup_request(:post, options, &blk); end - - protected - - def setup_request(method, options, &blk) - @req = HttpOptions.new(method, @uri, options) - send_request(&blk) - end - - def send_request(&blk) - begin - EventMachine.connect(@req.host, @req.port, EventMachine::HttpClient) { |c| - c.uri = @req.uri - c.method = @req.method - c.options = @req.options - c.comm_inactivity_timeout = @req.options[:timeout] - c.pending_connect_timeout = @req.options[:timeout] - blk.call(c) unless blk.nil? - } rescue EventMachine::ConnectionError => e - conn = EventMachine::HttpClient.new("") - conn.on_error(e.message, true) - conn.uri = @req.uri + # + # Currently, this can only fire on initial connection setup + # since #connect is a synchronous method. Hence, rescue the + # exception, and return a failed deferred which will immediately + # fail any client request. + # + # Once there is async-DNS, then we'll iterate over the outstanding + # client requests and fail them in order. + # + # Net outcome: failed connection will invoke the same ConnectionError + # message on the connection deferred, and on the client deferred. + # + conn = EventMachine::FailedConnection.new(req) + conn.error = e.message + conn.fail conn end end + + def self.use(klass) + @middleware << klass + end + + def self.middleware + @middleware + end end -end \ No newline at end of file +end