123456789_123456789_123456789_123456789_123456789_

Class: EventMachine::Protocols::LineAndTextProtocol

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

Overview

A protocol that handles line-oriented data with interspersed binary text.

This version is optimized for performance. See EventMachine::Protocols::LineText2 for a version which is optimized for correctness with regard to binary text blocks that can switch back to line mode.

Constant Summary

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

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) ⇒ LineAndTextProtocol

[ GitHub ]

  
# File 'lib/em/protocols/line_and_text.rb', line 37

def initialize *args
  super
  lbp_init_line_state
end

Instance Method Details

#lbp_init_line_state (private)

[ GitHub ]

  
# File 'lib/em/protocols/line_and_text.rb', line 118

def lbp_init_line_state
  @lpb_buffer = BufferedTokenizer.new("\n")
  @lbp_mode = :lines
end

#receive_data(data)

[ GitHub ]

  
# File 'lib/em/protocols/line_and_text.rb', line 42

def receive_data data
  if @lbp_mode == :lines
    begin
      @lpb_buffer.extract(data).each do |line|
        receive_line(line.chomp) if respond_to?(:receive_line)
      end
    rescue
      receive_error('overlength line') if respond_to?(:receive_error)
      close_connection
      return
    end
  else
    if @lbp_binary_limit > 0
      wanted = @lbp_binary_limit - @lbp_binary_bytes_received
      chunk = nil
      if data.length > wanted
        chunk = data.slice!(0...wanted)
      else
        chunk = data
        data = ""
      end
      @lbp_binary_buffer[@lbp_binary_bytes_received...(@lbp_binary_bytes_received+chunk.length)] = chunk
      @lbp_binary_bytes_received += chunk.length
      if @lbp_binary_bytes_received == @lbp_binary_limit
        receive_binary_data(@lbp_binary_buffer) if respond_to?(:receive_binary_data)
        lbp_init_line_state
      end
      receive_data(data) if data.length > 0
    else
      receive_binary_data(data) if respond_to?(:receive_binary_data)
      data = ""
    end
  end
end

#set_binary_mode(size = nil)

Set up to read the supplied number of binary bytes. This recycles all the data currently waiting in the line buffer, if any. If the limit is nil, then ALL subsequent data will be treated as binary data and passed to the upstream protocol handler as we receive it. If a limit is given, we'll hold the incoming binary data and not pass it upstream until we've seen it all, or until there is an unbind (in which case we'll pass up a partial). Specifying nil for the limit (the default) means there is no limit. Specifiyng zero for the limit will cause an immediate transition back to line mode.

[ GitHub ]

  
# File 'lib/em/protocols/line_and_text.rb', line 95

def set_binary_mode size = nil
  if @lbp_mode == :lines
    if size == 0
      receive_binary_data("") if respond_to?(:receive_binary_data)
      # Do no more work here. Stay in line mode and keep consuming data.
    else
      @lbp_binary_limit = size.to_i # (nil will be stored as zero)
      if @lbp_binary_limit > 0
        raise "Overlength" if @lbp_binary_limit > MaxBinaryLength # arbitrary sanity check
        @lbp_binary_buffer = "\0" * @lbp_binary_limit
        @lbp_binary_bytes_received = 0
      end

      @lbp_mode = :binary
      receive_data @lpb_buffer.flush
    end
  else
    raise "invalid operation"
  end
end

#unbind

[ GitHub ]

  
# File 'lib/em/protocols/line_and_text.rb', line 77

def unbind
  if @lbp_mode == :binary and @lbp_binary_limit > 0
    if respond_to?(:receive_binary_data)
      receive_binary_data( @lbp_binary_buffer[0...@lbp_binary_bytes_received] )
    end
  end
end