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