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 module Commands
class Serve class Serve
class Servlet < WEBrick::HTTPServlet::FileHandler 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) def initialize(server, root, callbacks)
extract_headers(server.config[:JekyllOptions]) # So we can access them easily.
@jekyll_opts = server.config[:JekyllOptions]
set_defaults
super super
end 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) def do_GET(req, res)
res.header.merge!(@headers) if @headers.any? rtn = super
return super validate_and_ensure_charset(req, res)
res.header.merge!(@headers)
rtn
end 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) private
file = super || super(req, res, "#{basename}.html") def validate_and_ensure_charset(req, res)
key = res.header.keys.grep(/content-type/i).first
typ = res.header[key]
return file if file unless typ =~ /;\s*charset=/
file = "#{req.path.gsub(/\/\Z/, "")}.html" res.header[key] = "#{typ}; charset=#{@jekyll_opts["encoding"]}"
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]
end end
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 end
end end