Class: Gopher::Dispatcher

Inherits:
EventMachine::Connection
  • Object
show all
Defined in:
lib/gopher2000/dispatcher.rb

Overview

Handle communication between Server and the actual gopher Application

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#appObject

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

Parameters:

  • request (Request)

    Request object to handle

Returns:

  • Response object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/gopher2000/dispatcher.rb', line 46

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_transmissionObject

Add the period on a line by itself that closes the connection

Returns:

  • valid string to mark end of transmission as specified in RFC1436



87
88
89
# File 'lib/gopher2000/dispatcher.rb', line 87

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

Parameters:

  • selector (String)

    incoming selector

Returns:

  • Response object



28
29
30
31
32
33
34
# File 'lib/gopher2000/dispatcher.rb', line 28

def receive_data data
  (@buf ||= '') << data
  
  while line = @buf.slice!(/(.*)\r?\n/)
    receive_line(line)
  end
end

#receive_line(line) ⇒ Object

Invoked with lines received over the network



37
38
39
# File 'lib/gopher2000/dispatcher.rb', line 37

def receive_line(line)
  call! Request.new(line, remote_ip)
end

#remote_ipObject

get the IP address of the client

Returns:

  • ip address



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

Parameters:



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/gopher2000/dispatcher.rb', line 70

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