diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/nickserver/em_server.rb | 107 | ||||
| -rw-r--r-- | lib/nickserver/server.rb | 107 | 
2 files changed, 115 insertions, 99 deletions
| diff --git a/lib/nickserver/em_server.rb b/lib/nickserver/em_server.rb new file mode 100644 index 0000000..faace4b --- /dev/null +++ b/lib/nickserver/em_server.rb @@ -0,0 +1,107 @@ +require 'eventmachine' +silence_warnings do +  require 'evma_httpserver' +end + +module Nickserver +  class EmServer < EM::Connection +    include EM::HttpServer + +    def self.start(options = {}) +      EventMachine.run do +        EM.start_server options[:host], options[:port], Nickserver::EmServer +      end +    end + +    def post_init +      super +      no_environment_strings +    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") +    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) +      response = EM::DelegatedHttpResponse.new(self) +      response.status = options[:status] +      response.content_type options[:content_type] +      response.content = options[:content] +      silence_warnings do +        response.send_response +      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 + +    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 +    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 +      end +    end + +    def adapter +      @adapter ||= Nickserver::Adapters::EmHttp.new +    end +  end +end diff --git a/lib/nickserver/server.rb b/lib/nickserver/server.rb index 2453f94..174d6ac 100644 --- a/lib/nickserver/server.rb +++ b/lib/nickserver/server.rb @@ -1,9 +1,6 @@  require 'kernel_ext' -require 'eventmachine' -silence_warnings do -  require 'evma_httpserver' -end  require 'json' +require 'nickserver/em_server'  require 'nickserver/couch_db/source'  require 'nickserver/hkp/source'  require 'nickserver/adapters/em_http' @@ -15,8 +12,7 @@ require 'nickserver/adapters/em_http'  # For info on EM::HttpServer, see https://github.com/eventmachine/evma_httpserver  #  module Nickserver -  class Server < EM::Connection -    include EM::HttpServer +  class Server      #      # Starts the Nickserver. Must be run inside an EM.run block. @@ -28,105 +24,18 @@ module Nickserver      #      def self.start(opts={})        Nickserver::Config.load -      options = {host: '127.0.0.1', port: Nickserver::Config.port.to_i}.merge(opts) +      options = { +        host: '127.0.0.1', +        port: Nickserver::Config.port.to_i +      }.merge(opts) +        unless defined?(TESTING)          puts "Starting nickserver #{options[:host]}:#{options[:port]}"        end -      EM.start_server options[:host], options[:port], Nickserver::Server -    end - -    def post_init -      super -      no_environment_strings -    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) +      Nickserver::EmServer.start(options)      end -    private - -    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 = {}) -      options = {status: 200, content_type: 'text/plain', content: ''}.merge(opts) -      response = EM::DelegatedHttpResponse.new(self) -      response.status = options[:status] -      response.content_type options[:content_type] -      response.content = options[:content] -      silence_warnings do -        response.send_response -      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 - -    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 -    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 -      end -    rescue # XXX what are we rescueing here? -      return false -    end - -    def adapter -      @adapter ||= Nickserver::Adapters::EmHttp.new -    end    end  end | 
