diff options
Diffstat (limited to 'lib/nickserver')
| -rw-r--r-- | lib/nickserver/em_server.rb | 80 | ||||
| -rw-r--r-- | lib/nickserver/request_handler.rb | 85 | 
2 files changed, 97 insertions, 68 deletions
| 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 | 
