Parent

Included Modules

EventMachine::HttpConnection

Attributes

conn[RW]
connopts[RW]
deferred[R]
error[RW]
uri[RW]

Public Class Methods

new() click to toggle source
# File lib/em-http/http_connection.rb, line 42
def initialize
  @deferred = true
  @middleware = []
end

Public Instance Methods

activate_connection(client) click to toggle source
# File lib/em-http/http_connection.rb, line 52
def activate_connection(client)
  begin
    EventMachine.bind_connect(@connopts.bind, @connopts.bind_port, @connopts.host, @connopts.port, HttpStubConnection) do |conn|
      post_init

      @deferred = false
      @conn = conn

      conn.parent = self
      conn.pending_connect_timeout = @connopts.connect_timeout
      conn.comm_inactivity_timeout = @connopts.inactivity_timeout
    end

    finalize_request(client)
  rescue EventMachine::ConnectionError => e
    #
    # 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 fail any client request at next
    # tick.  We fail at next tick to keep a consistent API when the newly
    # created HttpClient is failed. This approach has the advantage to
    # remove a state check of @deferred_status after creating a new
    # HttpRequest. The drawback is that users may setup a callback which we
    # know won't be used.
    #
    # 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.
    #
    EM.next_tick{client.close(e.message)}
  end
end
close(reason) click to toggle source
Alias for: unbind
conn=(c) click to toggle source
# File lib/em-http/http_connection.rb, line 47
def conn=(c)
  @conn = c
  @deferred = false
end
connection_completed() click to toggle source
# File lib/em-http/http_connection.rb, line 148
def connection_completed
  @peer = @conn.get_peername

  if @connopts.proxy && @connopts.proxy[:type] == :socks5
    socksify(client.req.uri.host, client.req.uri.port, *@connopts.proxy[:authorization]) { start }
  else
    start
  end
end
finalize_request(c) click to toggle source
# File lib/em-http/http_connection.rb, line 93
def finalize_request(c)
  @conn.callback { c.connection_completed }

  middleware.each do |m|
    c.callback &m.method(:response) if m.respond_to?(:response)
  end

  @clients.push c
end
middleware() click to toggle source
# File lib/em-http/http_connection.rb, line 103
def middleware
  [HttpRequest.middleware, @middleware].flatten
end
peer() click to toggle source
# File lib/em-http/http_connection.rb, line 135
def peer
  Socket.unpack_sockaddr_in(@peer)[1] rescue nil
end
post_init() click to toggle source
# File lib/em-http/http_connection.rb, line 107
def post_init
  @clients = []
  @pending = []

  @p = Http::Parser.new
  @p.header_value_type = :mixed
  @p.on_headers_complete = proc do |h|
    client.parse_response_header(h, @p.http_version, @p.status_code)
    :reset if client.req.no_body?
  end

  @p.on_body = proc do |b|
    client.on_body_data(b)
  end

  @p.on_message_complete = proc do
    if not client.continue?
      c = @clients.shift
      c.state = :finished
      c.on_request_complete
    end
  end
end
receive_data(data) click to toggle source
# File lib/em-http/http_connection.rb, line 139
def receive_data(data)
  begin
    @p << data
  rescue HTTP::Parser::Error => e
    c = @clients.shift
    c.nil? ? unbind(e.message) : c.on_error(e.message)
  end
end
redirect(client) click to toggle source
# File lib/em-http/http_connection.rb, line 163
def redirect(client)
  @pending.push client
end
send_data(data) click to toggle source
# File lib/em-http/http_connection.rb, line 198
def send_data(data)
  @conn.send_data data
end
setup_request(method, options = {}, c = nil) click to toggle source
# File lib/em-http/http_connection.rb, line 87
def setup_request(method, options = {}, c = nil)
  c ||= HttpClient.new(self, HttpClientOptions.new(@uri, options, method))
  @deferred ? activate_connection(c) : finalize_request(c)
  c
end
start() click to toggle source
# File lib/em-http/http_connection.rb, line 158
def start
  @conn.start_tls(@connopts.tls) if client && client.req.ssl?
  @conn.succeed
end
stream_file_data(filename, args = {}) click to toggle source
# File lib/em-http/http_connection.rb, line 202
def stream_file_data(filename, args = {})
  @conn.stream_file_data filename, args
end
unbind(reason) click to toggle source
# File lib/em-http/http_connection.rb, line 167
def unbind(reason)
  @clients.map { |c| c.unbind(reason) }

  if r = @pending.shift
    @clients.push r

    r.reset!
    @p.reset!

    begin
      @conn.set_deferred_status :unknown

      if @connopts.proxy
        @conn.reconnect(@connopts.host, @connopts.port)
      else
        @conn.reconnect(r.req.host, r.req.port)
      end

      @conn.pending_connect_timeout = @connopts.connect_timeout
      @conn.comm_inactivity_timeout = @connopts.inactivity_timeout
      @conn.callback { r.connection_completed }
    rescue EventMachine::ConnectionError => e
      @clients.pop.close(e.message)
    end
  else
    @deferred = true
    @conn.close_connection
  end
end
Also aliased as: close
use(klass, *args, &block) click to toggle source
# File lib/em-http/http_connection.rb, line 131
def use(klass, *args, &block)
  @middleware << klass.new(*args, &block)
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.