class CrapServer::ConnectionHandler
Public Class Methods
new(sockets)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 4 def initialize(sockets) @sockets = sockets @sockets.each do |io| add_to_read io end end
Public Instance Methods
add_read_buffer(io, string)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 65 def add_read_buffer(io, string) @rbuffer ||= {} @rbuffer[io.fileno] ||= '' @rbuffer[io.fileno] << string end
add_to_read(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 40 def add_to_read(io) @to_read ||= {} @to_read[io.fileno] = io end
add_to_write(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 11 def add_to_write(io) @to_write ||= {} @to_write[io.fileno] = io end
address(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 50 def address(io) @address ||= {} @address[io.fileno] end
buffer(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 26 def buffer(io) @buffer ||= {} @buffer[io.fileno] end
close(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 81 def close(io) remove_to_read io remove_to_write io @closeaw ||= {} @closeaw.delete io.fileno io.close end
close_after_write(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 76 def close_after_write(io) @closeaw ||= {} @closeaw[io.fileno] end
handle(&block)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 89 def handle(&block) # The main loop. Listening IPv4 and IPv6 connections accept_loop do |data, remote_socket, address_info| instance = CrapServer::ConnectionInstance.new instance.socket = remote_socket instance.config = config instance.address = address_info instance.handler = self instance.run data, &block end end
read_buffer(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 60 def read_buffer(io) @rbuffer ||= {} @rbuffer[io.fileno] end
remove_to_read(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 45 def remove_to_read(io) @to_read.delete io.fileno @address.delete io.fileno end
remove_to_write(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 20 def remove_to_write(io) @buffer ||= {} @to_write.delete io.fileno @buffer.delete io.fileno end
set_address(io, addrs)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 55 def set_address(io, addrs) @address ||= {} @address[io.fileno] = addrs end
set_buffer(io, string)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 31 def set_buffer(io, string) @buffer ||= {} @buffer[io.fileno] = string end
set_close_after_write(io)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 71 def set_close_after_write(io) @closeaw ||= {} @closeaw[io.fileno] = true end
to_read()
click to toggle source
# File lib/crap_server/connection_handler.rb, line 36 def to_read (@to_read ||= {}).values end
to_write()
click to toggle source
# File lib/crap_server/connection_handler.rb, line 16 def to_write (@to_write ||= {}).values end
Protected Instance Methods
accept_connection(socket)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 156 def accept_connection(socket) begin io, addr = socket.accept_nonblock set_address io, addr set_close_after_write io if config.auto_close_connection # Disabling Nagle's algorithm. Is fucking slow :P io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) # We add him to the read queue add_to_read io rescue Errno::EINPROGRESS, IO::EAGAINWaitReadable end end
accept_loop(&block)
click to toggle source
Evented loop (Reactor pattern)
# File lib/crap_server/connection_handler.rb, line 104 def accept_loop(&block) loop { @readables, @writables = IO.select(to_read, to_write) process_readables &block process_writables } end
config()
click to toggle source
# File lib/crap_server/connection_handler.rb, line 178 def config CrapServer::Application.send(:config) end
logger()
click to toggle source
# File lib/crap_server/connection_handler.rb, line 182 def logger CrapServer::Application.send(:logger) end
process_readables(&block)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 115 def process_readables(&block) @readables.each do |socket| if @sockets.include? socket accept_connection socket else begin read_and_process_data socket, &block rescue Errno::EAGAIN rescue EOFError remove_to_read socket end end end end
process_writables()
click to toggle source
# File lib/crap_server/connection_handler.rb, line 130 def process_writables @writables.each do |socket| begin string = buffer socket bytes = socket.write_nonblock string string.slice! 0, bytes if string.empty? # If we don't have more data to send to the client if close_after_write socket close socket else remove_to_write socket end else set_buffer socket, string remove_to_read socket end # If the client close the connection, we remove is from read and from write rescue Errno::ECONNRESET, Errno::EPIPE if close_after_write socket close socket end end end end
read_and_process_data(socket, &block)
click to toggle source
# File lib/crap_server/connection_handler.rb, line 169 def read_and_process_data(socket, &block) _, data = socket, socket.read_nonblock(config.read_buffer_size) block.call data, socket, address(socket) # We close the connection if we auto_close_connection is true and the user didn't write in the buffer. if config.auto_close_connection && buffer(socket).nil? close socket end end