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.
This commit is contained in:
Jordon Bedwell 2015-12-06 20:33:53 -06:00
parent fdf12efde4
commit 643ae68912
1 changed files with 34 additions and 31 deletions

View File

@ -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