From cd67dfac8f764140c47e0fba9304eba168c7a25b Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 21 Jun 2016 12:33:52 +0200 Subject: refactor: change send_response -> respond in em_server This way the interface mimics the one of Celluloid Reels request. request.respond status, content --- lib/nickserver/em_server.rb | 8 ++++---- lib/nickserver/request_handler.rb | 14 +++++--------- test/unit/request_handler_test.rb | 3 +-- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/lib/nickserver/em_server.rb b/lib/nickserver/em_server.rb index bcec4cd..a983249 100644 --- a/lib/nickserver/em_server.rb +++ b/lib/nickserver/em_server.rb @@ -23,11 +23,11 @@ module Nickserver handler.respond_to params, @http_headers end - def send_response(options = {}) + def respond(status, content) response = EM::DelegatedHttpResponse.new(self) - response.status = options[:status] - response.content_type options[:content_type] - response.content = options[:content] + response.status = status + response.content_type 'text/plain' + response.content = content silence_warnings do response.send_response end diff --git a/lib/nickserver/request_handler.rb b/lib/nickserver/request_handler.rb index 26b6ec1..a3fd57d 100644 --- a/lib/nickserver/request_handler.rb +++ b/lib/nickserver/request_handler.rb @@ -38,7 +38,7 @@ module Nickserver source = Nickserver::Hkp::Source.new(adapter) end source.query(uid) do |response| - send_response(status: response.status, content: response.content) + send_response response.status, response.content end end @@ -64,19 +64,15 @@ module Nickserver end end def send_error(msg = "not supported") - send_response(status: 500, content: "500 #{msg}\n") + send_response 500, "500 #{msg}\n" end def send_not_found(msg = "Not Found") - send_response(status: 404, content: "404 #{msg}\n") + send_response 404, "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: ''} + def send_response(status = 200, content = '') + responder.respond status, content end attr_reader :responder, :adapter diff --git a/test/unit/request_handler_test.rb b/test/unit/request_handler_test.rb index c9d316f..7fe766e 100644 --- a/test/unit/request_handler_test.rb +++ b/test/unit/request_handler_test.rb @@ -21,8 +21,7 @@ class Nickserver::RequestHandlerTest < Minitest::Test end def assert_response(args) - args[:content_type] ||= 'text/plain' - responder.expect :send_response, nil, [args] + responder.expect :respond, nil, [args[:status], args[:content]] handler.respond_to @params, @headers responder.verify end -- cgit v1.2.3 From 298afc7ec1d7cb49f5f0b29e5a19f6bb72f179fa Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 24 Jun 2016 14:13:54 +0200 Subject: first attempt at using celluloid instead of em - broken Main problem right now is the outdated version of webmock. --- lib/nickserver/adapters/celluloid_http.rb | 17 ++++++++++++++++ lib/nickserver/reel_server.rb | 34 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 lib/nickserver/adapters/celluloid_http.rb create mode 100644 lib/nickserver/reel_server.rb diff --git a/lib/nickserver/adapters/celluloid_http.rb b/lib/nickserver/adapters/celluloid_http.rb new file mode 100644 index 0000000..5772bd1 --- /dev/null +++ b/lib/nickserver/adapters/celluloid_http.rb @@ -0,0 +1,17 @@ +require 'nickserver/adapters' +# require 'celluloid/io' +require 'http' + +module Nickserver::Adapters + class CelluloidHttp + # include Celluloid::IO + + def get(url, options = {}) + response = HTTP.get url, + params: options[:query] + # ssl_socket_class: Celluloid::IO::SSLSocket + yield response.code, response.to_s + end + + end +end diff --git a/lib/nickserver/reel_server.rb b/lib/nickserver/reel_server.rb new file mode 100644 index 0000000..c12c402 --- /dev/null +++ b/lib/nickserver/reel_server.rb @@ -0,0 +1,34 @@ +require 'celluloid/autostart' +require 'reel' +require 'nickserver/adapters/celluloid_http' +require 'nickserver/request_handler' + +module Nickserver + class ReelServer + + def self.start(options = {}) + Reel::Server::HTTP.run(options[:host], options[:port]) do |connection| + # Support multiple keep-alive requests per connection + connection.each_request do |request| + handler = handler_for(request) + handler.respond_to params(request), request.headers + end + end + end + + protected + + def self.handler_for(request) + RequestHandler.new(request, Nickserver::Adapters::CelluloidHttp.new) + end + + def self.params(request) + if request.query_string + CGI.parse request.query_string + else + CGI.parse request.body.to_s + end + end + + end +end -- cgit v1.2.3 From 4132d6e6db3755334ace352165991487802c6b82 Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 30 Jun 2016 11:22:36 +0200 Subject: update webmock version --- nickserver.gemspec | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/nickserver.gemspec b/nickserver.gemspec index 2efdbb1..9338b3c 100644 --- a/nickserver.gemspec +++ b/nickserver.gemspec @@ -18,10 +18,9 @@ Gem::Specification.new do |gem| gem.require_paths = ["lib"] gem.add_development_dependency 'rake' - gem.add_development_dependency 'minitest', '~> 5.2' - gem.add_development_dependency 'webmock', '~> 1.17' + gem.add_development_dependency 'minitest' + gem.add_development_dependency 'webmock' - gem.add_dependency 'eventmachine', '~> 1.0.9' - gem.add_dependency 'em-http-request', '~> 1.1' - gem.add_dependency 'eventmachine_httpserver', '~> 0.2' + gem.add_dependency 'reel' + gem.add_dependency 'http' end -- cgit v1.2.3 From 0491e79c4e5f16d38cf87e53290394e1eccfa2e9 Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 30 Jun 2016 11:23:45 +0200 Subject: Trying to replace EM base server with reel some tests are still broken. But at least they are running now. --- Gemfile | 3 ++ bin/nickserver | 6 +-- lib/nickserver/adapters/em_http.rb | 24 ---------- lib/nickserver/em_server.rb | 51 -------------------- lib/nickserver/hkp/source.rb | 1 + lib/nickserver/reel_server.rb | 24 ++++++---- lib/nickserver/request_handler.rb | 5 +- lib/nickserver/server.rb | 9 ++-- test/integration/hkp_test.rb | 26 ++++------ test/integration/nickserver_test.rb | 80 ++++++++++++------------------- test/test_helper.rb | 14 ++---- test/unit/adapters/celluloid_http_test.rb | 23 +++++++++ test/unit/adapters/em_http_test.rb | 25 ---------- 13 files changed, 97 insertions(+), 194 deletions(-) delete mode 100644 lib/nickserver/adapters/em_http.rb delete mode 100644 lib/nickserver/em_server.rb create mode 100644 test/unit/adapters/celluloid_http_test.rb delete mode 100644 test/unit/adapters/em_http_test.rb diff --git a/Gemfile b/Gemfile index 619272b..d3dc389 100644 --- a/Gemfile +++ b/Gemfile @@ -2,3 +2,6 @@ source 'https://rubygems.org' # Specify your gem's dependencies in keymachine.gemspec gemspec + +gem 'byebug' + diff --git a/bin/nickserver b/bin/nickserver index f3795bf..8cf0738 100755 --- a/bin/nickserver +++ b/bin/nickserver @@ -20,7 +20,5 @@ load_local_gem require 'nickserver' Nickserver::Daemon.run('nickserver') do - EventMachine.run do - Nickserver::Server.start - end -end \ No newline at end of file + Nickserver::Server.start +end diff --git a/lib/nickserver/adapters/em_http.rb b/lib/nickserver/adapters/em_http.rb deleted file mode 100644 index 16db5ae..0000000 --- a/lib/nickserver/adapters/em_http.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'nickserver/adapters' -require 'em-http' - -module Nickserver::Adapters - class EmHttp - - def initialize - @timeout = 5 - end - - def get(url, options = {}) - get_request(url, options).callback {|http| - yield http.response_header.status, http.response - }.errback {|http| - yield 0, http.error - } - end - - def get_request(url, options = {}) - @request = EventMachine::HttpRequest.new(url) - @request.get timeout: @timeout, query: options[:query] - end - end -end diff --git a/lib/nickserver/em_server.rb b/lib/nickserver/em_server.rb deleted file mode 100644 index a983249..0000000 --- a/lib/nickserver/em_server.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'eventmachine' -silence_warnings do - require 'evma_httpserver' -end -require 'nickserver/request_handler' - -module Nickserver - class EmServer < EM::Connection - include EM::HttpServer - - def self.start(options = {}) - EventMachine.run do - EM.start_server options[:host], options[:port], self - end - end - - def post_init - super - no_environment_strings - end - - def process_http_request - handler.respond_to params, @http_headers - end - - def respond(status, content) - response = EM::DelegatedHttpResponse.new(self) - response.status = status - response.content_type 'text/plain' - response.content = content - silence_warnings do - response.send_response - end - end - - private - - def handler - @handler ||= RequestHandler.new(self, Nickserver::Adapters::EmHttp.new) - end - - def params - if @http_query_string - CGI.parse(@http_query_string) - elsif @http_post_content - CGI.parse(@http_post_content) - end - end - - end -end diff --git a/lib/nickserver/hkp/source.rb b/lib/nickserver/hkp/source.rb index 8b2a62b..9c79546 100644 --- a/lib/nickserver/hkp/source.rb +++ b/lib/nickserver/hkp/source.rb @@ -1,3 +1,4 @@ +require 'nickserver/source' require 'nickserver/response' require 'nickserver/hkp/response' require 'nickserver/hkp/client' diff --git a/lib/nickserver/reel_server.rb b/lib/nickserver/reel_server.rb index c12c402..abda57f 100644 --- a/lib/nickserver/reel_server.rb +++ b/lib/nickserver/reel_server.rb @@ -4,25 +4,31 @@ require 'nickserver/adapters/celluloid_http' require 'nickserver/request_handler' module Nickserver - class ReelServer + class ReelServer < Reel::Server::HTTP def self.start(options = {}) - Reel::Server::HTTP.run(options[:host], options[:port]) do |connection| - # Support multiple keep-alive requests per connection - connection.each_request do |request| - handler = handler_for(request) - handler.respond_to params(request), request.headers - end + new(options[:host], options[:port]).run + end + + def initialize(host = "127.0.0.1", port = 3000) + super(host, port, &method(:on_connection)) + end + + def on_connection(connection) + connection.each_request do |request| + handler = handler_for(request) + handler.respond_to params(request), request.headers end end + protected - def self.handler_for(request) + def handler_for(request) RequestHandler.new(request, Nickserver::Adapters::CelluloidHttp.new) end - def self.params(request) + def params(request) if request.query_string CGI.parse request.query_string else diff --git a/lib/nickserver/request_handler.rb b/lib/nickserver/request_handler.rb index a3fd57d..a54653a 100644 --- a/lib/nickserver/request_handler.rb +++ b/lib/nickserver/request_handler.rb @@ -1,3 +1,6 @@ +require 'nickserver/hkp/source' +require 'nickserver/couch_db/source' + module Nickserver class RequestHandler @@ -54,7 +57,7 @@ module Nickserver return uid_domain == Config.domain else # no domain configured, use Host header - host_header = headers.split(/\0/).grep(/^Host: /).first + host_header = headers['Host'] if host_header.nil? send_error("HTTP request must include a Host header.") else diff --git a/lib/nickserver/server.rb b/lib/nickserver/server.rb index 174d6ac..b8f5604 100644 --- a/lib/nickserver/server.rb +++ b/lib/nickserver/server.rb @@ -1,9 +1,6 @@ require 'kernel_ext' require 'json' -require 'nickserver/em_server' -require 'nickserver/couch_db/source' -require 'nickserver/hkp/source' -require 'nickserver/adapters/em_http' +require 'nickserver/reel_server' # @@ -15,7 +12,7 @@ module Nickserver class Server # - # Starts the Nickserver. Must be run inside an EM.run block. + # Starts the Nickserver. # # Available options: # @@ -33,7 +30,7 @@ module Nickserver puts "Starting nickserver #{options[:host]}:#{options[:port]}" end - Nickserver::EmServer.start(options) + Nickserver::ReelServer.start(options) end diff --git a/test/integration/hkp_test.rb b/test/integration/hkp_test.rb index a824a3f..cbb8190 100644 --- a/test/integration/hkp_test.rb +++ b/test/integration/hkp_test.rb @@ -1,6 +1,6 @@ require 'test_helper' require 'nickserver/hkp/source' -require 'nickserver/adapters/em_http' +require 'nickserver/adapters/celluloid_http' class HkpTest < Minitest::Test @@ -89,9 +89,9 @@ class HkpTest < Minitest::Test ca_file = file_path('mayfirst-ca.pem') real_network do - stub_config(:hkp_url, hkp_url) do - stub_config(:hkp_ca_file, ca_file) do - #stub_config(:hkp_ca_file, file_path('autistici-ca.pem')) do + config.stub(:hkp_url, hkp_url) do + config.stub(:hkp_ca_file, ca_file) do + #config.stub(:hkp_ca_file, file_path('autistici-ca.pem')) do assert File.exist?(Nickserver::Config.hkp_ca_file) uid = 'elijah@riseup.net' assert_key_info_for_uid uid do |keys| @@ -112,26 +112,20 @@ class HkpTest < Minitest::Test end def assert_response_for_uid(uid, &block) - EM.run do - Nickserver::Hkp::Source.new(adapter).query uid do |response| - yield response - EM.stop - end + Nickserver::Hkp::Source.new(adapter).query uid do |response| + yield response end end def assert_key_info_for_uid(uid, &block) - EM.run do - Nickserver::Hkp::Source.new(adapter).search uid do |status, keys| - assert_equal 200, status - yield keys - EM.stop - end + Nickserver::Hkp::Source.new(adapter).search uid do |status, keys| + assert_equal 200, status + yield keys end end def adapter - Nickserver::Adapters::EmHttp.new + Nickserver::Adapters::CelluloidHttp.new end def fetch_key_info(body_source, uid, &block) diff --git a/test/integration/nickserver_test.rb b/test/integration/nickserver_test.rb index b4ff4da..00b2642 100644 --- a/test/integration/nickserver_test.rb +++ b/test/integration/nickserver_test.rb @@ -1,21 +1,27 @@ require 'test_helper' require 'json' +require 'celluloid/test' # # Some important notes to understanding these tests: # -# (1) Requests to localhost always bypass HTTP stub. +# (1) Requests to 127.0.0.1 always bypass HTTP stub. # -# (2) All requests to nickserver are to localhost. +# (2) All requests to nickserver are to 127.0.0.1. # # (3) the "Host" header for requests to nickserver must be set (or Config.domain set) # # (4) When stubbing requests to couchdb, the couchdb host is changed from the -# default (localhost) to a dummy value (notlocalhost). +# default (127.0.0.1) to a dummy value (notlocalhost). # class NickserverTest < Minitest::Test + def setup + super + Celluloid.shutdown; Celluloid.boot + end + def test_GET_served_via_SKS uid = 'cloudadmin@leap.se' key_id = 'E818C478D3141282F7590D29D041EB11B1647490' @@ -24,9 +30,8 @@ class NickserverTest < Minitest::Test start do params = {query: {"address" => uid}} - get(params) do |http| - assert_equal file_content(:leap_public_key), JSON.parse(http.response)["openpgp"] - stop + get(params) do |response| + assert_equal file_content(:leap_public_key), JSON.parse(response.to_s)["openpgp"] end end end @@ -39,9 +44,8 @@ class NickserverTest < Minitest::Test start do params = {body: {"address" => uid}} - post(params) do |http| - assert_equal file_content(:leap_public_key), JSON.parse(http.response)["openpgp"] - stop + post(params) do |response| + assert_equal file_content(:leap_public_key), JSON.parse(response.to_s)["openpgp"] end end end @@ -52,9 +56,8 @@ class NickserverTest < Minitest::Test stub_couch_response(uid, status: 404) do start do params = {query: {"address" => uid}, head: {host: domain}} - get(params) do |http| - assert_equal 404, http.response_header.status - stop + get(params) do |response| + assert_equal 404, response.code end end end @@ -66,9 +69,8 @@ class NickserverTest < Minitest::Test stub_couch_response(uid, body: file_content(:empty_couchdb_result)) do start do params = {query: {"address" => uid}, head: {host: domain}} - get(params) do |http| - assert_equal 404, http.response_header.status - stop + get(params) do |response| + assert_equal 404, response.code end end end @@ -80,9 +82,8 @@ class NickserverTest < Minitest::Test stub_couch_response(uid, body: file_content(:blue_couchdb_result)) do start do params = {query: {"address" => uid}, head: {host: domain}} - get(params) do |http| - assert_equal file_content(:blue_nickserver_result), http.response - stop + get(params) do |response| + assert_equal file_content(:blue_nickserver_result), response.to_s end end end @@ -90,9 +91,8 @@ class NickserverTest < Minitest::Test def test_GET_empty start do - get({}) do |http| - assert_equal "404 Not Found\n", http.response - stop + get({}) do |response| + assert_equal "404 Not Found\n", response.to_s end end end @@ -103,53 +103,35 @@ class NickserverTest < Minitest::Test # start nickserver # def start(timeout = 1) - Timeout::timeout(timeout) do - EM.run do - Nickserver::Server.start - EM.epoll - yield - end - end - rescue Timeout::Error - flunk 'EventMachine was not stopped before the timeout expired' + server = Nickserver::ReelServer.new '127.0.0.1', config.port + yield server + ensure + server.terminate if server && server.alive? end # # http GET requests to nickserver # def get(params, &block) - request(:get, params, &block) + request(:get, params[:query], &block) end # # http POST requests to nickserver # def post(params, &block) - request(:post, params, &block) + request(:post, params[:body], &block) end # # http request to nickserver # - # this works because http requests to localhost are not stubbed, but requests to other domains are. + # this works because http requests to 127.0.0.1 are not stubbed, but requests to other domains are. # def request(method, params) - EventMachine::HttpRequest.new("http://localhost:#{Nickserver::Config.port}/").send(method,params).callback {|http| - # p http.response_header.status - # p http.response_header - # p http.response - yield http - }.errback {|http| - flunk(http.error) if http.error - EM.stop - } - end - - # - # stop nickserver - # - def stop - EM.stop + request = HTTP.request method, "http://127.0.0.1:#{config.port}/", + params: params + yield request end end diff --git a/test/test_helper.rb b/test/test_helper.rb index afdd3f9..689928c 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -48,26 +48,22 @@ class Minitest::Test def stub_sks_get_reponse(key_id, opts = {}) options = {status: 200, body: ""}.merge(opts) - stub_http_request(:get, Nickserver::Config.hkp_url).with( + stub_http_request(:get, config.hkp_url).with( query: {op: 'get', search: "0x"+key_id, exact: 'on', options: 'mr'} ).to_return(options) end def stub_couch_response(uid, opts = {}) # can't stub localhost, so set couch_host to anything else - Nickserver::Config.stub :couch_host, 'notlocalhost' do + config.stub :couch_host, 'notlocalhost' do options = {status: 200, body: ""}.merge(opts) query = "\?key=#{"%22#{uid}%22"}&reduce=false" - stub_http_request(:get, /#{Regexp.escape(Nickserver::Config.couch_url)}.*#{query}/).to_return(options) + stub_http_request(:get, /#{Regexp.escape(config.couch_url)}.*#{query}/).to_return(options) yield end end - # - # temporarily stubs the config property for the duration of the given block - # - def stub_config(property, value, &block) - Nickserver::Config.stub(property, value, &block) + def config + Nickserver::Config end - end diff --git a/test/unit/adapters/celluloid_http_test.rb b/test/unit/adapters/celluloid_http_test.rb new file mode 100644 index 0000000..64c7a5d --- /dev/null +++ b/test/unit/adapters/celluloid_http_test.rb @@ -0,0 +1,23 @@ +require 'test_helper' +require 'nickserver/adapters/celluloid_http' +require 'byebug' + +class Nickserver::Adapters::CelluloidHttpTest < Minitest::Test + + def test_successful_request + url = 'http://url.to' + stub_http_request(:get, url) + .with(query: {key: :value}) + .to_return status: 200, body: 'body' + adapter.get(url, query: {key: :value}) do |status, body| + assert_equal 200, status + assert_equal 'body', body + end + end + + protected + + def adapter + @adapter ||= Nickserver::Adapters::CelluloidHttp.new + end +end diff --git a/test/unit/adapters/em_http_test.rb b/test/unit/adapters/em_http_test.rb deleted file mode 100644 index 659ff1b..0000000 --- a/test/unit/adapters/em_http_test.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'test_helper' -require 'nickserver/adapters/em_http' - -class Nickserver::Adapters::EmHttpTest < Minitest::Test - - def test_successful_request - url = 'http://url.to' - stub_http_request(:get, url) - .with(query: {key: :value}) - .to_return status: 200, body: 'body' - EM.run do - adapter.get(url, query: {key: :value}) do |status, body| - assert_equal 200, status - assert_equal 'body', body - EM.stop - end - end - end - - protected - - def adapter - Nickserver::Adapters::EmHttp.new - end -end -- cgit v1.2.3 From 7802da3d9684c5c78d34e0154f827221803b207b Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 30 Jun 2016 13:17:08 +0200 Subject: fix host header handling and tests --- lib/nickserver/request_handler.rb | 2 +- test/integration/nickserver_test.rb | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/nickserver/request_handler.rb b/lib/nickserver/request_handler.rb index a54653a..f6954f1 100644 --- a/lib/nickserver/request_handler.rb +++ b/lib/nickserver/request_handler.rb @@ -61,7 +61,7 @@ module Nickserver if host_header.nil? send_error("HTTP request must include a Host header.") else - host = host_header.split(':')[1].strip.sub(/^nicknym\./, '') + host = host_header.split(':')[0].strip.sub(/^nicknym\./, '') return uid_domain == host end end diff --git a/test/integration/nickserver_test.rb b/test/integration/nickserver_test.rb index 00b2642..f30d2ba 100644 --- a/test/integration/nickserver_test.rb +++ b/test/integration/nickserver_test.rb @@ -55,7 +55,7 @@ class NickserverTest < Minitest::Test uid = "bananas@" + domain stub_couch_response(uid, status: 404) do start do - params = {query: {"address" => uid}, head: {host: domain}} + params = {query: {"address" => uid}, head: {"Host" => domain}} get(params) do |response| assert_equal 404, response.code end @@ -81,7 +81,7 @@ class NickserverTest < Minitest::Test uid = "blue@" + domain stub_couch_response(uid, body: file_content(:blue_couchdb_result)) do start do - params = {query: {"address" => uid}, head: {host: domain}} + params = {query: {"address" => uid}, head: {"Host" => domain}} get(params) do |response| assert_equal file_content(:blue_nickserver_result), response.to_s end @@ -112,15 +112,15 @@ class NickserverTest < Minitest::Test # # http GET requests to nickserver # - def get(params, &block) - request(:get, params[:query], &block) + def get(options = {}, &block) + request(:get, params: options[:query], head: options[:head], &block) end # # http POST requests to nickserver # - def post(params, &block) - request(:post, params[:body], &block) + def post(options, &block) + request(:post, params: options[:body], head: options[:head], &block) end # @@ -128,10 +128,11 @@ class NickserverTest < Minitest::Test # # this works because http requests to 127.0.0.1 are not stubbed, but requests to other domains are. # - def request(method, params) - request = HTTP.request method, "http://127.0.0.1:#{config.port}/", - params: params - yield request + def request(method, options = {}) + response = HTTP. + headers(options.delete(:head)). + request method, "http://127.0.0.1:#{config.port}/", options + yield response end end -- cgit v1.2.3 From fe9a23419f9a875a98fc05dc22e2ad6c5f6dbe3b Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 30 Jun 2016 13:47:40 +0200 Subject: actually use celluloid io for http requests --- lib/nickserver/adapters/celluloid_http.rb | 6 +++--- test/integration/hkp_test.rb | 12 ++++++++++++ test/unit/adapters/celluloid_http_test.rb | 12 +++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/nickserver/adapters/celluloid_http.rb b/lib/nickserver/adapters/celluloid_http.rb index 5772bd1..5ded702 100644 --- a/lib/nickserver/adapters/celluloid_http.rb +++ b/lib/nickserver/adapters/celluloid_http.rb @@ -4,12 +4,12 @@ require 'http' module Nickserver::Adapters class CelluloidHttp - # include Celluloid::IO + include Celluloid::IO def get(url, options = {}) response = HTTP.get url, - params: options[:query] - # ssl_socket_class: Celluloid::IO::SSLSocket + params: options[:query], + ssl_socket_class: Celluloid::IO::SSLSocket yield response.code, response.to_s end diff --git a/test/integration/hkp_test.rb b/test/integration/hkp_test.rb index cbb8190..586b3ab 100644 --- a/test/integration/hkp_test.rb +++ b/test/integration/hkp_test.rb @@ -1,9 +1,21 @@ require 'test_helper' require 'nickserver/hkp/source' require 'nickserver/adapters/celluloid_http' +require 'celluloid/test' class HkpTest < Minitest::Test + def setup + super + Celluloid.boot + end + + def teardown + Celluloid.shutdown + super + end + + def test_key_info_expired fetch_key_info(:hkp_vindex_result, 'lemur@leap.se') do |keys| assert_equal 1, keys.length, 'should find a single key' diff --git a/test/unit/adapters/celluloid_http_test.rb b/test/unit/adapters/celluloid_http_test.rb index 64c7a5d..c3c58b1 100644 --- a/test/unit/adapters/celluloid_http_test.rb +++ b/test/unit/adapters/celluloid_http_test.rb @@ -1,9 +1,19 @@ require 'test_helper' require 'nickserver/adapters/celluloid_http' -require 'byebug' +require 'celluloid/test' class Nickserver::Adapters::CelluloidHttpTest < Minitest::Test + def setup + super + Celluloid.boot + end + + def teardown + Celluloid.shutdown + super + end + def test_successful_request url = 'http://url.to' stub_http_request(:get, url) -- cgit v1.2.3 From 39697391452a1306e4aef3a5126bd2b9639b5936 Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 30 Jun 2016 17:10:26 +0200 Subject: use proper ssl connection with ca_file - green! --- lib/nickserver/adapters/celluloid_http.rb | 6 ++++++ test/unit/adapters/celluloid_http_test.rb | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/nickserver/adapters/celluloid_http.rb b/lib/nickserver/adapters/celluloid_http.rb index 5ded702..9e5fa3b 100644 --- a/lib/nickserver/adapters/celluloid_http.rb +++ b/lib/nickserver/adapters/celluloid_http.rb @@ -9,9 +9,15 @@ module Nickserver::Adapters def get(url, options = {}) response = HTTP.get url, params: options[:query], + ssl_context: ctx, ssl_socket_class: Celluloid::IO::SSLSocket yield response.code, response.to_s end + def ctx + OpenSSL::SSL::SSLContext.new.tap do |ctx| + ctx.ca_file = Nickserver::Config.hkp_ca_file + end + end end end diff --git a/test/unit/adapters/celluloid_http_test.rb b/test/unit/adapters/celluloid_http_test.rb index c3c58b1..c9ea411 100644 --- a/test/unit/adapters/celluloid_http_test.rb +++ b/test/unit/adapters/celluloid_http_test.rb @@ -25,6 +25,15 @@ class Nickserver::Adapters::CelluloidHttpTest < Minitest::Test end end + def test_https_for_hkp + url = Nickserver::Config.hkp_url + real_network do + adapter.get url do |status, _body| + assert_equal 404, status + end + end + end + protected def adapter -- cgit v1.2.3 From 8a664a39bc3dd77a9c53fa5931f81c2b2b8b7295 Mon Sep 17 00:00:00 2001 From: Azul Date: Sat, 2 Jul 2016 10:49:48 +0200 Subject: minor: silence warnings and cleanup --- Gemfile | 3 --- lib/nickserver/adapters/celluloid_http.rb | 4 +++- lib/nickserver/reel_server.rb | 11 +++++++++-- lib/nickserver/server.rb | 1 - test/integration/hkp_test.rb | 1 - test/integration/nickserver_test.rb | 1 - test/test_helper.rb | 1 + test/unit/adapters/celluloid_http_test.rb | 1 - 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index d3dc389..619272b 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,3 @@ source 'https://rubygems.org' # Specify your gem's dependencies in keymachine.gemspec gemspec - -gem 'byebug' - diff --git a/lib/nickserver/adapters/celluloid_http.rb b/lib/nickserver/adapters/celluloid_http.rb index 9e5fa3b..1adfaca 100644 --- a/lib/nickserver/adapters/celluloid_http.rb +++ b/lib/nickserver/adapters/celluloid_http.rb @@ -1,5 +1,7 @@ require 'nickserver/adapters' -# require 'celluloid/io' +silence_warnings do + require 'celluloid/io' +end require 'http' module Nickserver::Adapters diff --git a/lib/nickserver/reel_server.rb b/lib/nickserver/reel_server.rb index abda57f..8e17bc6 100644 --- a/lib/nickserver/reel_server.rb +++ b/lib/nickserver/reel_server.rb @@ -1,5 +1,6 @@ -require 'celluloid/autostart' -require 'reel' +silence_warnings do + require 'reel' +end require 'nickserver/adapters/celluloid_http' require 'nickserver/request_handler' @@ -14,6 +15,12 @@ module Nickserver super(host, port, &method(:on_connection)) end + def handle_connection(*args) + silence_warnings do + super + end + end + def on_connection(connection) connection.each_request do |request| handler = handler_for(request) diff --git a/lib/nickserver/server.rb b/lib/nickserver/server.rb index b8f5604..8f4a49f 100644 --- a/lib/nickserver/server.rb +++ b/lib/nickserver/server.rb @@ -6,7 +6,6 @@ require 'nickserver/reel_server' # # This is the main HTTP server that clients connect to in order to fetch keys # -# For info on EM::HttpServer, see https://github.com/eventmachine/evma_httpserver # module Nickserver class Server diff --git a/test/integration/hkp_test.rb b/test/integration/hkp_test.rb index 586b3ab..09673cf 100644 --- a/test/integration/hkp_test.rb +++ b/test/integration/hkp_test.rb @@ -1,7 +1,6 @@ require 'test_helper' require 'nickserver/hkp/source' require 'nickserver/adapters/celluloid_http' -require 'celluloid/test' class HkpTest < Minitest::Test diff --git a/test/integration/nickserver_test.rb b/test/integration/nickserver_test.rb index f30d2ba..d179d7e 100644 --- a/test/integration/nickserver_test.rb +++ b/test/integration/nickserver_test.rb @@ -1,6 +1,5 @@ require 'test_helper' require 'json' -require 'celluloid/test' # # Some important notes to understanding these tests: diff --git a/test/test_helper.rb b/test/test_helper.rb index 689928c..1ed2a98 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -7,6 +7,7 @@ require 'minitest/autorun' silence_warnings do require 'webmock/minitest' end +require 'celluloid/test' require 'nickserver' require 'minitest/pride' require 'minitest/hell' diff --git a/test/unit/adapters/celluloid_http_test.rb b/test/unit/adapters/celluloid_http_test.rb index c9ea411..87e7f55 100644 --- a/test/unit/adapters/celluloid_http_test.rb +++ b/test/unit/adapters/celluloid_http_test.rb @@ -1,6 +1,5 @@ require 'test_helper' require 'nickserver/adapters/celluloid_http' -require 'celluloid/test' class Nickserver::Adapters::CelluloidHttpTest < Minitest::Test -- cgit v1.2.3 From fb2d7e6f8f1fceefbc8964d34369a867eb8f25bb Mon Sep 17 00:00:00 2001 From: Azul Date: Sat, 2 Jul 2016 12:03:46 +0200 Subject: refactor: replace blocks/yields with returns This became possible because we now use celluloid. Celluloid handles asynchronity without the need for callbacks or blocks. --- lib/nickserver/adapters/celluloid_http.rb | 2 +- lib/nickserver/couch_db/source.rb | 5 ++- lib/nickserver/hkp/client.rb | 6 ++-- lib/nickserver/hkp/source.rb | 35 ++++++++++---------- lib/nickserver/request_handler.rb | 5 ++- test/helpers/test_adapter.rb | 10 ------ test/integration/couch_db/source_test.rb | 8 +++-- test/integration/nickserver_test.rb | 7 +++- test/unit/adapters/celluloid_http_test.rb | 12 +++---- test/unit/couch_db/source_unit_test.rb | 5 ++- test/unit/hkp/client_test.rb | 53 +++++++++++++++++++++++++++++++ 11 files changed, 96 insertions(+), 52 deletions(-) delete mode 100644 test/helpers/test_adapter.rb create mode 100644 test/unit/hkp/client_test.rb diff --git a/lib/nickserver/adapters/celluloid_http.rb b/lib/nickserver/adapters/celluloid_http.rb index 1adfaca..d326b8a 100644 --- a/lib/nickserver/adapters/celluloid_http.rb +++ b/lib/nickserver/adapters/celluloid_http.rb @@ -13,7 +13,7 @@ module Nickserver::Adapters params: options[:query], ssl_context: ctx, ssl_socket_class: Celluloid::IO::SSLSocket - yield response.code, response.to_s + return response.code, response.to_s end def ctx diff --git a/lib/nickserver/couch_db/source.rb b/lib/nickserver/couch_db/source.rb index b30fdfc..7c3ad95 100644 --- a/lib/nickserver/couch_db/source.rb +++ b/lib/nickserver/couch_db/source.rb @@ -11,9 +11,8 @@ module Nickserver::CouchDB VIEW = '/_design/Identity/_view/pgp_key_by_email' def query(nick) - adapter.get url, query: query_for(nick) do |status, body| - yield Response.new(nick, status: status, body: body) - end + status, body = adapter.get url, query: query_for(nick) + Response.new(nick, status: status, body: body) end protected diff --git a/lib/nickserver/hkp/client.rb b/lib/nickserver/hkp/client.rb index 6bd239d..d9a9b48 100644 --- a/lib/nickserver/hkp/client.rb +++ b/lib/nickserver/hkp/client.rb @@ -21,7 +21,7 @@ module Nickserver; module Hkp # used to fetch an array of KeyInfo objects that match the given email # def get_key_infos_by_email(email, &block) - get op: 'vindex', search: email, fingerprint: 'on', &block + get op: 'vindex', search: email, fingerprint: 'on' end # @@ -35,10 +35,10 @@ module Nickserver; module Hkp attr_reader :adapter - def get(query, &block) + def get(query) # in practice, exact=on seems to have no effect query = {exact: 'on', options: 'mr'}.merge query - adapter.get Config.hkp_url, query: query, &block + adapter.get Config.hkp_url, query: query end end end; end diff --git a/lib/nickserver/hkp/source.rb b/lib/nickserver/hkp/source.rb index 9c79546..0d79856 100644 --- a/lib/nickserver/hkp/source.rb +++ b/lib/nickserver/hkp/source.rb @@ -14,22 +14,20 @@ require "nickserver/hkp/key_info" module Nickserver; module Hkp class Source < Nickserver::Source - def query(nick, &block) - search(nick) do |status, response| - if status == 200 - best = pick_best_key(response) - get_key_by_fingerprint(nick, best.keyid, &block) - else - yield Nickserver::Response.new(status, response) - end + def query(nick) + status, response = search(nick) + if status == 200 + best = pick_best_key(response) + get_key_by_fingerprint(nick, best.keyid) + else + Nickserver::Response.new(status, response) end end - def search(nick, &block) - client.get_key_infos_by_email(nick) do |status, response| - parser = ParseKeyInfo.new status, response - yield parser.status_for(nick), parser.response_for(nick) - end + def search(nick) + status, response = client.get_key_infos_by_email(nick) + parser = ParseKeyInfo.new status, response + return parser.status_for(nick), parser.response_for(nick) end protected @@ -45,12 +43,11 @@ module Nickserver; module Hkp end def get_key_by_fingerprint(nick, fingerprint) - client.get_key_by_fingerprint fingerprint do |status, response| - if status == 200 - yield Response.new nick, response - else - yield Nickserver::Response.new status, "HKP Request failed" - end + status, response = client.get_key_by_fingerprint fingerprint + if status == 200 + Response.new nick, response + else + Nickserver::Response.new status, "HKP Request failed" end end diff --git a/lib/nickserver/request_handler.rb b/lib/nickserver/request_handler.rb index f6954f1..295d3c0 100644 --- a/lib/nickserver/request_handler.rb +++ b/lib/nickserver/request_handler.rb @@ -40,9 +40,8 @@ module Nickserver else source = Nickserver::Hkp::Source.new(adapter) end - source.query(uid) do |response| - send_response response.status, response.content - end + response = source.query(uid) + send_response response.status, response.content end # diff --git a/test/helpers/test_adapter.rb b/test/helpers/test_adapter.rb deleted file mode 100644 index 46d4713..0000000 --- a/test/helpers/test_adapter.rb +++ /dev/null @@ -1,10 +0,0 @@ -class TestAdapter - def initialize(status, content) - @status = status - @content = content - end - - def get(url, opts) - yield @status, @content - end -end diff --git a/test/integration/couch_db/source_test.rb b/test/integration/couch_db/source_test.rb index 21e3642..cb1153e 100644 --- a/test/integration/couch_db/source_test.rb +++ b/test/integration/couch_db/source_test.rb @@ -1,6 +1,5 @@ require 'test_helper' require 'file_content' -require 'helpers/test_adapter' require 'nickserver/couch_db/source' module Nickserver::CouchDB @@ -8,12 +7,17 @@ module Nickserver::CouchDB include FileContent def test_couch_query_and_response - adapter = TestAdapter.new 200, file_content(:blue_couchdb_result) + adapter = adapter_returns 200, file_content(:blue_couchdb_result) source = Source.new adapter source.query 'blue@example.org' do |response| assert_equal 200, response.status assert_equal file_content(:blue_nickserver_result), response.content end end + + def adapter_returns(*return_values) + adapter = Minitest::Mock.new + adapter.expect :get, return_values, [String, Hash] + end end end diff --git a/test/integration/nickserver_test.rb b/test/integration/nickserver_test.rb index d179d7e..710c3a1 100644 --- a/test/integration/nickserver_test.rb +++ b/test/integration/nickserver_test.rb @@ -18,7 +18,12 @@ class NickserverTest < Minitest::Test def setup super - Celluloid.shutdown; Celluloid.boot + Celluloid.boot + end + + def teardown + Celluloid.shutdown + super end def test_GET_served_via_SKS diff --git a/test/unit/adapters/celluloid_http_test.rb b/test/unit/adapters/celluloid_http_test.rb index 87e7f55..4381b8f 100644 --- a/test/unit/adapters/celluloid_http_test.rb +++ b/test/unit/adapters/celluloid_http_test.rb @@ -18,18 +18,16 @@ class Nickserver::Adapters::CelluloidHttpTest < Minitest::Test stub_http_request(:get, url) .with(query: {key: :value}) .to_return status: 200, body: 'body' - adapter.get(url, query: {key: :value}) do |status, body| - assert_equal 200, status - assert_equal 'body', body - end + status, body = adapter.get(url, query: {key: :value}) + assert_equal 200, status + assert_equal 'body', body end def test_https_for_hkp url = Nickserver::Config.hkp_url real_network do - adapter.get url do |status, _body| - assert_equal 404, status - end + status, _body = adapter.get url + assert_equal 404, status end end diff --git a/test/unit/couch_db/source_unit_test.rb b/test/unit/couch_db/source_unit_test.rb index 19ea9bc..fd07808 100644 --- a/test/unit/couch_db/source_unit_test.rb +++ b/test/unit/couch_db/source_unit_test.rb @@ -7,10 +7,9 @@ module Nickserver::CouchDB def test_query address = "nick@domain.tl" adapter = Minitest::Mock.new - adapter.expect :get, nil, + adapter.expect :get, [200, nil], [String, {query: { reduce: "false", key: "\"#{address}\"" }}] - query = Source.new(adapter) - query.query address + Source.new(adapter).query address adapter.verify end end diff --git a/test/unit/hkp/client_test.rb b/test/unit/hkp/client_test.rb new file mode 100644 index 0000000..9784d0a --- /dev/null +++ b/test/unit/hkp/client_test.rb @@ -0,0 +1,53 @@ +require 'test_helper' +require 'nickserver/hkp/client' + +module Nickserver::Hkp + class ClientTest < Minitest::Test + + def test_get_key_infos_by_email + adapter_expects_query op: "vindex", + search: email, + options: "mr", + fingerprint: "on", + exact: "on" + client.get_key_infos_by_email(email) + @adapter.verify + end + + def test_key_by_fingerprint + adapter_expects_query op: "get", + search: "0x#{fingerprint}", + options: "mr", + exact: "on" + client.get_key_by_fingerprint(fingerprint) + @adapter.verify + end + + def client + @client ||= Client.new @adapter + end + + def adapter_expects_query(query = {}) + adapter_expects Nickserver::Config.hkp_url, query: query + end + + def adapter_expects(*args) + @adapter = Minitest::Mock.new + @adapter.expect :get, dummy_response, + args + end + + def email + 'dummy_email' + end + + def fingerprint + 'dummy_fingerprint' + end + + def dummy_response + [200, 'dummy_response'] + end + + end +end -- cgit v1.2.3 From e81c1a8cf274a13903be00c74c975c0cb2c20995 Mon Sep 17 00:00:00 2001 From: Azul Date: Sat, 2 Jul 2016 13:16:35 +0200 Subject: refactor: turn EmailAddress into a class, cleanup --- Gemfile | 2 ++ lib/nickserver/email_address.rb | 64 +++++++++++++++++++++++------------- lib/nickserver/hkp/client.rb | 5 +-- lib/nickserver/hkp/parse_key_info.rb | 10 +++--- lib/nickserver/nickname.rb | 51 ---------------------------- lib/nickserver/request_handler.rb | 48 +++++++++++++-------------- lib/server.rb | 19 ----------- test/unit/email_address_test.rb | 22 +++++++++++++ test/unit/nickname_test.rb | 28 ---------------- test/unit/request_handler_test.rb | 5 +++ 10 files changed, 103 insertions(+), 151 deletions(-) delete mode 100644 lib/nickserver/nickname.rb delete mode 100644 lib/server.rb create mode 100644 test/unit/email_address_test.rb delete mode 100644 test/unit/nickname_test.rb diff --git a/Gemfile b/Gemfile index 619272b..5d8013e 100644 --- a/Gemfile +++ b/Gemfile @@ -2,3 +2,5 @@ source 'https://rubygems.org' # Specify your gem's dependencies in keymachine.gemspec gemspec + +gem 'byebug' diff --git a/lib/nickserver/email_address.rb b/lib/nickserver/email_address.rb index 26053a2..2b3f2c2 100644 --- a/lib/nickserver/email_address.rb +++ b/lib/nickserver/email_address.rb @@ -1,25 +1,45 @@ -# -# This rather crazy regexp is from here: http://code.iamcal.com/php/rfc822/ -# Licensed GPLv3 -# -# It is too liberal, allowing "!@x" as a valid address, for example, but it does -# follow the specification rather closely. -# - module Nickserver - EmailAddress = begin - qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]' - dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]' - atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+' - quoted_pair = '\\x5c[\\x00-\\x7f]' - domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d" - quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22" - domain_ref = atom - sub_domain = "(?:#{domain_ref}|#{domain_literal})" - word = "(?:#{atom}|#{quoted_string})" - domain = "#{sub_domain}(?:\\x2e#{sub_domain})*" - local_part = "#{word}(?:\\x2e#{word})*" - addr_spec = "#{local_part}\\x40#{domain}" - /\A#{addr_spec}\z/n + class EmailAddress + + REGEXP = begin + qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]' + dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]' + atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+' + quoted_pair = '\\x5c[\\x00-\\x7f]' + domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d" + quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22" + domain_ref = atom + sub_domain = "(?:#{domain_ref}|#{domain_literal})" + word = "(?:#{atom}|#{quoted_string})" + domain = "#{sub_domain}(?:\\x2e#{sub_domain})*" + local_part = "#{word}(?:\\x2e#{word})*" + addr_spec = "#{local_part}\\x40#{domain}" + /\A#{addr_spec}\z/n + end + + def initialize(address) + @address = address.to_s + end + + def valid? + address =~ REGEXP + end + + def invalid? + !valid? + end + + def domain?(domain) + address.end_with? "@#{domain}" + end + + def to_s + address + end + + protected + + attr_reader :address + end end diff --git a/lib/nickserver/hkp/client.rb b/lib/nickserver/hkp/client.rb index d9a9b48..1fbe7a2 100644 --- a/lib/nickserver/hkp/client.rb +++ b/lib/nickserver/hkp/client.rb @@ -21,7 +21,7 @@ module Nickserver; module Hkp # used to fetch an array of KeyInfo objects that match the given email # def get_key_infos_by_email(email, &block) - get op: 'vindex', search: email, fingerprint: 'on' + get op: 'vindex', search: email.to_s, fingerprint: 'on' end # @@ -38,7 +38,8 @@ module Nickserver; module Hkp def get(query) # in practice, exact=on seems to have no effect query = {exact: 'on', options: 'mr'}.merge query - adapter.get Config.hkp_url, query: query + response = adapter.get Config.hkp_url, query: query + return response end end end; end diff --git a/lib/nickserver/hkp/parse_key_info.rb b/lib/nickserver/hkp/parse_key_info.rb index 9d59d6b..2f928a0 100644 --- a/lib/nickserver/hkp/parse_key_info.rb +++ b/lib/nickserver/hkp/parse_key_info.rb @@ -19,7 +19,8 @@ module Nickserver; module Hkp @vindex_result = vindex_result end - def status_for(uid) + def status_for(email) + uid = email.to_s if hkp_ok? && keys(uid).empty? error_status(uid) else @@ -27,7 +28,8 @@ module Nickserver; module Hkp end end - def response_for(uid) + def response_for(email) + uid = email.to_s if keys(uid).any? keys(uid) else @@ -35,6 +37,8 @@ module Nickserver; module Hkp end end + protected + def keys(uid) key_infos(uid).reject { |key| error_for_key(key) } end @@ -47,8 +51,6 @@ module Nickserver; module Hkp end end - protected - attr_reader :status attr_reader :vindex_result diff --git a/lib/nickserver/nickname.rb b/lib/nickserver/nickname.rb deleted file mode 100644 index 938d4a4..0000000 --- a/lib/nickserver/nickname.rb +++ /dev/null @@ -1,51 +0,0 @@ -module Nickserver - class Nickname - - EmailAddress = begin - qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]' - dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]' - atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+' - quoted_pair = '\\x5c[\\x00-\\x7f]' - domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d" - quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22" - domain_ref = atom - sub_domain = "(?:#{domain_ref}|#{domain_literal})" - word = "(?:#{atom}|#{quoted_string})" - domain = "#{sub_domain}(?:\\x2e#{sub_domain})*" - local_part = "#{word}(?:\\x2e#{word})*" - addr_spec = "#{local_part}\\x40#{domain}" - /\A#{addr_spec}\z/n - end - - LOCAL_DOMAIN = 'test.me' - - def initialize(address) - @address = address.to_s - end - - def valid? - address =~ EmailAddress - end - - def invalid? - !valid? - end - - def local? - address.end_with? LOCAL_DOMAIN - end - - def remote? - !local? - end - - def to_s - address - end - - protected - - attr_reader :address - - end -end diff --git a/lib/nickserver/request_handler.rb b/lib/nickserver/request_handler.rb index 295d3c0..608db83 100644 --- a/lib/nickserver/request_handler.rb +++ b/lib/nickserver/request_handler.rb @@ -10,13 +10,13 @@ module Nickserver end def respond_to(params, headers) - uid = get_uid_from_params(params) - if uid.nil? + email = get_email_from_params(params) + if email.nil? send_not_found - elsif uid !~ EmailAddress + elsif email.invalid? send_error("Not a valid address") else - send_key(uid, headers) + send_key(email, headers) end rescue RuntimeError => exc puts "Error: #{exc}" @@ -26,22 +26,22 @@ module Nickserver protected - def get_uid_from_params(params) + def get_email_from_params(params) if params && params["address"] && params["address"].any? - return params["address"].first - else - return nil + EmailAddress.new(params["address"].first) end end - def send_key(uid, headers) - if local_address?(uid, headers) + def send_key(email, headers) + if local_address?(email, headers) source = Nickserver::CouchDB::Source.new(adapter) else source = Nickserver::Hkp::Source.new(adapter) end - response = source.query(uid) + response = source.query(email) send_response response.status, response.content + rescue MissingHostHeader + send_error("HTTP request must include a Host header.") end # @@ -50,21 +50,17 @@ module Nickserver # # 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['Host'] - if host_header.nil? - send_error("HTTP request must include a Host header.") - else - host = host_header.split(':')[0].strip.sub(/^nicknym\./, '') - return uid_domain == host - end - end + def local_address?(email, headers) + email.domain?(Config.domain || domain_from_headers(headers)) end + + # no domain configured, use Host header + def domain_from_headers(headers) + host_header = headers['Host'] + raise MissingHostHeader if host_header.nil? + host_header.split(':')[0].strip.sub(/^nicknym\./, '') + end + def send_error(msg = "not supported") send_response 500, "500 #{msg}\n" end @@ -79,5 +75,7 @@ module Nickserver attr_reader :responder, :adapter + class MissingHostHeader < StandardError + end end end diff --git a/lib/server.rb b/lib/server.rb deleted file mode 100644 index 4e7cf51..0000000 --- a/lib/server.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Server - - def process_http_request - lookup.respond_with(Responder) - end - - def lookup - LookupFactory.lookup_for(nick) - end - - def nick - Nickname.new(request.address) - end - - def request - Request.new(params) - end - -end diff --git a/test/unit/email_address_test.rb b/test/unit/email_address_test.rb new file mode 100644 index 0000000..6d57a8c --- /dev/null +++ b/test/unit/email_address_test.rb @@ -0,0 +1,22 @@ +require 'test_helper' +require 'nickserver/email_address' + +class EmailAddressTest < Minitest::Test + + def test_domain + nick = Nickserver::EmailAddress.new 'nick@test.me' + assert nick.domain?('test.me') + assert !nick.domain?('est.me') + end + + def test_valid + nick = Nickserver::EmailAddress.new 'nick@remote.domain' + assert nick.valid? + end + + def test_invalid + nick = Nickserver::EmailAddress.new 'asdf' + assert nick.invalid? + end + +end diff --git a/test/unit/nickname_test.rb b/test/unit/nickname_test.rb deleted file mode 100644 index 8681545..0000000 --- a/test/unit/nickname_test.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'test_helper' -require 'nickserver/nickname' - -class NicknameTest < Minitest::Test - - def test_local - nick = Nickserver::Nickname.new 'nick@test.me' - assert nick.local? - assert !nick.remote? - end - - def test_remote - nick = Nickserver::Nickname.new 'nick@remote.domain' - assert !nick.local? - assert nick.remote? - end - - def test_valid - nick = Nickserver::Nickname.new 'nick@remote.domain' - assert nick.valid? - end - - def test_invalid - nick = Nickserver::Nickname.new 'asdf' - assert nick.invalid? - end - -end diff --git a/test/unit/request_handler_test.rb b/test/unit/request_handler_test.rb index 7fe766e..ef656f9 100644 --- a/test/unit/request_handler_test.rb +++ b/test/unit/request_handler_test.rb @@ -13,6 +13,11 @@ class Nickserver::RequestHandlerTest < Minitest::Test assert_response status: 500, content: "500 Not a valid address\n" end + def test_missing_domain + handle address: ['valid@email.tld'] + assert_response status: 500, content: "500 HTTP request must include a Host header.\n" + end + protected def handle(params = {}, headers = {}) -- cgit v1.2.3 From 6732fef4df156a02ed83f006f19f66cf567b5340 Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 4 Jul 2016 10:49:10 +0200 Subject: fix start / stop script I have to admit I don't completely understand what is going on here. https://github.com/celluloid/celluloid/wiki/Frequently-Asked-Questions says you can either use sleep after initiating the actors or call run on them. But this might not be true for reel. At least run did not work and now new; sleep seems to work fine. --- bin/nickserver | 1 + lib/nickserver/reel_server.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/nickserver b/bin/nickserver index 8cf0738..93dfd53 100755 --- a/bin/nickserver +++ b/bin/nickserver @@ -21,4 +21,5 @@ require 'nickserver' Nickserver::Daemon.run('nickserver') do Nickserver::Server.start + sleep end diff --git a/lib/nickserver/reel_server.rb b/lib/nickserver/reel_server.rb index 8e17bc6..6f05e0b 100644 --- a/lib/nickserver/reel_server.rb +++ b/lib/nickserver/reel_server.rb @@ -8,7 +8,7 @@ module Nickserver class ReelServer < Reel::Server::HTTP def self.start(options = {}) - new(options[:host], options[:port]).run + new(options[:host], options[:port]) end def initialize(host = "127.0.0.1", port = 3000) -- cgit v1.2.3