diff --git a/lib/jekyll/commands/serve/servlet.rb b/lib/jekyll/commands/serve/servlet.rb index 2e41b697524..70b6d66df34 100644 --- a/lib/jekyll/commands/serve/servlet.rb +++ b/lib/jekyll/commands/serve/servlet.rb @@ -18,13 +18,17 @@ def initialize(server, root, callbacks) super end + def search_index_file(req, res) + super || search_file(req, res, ".html") + end + # Add the ability to tap file.html the same way that Nginx does on our # Docker images (or on GitHub Pages.) The difference is that we might end # up with a different preference on which comes first. def search_file(req, res, basename) # /file.* > /file/index.html > /file.html - super || super(req, res, ".html") || super(req, res, "#{basename}.html") + super || super(req, res, "#{basename}.html") end # rubocop:disable Naming/MethodName diff --git a/test/fixtures/webrick/bar.html b/test/fixtures/webrick/bar.html new file mode 100644 index 00000000000..76870bf2f38 --- /dev/null +++ b/test/fixtures/webrick/bar.html @@ -0,0 +1 @@ +Content of bar.html diff --git a/test/fixtures/webrick/bar/baz.html b/test/fixtures/webrick/bar/baz.html new file mode 100644 index 00000000000..794d5f2202d --- /dev/null +++ b/test/fixtures/webrick/bar/baz.html @@ -0,0 +1 @@ +Content of baz.html diff --git a/test/helper.rb b/test/helper.rb index 672fedd2862..aa94be13e61 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -44,6 +44,8 @@ def jruby? include Jekyll +require "jekyll/commands/serve/servlet" + # Report with color. Minitest::Reporters.use! [ Minitest::Reporters::DefaultReporter.new( @@ -194,3 +196,55 @@ def skip_if_windows(msg = nil) end end end + +class FakeLogger + def <<(str); end +end + +module TestWEBrick + + module_function + + def mount_server(&block) + server = WEBrick::HTTPServer.new(config) + + begin + server.mount("/", Jekyll::Commands::Serve::Servlet, document_root, + document_root_options) + + server.start + addr = server.listeners[0].addr + block.yield([server, addr[3], addr[1]]) + rescue StandardError => e + raise e + ensure + server.shutdown + sleep 0.1 until server.status == :Stop + end + end + + def config + logger = FakeLogger.new + { + :BindAddress => "127.0.0.1", :Port => 0, + :ShutdownSocketWithoutClose => true, + :ServerType => Thread, + :Logger => WEBrick::Log.new(logger), + :AccessLog => [[logger, ""]], + :JekyllOptions => {}, + } + end + + def document_root + "#{File.dirname(__FILE__)}/fixtures/webrick" + end + + def document_root_options + WEBrick::Config::FileHandler.merge({ + :FancyIndexing => true, + :NondisclosureName => [ + ".ht*", "~*", + ], + }) + end +end diff --git a/test/test_commands_serve_servlet.rb b/test/test_commands_serve_servlet.rb new file mode 100644 index 00000000000..1f84cbbbe64 --- /dev/null +++ b/test/test_commands_serve_servlet.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require "webrick" +require "helper" +require "net/http" + +class TestCommandsServeServlet < JekyllUnitTest + def get(path) + TestWEBrick.mount_server do |_server, addr, port| + http = Net::HTTP.new(addr, port) + req = Net::HTTP::Get.new(path) + + http.request(req) { |response| yield(response) } + end + end + + context "with a directory and file with the same name" do + should "find that file" do + get("/bar/") do |response| + assert_equal("200", response.code) + assert_equal("Content of bar.html", response.body.strip) + end + end + + should "find file in directory" do + get("/bar/baz") do |response| + assert_equal("200", response.code) + assert_equal("Content of baz.html", response.body.strip) + end + end + + should "return 404 for non-existing files" do + get("/bar/missing") do |response| + assert_equal("404", response.code) + end + end + end +end