class Gopher::Dispatcher

Handle communication between Server and the actual gopher Application

Attributes

app[RW]

the Application we are running

Public Instance Methods

call!(request) click to toggle source

generate a request object from an incoming selector, and dispatch it to the app @param [Request] request Request object to handle @return Response object

# 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() click to toggle source

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

@return valid string to mark end of transmission as specified in RFC1436

# File lib/gopher2000/dispatcher.rb, line 93
def end_of_transmission
  [Gopher::Rendering::LINE_ENDING, ".", Gopher::Rendering::LINE_ENDING].join
end
receive_data(data) click to toggle source

called by EventMachine when there’s an incoming request

@param [String] selector incoming selector @return Response object

# 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) click to toggle source

Invoked with lines received over the network

# File lib/gopher2000/dispatcher.rb, line 43
def receive_line(line, ip_address)
  call! Request.new(line, ip_address)
end
remote_ip() click to toggle source

get the IP address of the client @return ip address

# File lib/gopher2000/dispatcher.rb, line 17
def remote_ip
  Socket.unpack_sockaddr_in(get_peername).last
end
send_response(response) click to toggle source

send the response back to the client @param [Response] response object

# 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