From b185742d959a0a3854c5e628354a538a15bdea15 Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 20 Jun 2016 12:16:27 +0200 Subject: seperate generic RequestHandler from EmServer The request handler takes a responder (the EmServer) and an adapter as initialization arguments. It will then respond to requests by querying the sources using the adapter and calling send_response on the responder. --- lib/nickserver/em_server.rb | 80 ++++++------------------------------ lib/nickserver/request_handler.rb | 85 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 68 deletions(-) create mode 100644 lib/nickserver/request_handler.rb (limited to 'lib') diff --git a/lib/nickserver/em_server.rb b/lib/nickserver/em_server.rb index faace4b..bcec4cd 100644 --- a/lib/nickserver/em_server.rb +++ b/lib/nickserver/em_server.rb @@ -2,6 +2,7 @@ require 'eventmachine' silence_warnings do require 'evma_httpserver' end +require 'nickserver/request_handler' module Nickserver class EmServer < EM::Connection @@ -9,7 +10,7 @@ module Nickserver def self.start(options = {}) EventMachine.run do - EM.start_server options[:host], options[:port], Nickserver::EmServer + EM.start_server options[:host], options[:port], self end end @@ -19,32 +20,10 @@ module Nickserver end def process_http_request - uid = get_uid_from_request - if uid.nil? - send_not_found - elsif uid !~ EmailAddress - send_error("Not a valid address") - else - send_key(uid) - end - rescue RuntimeError => exc - puts "Error: #{exc}" - puts exc.backtrace - send_error(exc.to_s) - end - - private - - def send_error(msg = "not supported") - send_response(status: 500, content: "500 #{msg}\n") + handler.respond_to params, @http_headers end - def send_not_found(msg = "Not Found") - send_response(status: 404, content: "404 #{msg}\n") - end - - def send_response(opts = {}) - options = {status: 200, content_type: 'text/plain', content: ''}.merge(opts) + def send_response(options = {}) response = EM::DelegatedHttpResponse.new(self) response.status = options[:status] response.content_type options[:content_type] @@ -54,54 +33,19 @@ module Nickserver end end - def get_uid_from_request - if @http_query_string - params = CGI.parse(@http_query_string) - elsif @http_post_content - params = CGI.parse(@http_post_content) - end - if params && params["address"] && params["address"].any? - return params["address"].first - else - return nil - end - end + private - def send_key(uid) - if local_address?(uid) - source = Nickserver::CouchDB::Source.new(adapter) - else - source = Nickserver::Hkp::Source.new(adapter) - end - source.query(uid) do |response| - send_response(status: response.status, content: response.content) - end + def handler + @handler ||= RequestHandler.new(self, Nickserver::Adapters::EmHttp.new) end - # - # Return true if the user address is for a user of this service provider. - # e.g. if the provider is example.org, then alice@example.org returns true. - # - # If 'domain' is not configured, we rely on the Host header of the HTTP request. - # - def local_address?(uid) - uid_domain = uid.sub(/^.*@(.*)$/, "\\1") - if Config.domain - return uid_domain == Config.domain - else - # no domain configured, use Host header - host_header = @http_headers.split(/\0/).grep(/^Host: /).first - if host_header.nil? - send_error("HTTP request must include a Host header.") - else - host = host_header.split(':')[1].strip.sub(/^nicknym\./, '') - return uid_domain == host - end + def params + if @http_query_string + CGI.parse(@http_query_string) + elsif @http_post_content + CGI.parse(@http_post_content) end end - def adapter - @adapter ||= Nickserver::Adapters::EmHttp.new - end end end diff --git a/lib/nickserver/request_handler.rb b/lib/nickserver/request_handler.rb new file mode 100644 index 0000000..26b6ec1 --- /dev/null +++ b/lib/nickserver/request_handler.rb @@ -0,0 +1,85 @@ +module Nickserver + class RequestHandler + + def initialize(responder, adapter) + @responder = responder + @adapter = adapter + end + + def respond_to(params, headers) + uid = get_uid_from_params(params) + if uid.nil? + send_not_found + elsif uid !~ EmailAddress + send_error("Not a valid address") + else + send_key(uid, headers) + end + rescue RuntimeError => exc + puts "Error: #{exc}" + puts exc.backtrace + send_error(exc.to_s) + end + + protected + + def get_uid_from_params(params) + if params && params["address"] && params["address"].any? + return params["address"].first + else + return nil + end + end + + def send_key(uid, headers) + if local_address?(uid, headers) + source = Nickserver::CouchDB::Source.new(adapter) + else + source = Nickserver::Hkp::Source.new(adapter) + end + source.query(uid) do |response| + send_response(status: response.status, content: response.content) + end + end + + # + # Return true if the user address is for a user of this service provider. + # e.g. if the provider is example.org, then alice@example.org returns true. + # + # If 'domain' is not configured, we rely on the Host header of the HTTP request. + # + def local_address?(uid, headers) + uid_domain = uid.sub(/^.*@(.*)$/, "\\1") + if Config.domain + return uid_domain == Config.domain + else + # no domain configured, use Host header + host_header = headers.split(/\0/).grep(/^Host: /).first + if host_header.nil? + send_error("HTTP request must include a Host header.") + else + host = host_header.split(':')[1].strip.sub(/^nicknym\./, '') + return uid_domain == host + end + end + end + def send_error(msg = "not supported") + send_response(status: 500, content: "500 #{msg}\n") + end + + def send_not_found(msg = "Not Found") + send_response(status: 404, content: "404 #{msg}\n") + end + + def send_response(opts = {}) + responder.send_response default_response.merge(opts) + end + + def default_response + {status: 200, content_type: 'text/plain', content: ''} + end + + attr_reader :responder, :adapter + + end +end -- cgit v1.2.3