123456789_123456789_123456789_123456789_123456789_

Class: EventMachine::Protocols::HeaderAndContentProtocol

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Connection
Instance Chain:
Inherits: EventMachine::Connection
Defined in: lib/em/protocols/header_and_content.rb

Overview

Usage

class RequestHandler < EM::P::HeaderAndContentProtocol def receive_request headers, content p [:request, headers, content] end end

EM.run{ EM.start_server 'localhost', 80, RequestHandler }

Constant Summary

LineText2 - Included

MaxBinaryLength

Class Method Summary

Connection - Inherited

.new

Override .new so subclasses don't have to call super and can ignore connection-specific arguments.

Instance Attribute Summary

Connection - Inherited

#comm_inactivity_timeout

comm_inactivity_timeout returns the current value (float in seconds) of the inactivity-timeout property of network-connection and datagram-socket objects.

#comm_inactivity_timeout=

Allows you to set the inactivity-timeout property for a network connection or datagram socket.

#error?

Returns true if the connection is in an error state, false otherwise.

#notify_readable=

Watches connection for readability.

#notify_readable?,
#notify_writable=

Watches connection for writeability.

#notify_writable?

Returns true if the connection is being watched for writability.

#paused?,
#pending_connect_timeout

The duration after which a TCP connection in the connecting state will fail.

#pending_connect_timeout=

Sets the duration after which a TCP connection in a connecting state will fail.

#signature, #watch_only?

Instance Method Summary

LineText2 - Included

#receive_binary_data

Stub.

#receive_data,
#receive_end_of_binary_data

Stub.

#receive_line

Stub.

#set_binary_mode

Alias for #set_text_mode, added for back-compatibility with LineAndTextProtocol.

#set_delimiter

The line delimiter may be a regular expression or a string.

#set_line_mode

Called internally but also exposed to user code, for the case in which processing of binary data creates a need to transition back to line mode.

#set_text_mode,
#unbind

In case of a dropped connection, we'll send a partial buffer to user code when in sized text mode.

Connection - Inherited

#associate_callback_target

conn_associate_callback_target.

#close_connection

EventMachine::Connection#close_connection is called only by user code, and never by the event loop.

#close_connection_after_writing
#connection_completed

Called by the event loop when a remote TCP connection attempt completes successfully.

#detach

Removes given connection from the event loop.

#disable_keepalive

t_disable_keepalive.

#enable_keepalive

t_enable_keepalive.

#get_cipher_bits, #get_cipher_name, #get_cipher_protocol,
#get_idle_time

The number of seconds since the last send/receive activity on this connection.

#get_outbound_data_size

conn_get_outbound_data_size.

#get_peer_cert

If TLS is active on the connection, returns the remote X509 certificate as a string, in the popular PEM format.

#get_peername

This method is used with stream-connections to obtain the identity of the remotely-connected peer.

#get_pid

Returns the PID (kernel process identifier) of a subprocess associated with this Connection object.

#get_proxied_bytes

The number of bytes proxied to another connection.

#get_sni_hostname, #get_sock_opt,
#get_sockname

Used with stream-connections to obtain the identity of the local side of the connection.

#get_status

Returns a subprocess exit status.

#initialize

Stubbed initialize so legacy superclasses can safely call super.

#original_method,
#pause

Pause a connection so that EventMachine#send_data and #receive_data events are not fired until #resume is called.

#post_init

Called by the event loop immediately after the network connection has been established, and before resumption of the network loop.

#proxy_completed

called when the reactor finished proxying all of the requested bytes.

#proxy_incoming_to

EventMachine::Connection#proxy_incoming_to is called only by user code.

#proxy_target_unbound

Called by the reactor after attempting to relay incoming data to a descriptor (set as a proxy target descriptor with EventMachine.enable_proxy) that has already been closed.

#receive_data

Called by the event loop whenever data has been received by the network connection.

#reconnect

