From 643ae6891271f9cfc481f9b42ecea890b2f9dcef Mon Sep 17 00:00:00 2001 From: Jordon Bedwell Date: Sun, 6 Dec 2015 20:33:53 -0600 Subject: [PATCH] Add a default charset to content-type on webrick. Add a default charset to content-type on webrick, using Jekyll's default encoding (or user set encoding) and cleanup servlet removing unecessary logic that really served no purpose at the end of the day, we don't need to strictly match Nginx, only be "like it." This also cleans up the way we set headers and merges that logic into a cleaner to understand interface that is slightly speedier. --- lib/jekyll/commands/serve/servlet.rb | 65 +++++++++++++++------------- 1 file changed, 34 insertions(+), 31 deletions(-) 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