Class: Gopher::Dispatcher
- Inherits:
-
EventMachine::Connection
- Object
- EventMachine::Connection
- Gopher::Dispatcher
- Defined in:
- lib/gopher2000/dispatcher.rb
Overview
Handle communication between Server and the actual gopher Application
Instance Attribute Summary collapse
-
#app ⇒ Object
the Application we are running.
Instance Method Summary collapse
-
#call!(request) ⇒ Object
generate a request object from an incoming selector, and dispatch it to the app.
-
#end_of_transmission ⇒ Object
Add the period on a line by itself that closes the connection.
-
#receive_data(data) ⇒ Object
called by EventMachine when there's an incoming request.
-
#receive_line(line, ip_address) ⇒ Object
Invoked with lines received over the network.
-
#remote_ip ⇒ Object
get the IP address of the client.
-
#send_response(response) ⇒ Object
send the response back to the client.
Instance Attribute Details
#app ⇒ Object
the Application we are running
11 12 13 |
# File 'lib/gopher2000/dispatcher.rb', line 11 def app @app end |
Instance Method Details
#call!(request) ⇒ Object
generate a request object from an incoming selector, and dispatch it to the app
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/gopher2000/dispatcher.rb', line 52 def call!(request) operation = proc { app.dispatch(request) } callback = proc {|result| send_response result close_connection_after_writing } # # if we don't want to block on slow calls, use EM#defer # @see http://eventmachine.rubyforge.org/EventMachine.html#M000486 # if app.non_blocking? EventMachine.defer( operation, callback ) else callback.call(operation.call) end end |
#end_of_transmission ⇒ Object
Add the period on a line by itself that closes the connection
93 94 95 |
# File 'lib/gopher2000/dispatcher.rb', line 93 def end_of_transmission [Gopher::Rendering::LINE_ENDING, ".", Gopher::Rendering::LINE_ENDING].join end |
#receive_data(data) ⇒ Object
called by EventMachine when there's an incoming request
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/gopher2000/dispatcher.rb', line 28 def receive_data data (@buf ||= '') << data first_line = true ip_address = remote_ip while line = @buf.slice!(/(.*)\r?\n/) is_proxy = first_line && line.match?(/^PROXY TCP[4,6] /) receive_line(line, ip_address) unless is_proxy ip_address = line.split(/ /)[2] if is_proxy first_line = false end end |
#receive_line(line, ip_address) ⇒ Object
Invoked with lines received over the network
43 44 45 |
# File 'lib/gopher2000/dispatcher.rb', line 43 def receive_line(line, ip_address) call! Request.new(line, ip_address) end |
#remote_ip ⇒ Object
get the IP address of the client
17 18 19 |
# File 'lib/gopher2000/dispatcher.rb', line 17 def remote_ip Socket.unpack_sockaddr_in(get_peername).last end |
#send_response(response) ⇒ Object
send the response back to the client
76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/gopher2000/dispatcher.rb', line 76 def send_response(response) case response when Gopher::Response then send_response(response.body) when String then send_data(response + end_of_transmission) when StringIO then send_data(response.read + end_of_transmission) when File while chunk = response.read(8192) do send_data(chunk) end response.close end end |