From f3d1c7903213a5237dddbe20ec5d6819fca34420 Mon Sep 17 00:00:00 2001 From: Dan Bernier Date: Fri, 26 Jul 2024 17:31:11 -0400 Subject: [PATCH 1/2] Test Puma::Acme::Middleware --- puma-acme.gemspec | 1 + test/puma/acme/middleware_test.rb | 57 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 test/puma/acme/middleware_test.rb diff --git a/puma-acme.gemspec b/puma-acme.gemspec index 4fd2fbd..d6925b3 100644 --- a/puma-acme.gemspec +++ b/puma-acme.gemspec @@ -30,6 +30,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'minitest', '~> 5.14' s.add_development_dependency 'minitest-mock_expectations', '~> 1.2' s.add_development_dependency 'r509', '~> 1.0' + s.add_development_dependency 'rack-test' s.add_development_dependency 'rake', '~> 13.0' s.add_development_dependency 'vcr', '~> 6.1' s.add_development_dependency 'webmock', '~> 3.19' diff --git a/test/puma/acme/middleware_test.rb b/test/puma/acme/middleware_test.rb new file mode 100644 index 0000000..5d7a27a --- /dev/null +++ b/test/puma/acme/middleware_test.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require_relative '../.././test_helper' +require "rack/test" + +module Puma + module Acme + class MiddlewareTest < Minitest::Test + include ::Rack::Test::Methods + + def test_it_returns_the_manager_answer_value_when_present + get '/.well-known/acme-challenge/good-token' + assert_equal '42', last_response.body + assert_equal 'text/plain;charset=utf-8', last_response.headers['content-type'] + end + + def test_it_passes_through_if_manager_provides_no_answer + get '/.well-known/acme-challenge/unknown-token' + assert_equal 'request not handled by middleware', last_response.body + end + + def test_it_passes_unrecognized_requests_through + get '/' + assert_equal 'request not handled by middleware', last_response.body + + get '/any-other/path' + assert_equal 'request not handled by middleware', last_response.body + end + + class App + def call(env) + [200, {}, ['request not handled by middleware']] + end + end + + class FakeManager + class Answer + def initialize(value) + @value = value + end + attr_reader :value + end + + def answer(type:, token:) + Answer.new('42') if token == 'good-token' + end + end + + def app + Puma::Acme::Middleware.new( + App.new, + manager: FakeManager.new + ) + end + end + end +end From 9e166803d264d98278192b95ead5fc27a8f4ee18 Mon Sep 17 00:00:00 2001 From: Dan Bernier Date: Fri, 26 Jul 2024 17:58:34 -0400 Subject: [PATCH 2/2] Rewrite Puma::Acme::Middleware w/o Sinatra --- lib/puma/acme/middleware.rb | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/puma/acme/middleware.rb b/lib/puma/acme/middleware.rb index 71204a9..db142f0 100644 --- a/lib/puma/acme/middleware.rb +++ b/lib/puma/acme/middleware.rb @@ -3,16 +3,18 @@ module Puma module Acme # ACME challenge response handler for HTTP-01 challenges. - class Middleware < Sinatra::Base + class Middleware def initialize(app, manager:) @app = app @manager = manager + end - super(app) + def call(env) + dup._call(env) end - get '/.well-known/acme-challenge/:token' do - if (token = params[:token]).nil? + def _call(env) + if (token = token(env)).nil? return @app.call(env) end @@ -20,8 +22,15 @@ def initialize(app, manager:) return @app.call(env) end - content_type 'text/plain' - answer.value + [200, {'content-type' => 'text/plain;charset=utf-8'}, [answer.value]] + end + + private + + def token(env) + path = ::Rack::Request.new(env).path_info + prefix = '/.well-known/acme-challenge/' + path[prefix.size..-1] if path.start_with?(prefix) end end end