diff --git a/lib/jekyll/commands/serve/servlet.rb b/lib/jekyll/commands/serve/servlet.rb index cc6d958f..fa376f61 100644 --- a/lib/jekyll/commands/serve/servlet.rb +++ b/lib/jekyll/commands/serve/servlet.rb @@ -4,52 +4,55 @@ module Jekyll module Commands class Serve class Servlet < WEBrick::HTTPServlet::FileHandler - HEADER_DEFAULTS = {} + DEFAULTS = { + "Cache-Control" => "private, max-age=0, proxy-revalidate, " \ + "no-store, no-cache, must-revalidate" + } def initialize(server, root, callbacks) - extract_headers(server.config[:JekyllOptions]) + # So we can access them easily. + @jekyll_opts = server.config[:JekyllOptions] + set_defaults super 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, "#{basename}.html") + end + # def do_GET(req, res) - res.header.merge!(@headers) if @headers.any? - return super + rtn = super + validate_and_ensure_charset(req, res) + res.header.merge!(@headers) + rtn end - # file > file/index.html > file.html > directory -> Having a directory - # with the same name as a file will result in the file being served the way - # that Nginx behaves (probably not exactly...) For browsing. + # - def search_file(req, res, basename) - file = super || super(req, res, "#{basename}.html") + private + def validate_and_ensure_charset(req, res) + key = res.header.keys.grep(/content-type/i).first + typ = res.header[key] - return file if file - file = "#{req.path.gsub(/\/\Z/, "")}.html" - if file && File.file?(File.join(@config[:DocumentRoot], file)) - return ".html" - end - - nil - end - - def extract_headers(opts) - @headers = add_defaults(opts.fetch("webrick", {}).fetch("headers", { - # Nothing. - })) - end - - def add_defaults(opts) - control_development_cache(opts) - HEADER_DEFAULTS.each_with_object(opts) do |(k, v), h| - h[k] = v if !h[k] + unless typ =~ /;\s*charset=/ + res.header[key] = "#{typ}; charset=#{@jekyll_opts["encoding"]}" end end - def control_development_cache(opts) - if !opts.has_key?("Cache-Control") && Jekyll.env == "development" - opts["Cache-Control"] = "private, max-age=0, proxy-revalidate, no-store, no-cache, must-revalidate" + # + + private + def set_defaults + hash_ = @jekyll_opts.fetch("webrick", {}).fetch("headers", {}) + DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash| + hash[key] = val if !hash.key?(key) end end end