Reconnect to a given host/port with the current instance.

#resume

Resume a connection's EventMachine#send_data and #receive_data events.

#send_data

Call this method to send data to the remote end of the network connection.

#send_datagram

Sends UDP messages.

#send_file_data

Like Connection#send_data, this sends data to the remote end of the network connection.

#set_sock_opt,
#ssl_handshake_completed

Called by ::EventMachine when the SSL/TLS handshake has been completed, as a result of calling #start_tls to initiate SSL/TLS on the connection.

#ssl_verify_peer

Called by ::EventMachine when :verify_peer => true has been passed to EventMachine#start_tls.

#start_tls

Call EventMachine#start_tls at any point to initiate TLS encryption on connected streams.

#stop_proxying

A helper method for EventMachine.disable_proxy

#stream_file_data

Open a file on the filesystem and send it to the remote peer.

#unbind

called by the framework whenever a connection (either a server or client connection) is closed.

Constructor Details

.new(*args) ⇒ HeaderAndContentProtocol

[ GitHub ]

  
# File 'lib/em/protocols/header_and_content.rb', line 51

def initialize *args
  super
  init_for_request
end

Class Method Details

.headers_2_hash(hdrs)

[ GitHub ]

  
# File 'lib/em/protocols/header_and_content.rb', line 124

def headers_2_hash hdrs
  hash = {}
  hdrs.each {|h|
    if /\A([^\s:]+)\s*:\s*/ =~ h
      tail = $'.dup
      hash[ $1.downcase.gsub(/-/,"_").intern ] = tail
    end
  }
  hash
end

Instance Method Details

#dispatch_request (private)

[ GitHub ]

  
# File 'lib/em/protocols/header_and_content.rb', line 97

def dispatch_request
  if respond_to?(:receive_request)
    receive_request @hc_headers, @hc_content
  end
  init_for_request
end

#headers_2_hash(hdrs)

Basically a convenience method. We might create a subclass that does this automatically. But it's such a performance killer.

[ GitHub ]

  
# File 'lib/em/protocols/header_and_content.rb', line 119

def headers_2_hash hdrs
  self.class.headers_2_hash hdrs
end

#init_for_request (private)

[ GitHub ]

  
# File 'lib/em/protocols/header_and_content.rb', line 105

def init_for_request
  @hc_mode = :discard_blanks
  @hc_headers = []
  # originally was @hc_headers ||= []; @hc_headers.clear to get a performance
  # boost, but it's counterproductive because a subclassed handler will have to
  # call dup to use the header array we pass in receive_headers.

  @hc_content_length = nil
  @hc_content = ""
end

#receive_binary_data(text)

[ GitHub ]

  
# File 'lib/em/protocols/header_and_content.rb', line 92

def receive_binary_data text
  @hc_content = text
  dispatch_request
end

#receive_line(line)

[ GitHub ]

  
# File 'lib/em/protocols/header_and_content.rb', line 56

def receive_line line
  case @hc_mode
  when :discard_blanks
    unless line == ""
      @hc_mode = :headers
      receive_line line
    end
  when :headers
    if line == ""
      raise "unrecognized state" unless @hc_headers.length > 0
      if respond_to?(:receive_headers)
        receive_headers @hc_headers
      end
      # @hc_content_length will be nil, not 0, if there was no content-length header.
      if @hc_content_length.to_i > 0
        set_binary_mode @hc_content_length
      else
        dispatch_request
      end
    else
      @hc_headers << line
      if ContentLengthPattern =~ line
        # There are some attacks that rely on sending multiple content-length
        # headers. This is a crude protection, but needs to become tunable.
        raise "extraneous content-length header" if @hc_content_length
        @hc_content_length = $1.to_i
      end
      if @hc_headers.length == 1 and respond_to?(:receive_first_header_line)
        receive_first_header_line line
      end
    end
  else
    raise "internal error, unsupported mode"
  end
end