Skip to content

Commit

Permalink
Fix serving files that clash with directories
Browse files Browse the repository at this point in the history
Jekyll extends WEBrick to serve file.html if file is requested but
doesn't exist (see jekyll#3452). This doesn't work if file exists as a
directory though.

This commit extends WEBrick further so that if file exists as a
directory, we first try and serve file/index.html (as normal), but
fallback to file.html if no index can be found within the file
directory (reported as jekyll#6222).

It is slightly hacky, to avoid having to re-implement the entire
set_filename method, we instead extend search_index_file and mutate
res.filename, reverting the change if it isn't needed.

See base class search_index_file implementation:

https://github.com/ruby/webrick/blob/3fb6a011/lib/webrick/httpservlet/filehandler.rb#L356-L363
  • Loading branch information
MattSturgeon committed Jul 19, 2017
1 parent 56546a2 commit 737461c
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion lib/jekyll/commands/serve/servlet.rb
Expand Up @@ -21,10 +21,36 @@ def initialize(server, root, callbacks)
# up with a different preference on which comes first.

def search_file(req, res, basename)
# /file.* > /file/index.html > /file.html
# /file.* -> /file.html
super || super(req, res, "#{basename}.html")
end

def search_index_file(req, res)
# /file/index.html -> /file.html

# First, let's see if the our super method can figure it out.
# (i.e Check for index.html files in the res.filename directory)
file = super

unless file
# Ok, I guess that didn't work, I guess there's no basename/index.html
# Let's look for basename.html instead...

# Split the basename from the path (res.filename)
i = res.filename.rindex "\/"
basename = res.filename[i..-1]
res.filename = res.filename[0, i]

# Try and find a file named dirname.html in the parent directory.
file = search_file(req, res, basename + ".html")

# If we didn't find a file, revert our changes to res.filename.
res.filename << basename unless file
end

return file
end

# rubocop:disable Style/MethodName
def do_GET(req, res)
rtn = super
Expand Down

0 comments on commit 737461c

Please sign in to comment.