mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/webrick/config.rb:
add WEBrick::Config::FileHandler[:AcceptableLanguages]. * lib/webrick/httpservlet/filehandler.rb (WEBrick::HTTPServlet::FileHandler#set_filename): search files having suffix of language-name which Accept-Language header field includes if :AcceptableLanguages options is present. * lib/webrick/httpservlet/filehandler.rb (WEBrick::HTTPServlet::FileHandler#get_servlet): new method to search servlet correspond to the suffix of filename. * lib/webrick/httprequest.rb: add attributes access methods: accept, accept_charset, accept_encoding, accept_language, content_length and content_type. * lib/webrick/httpresponse.rb: add attribute access methods: content_length, content_length=, content_type and content_type=. * lib/webrick/httputils.rb (WEBrick::HTTPUtils.mime_types): use the second suffix to detect media type. (the first suffix may be a language name.) * lib/webrick/httputils.rb (WEBrick::HTTPUtils.parse_qvalues): add method to parse Accept header field. it returns an Array of values sorted by the qvalues. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7033 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
90b337ce37
commit
385edf1e5c
6 changed files with 165 additions and 31 deletions
|
@ -126,7 +126,7 @@ module WEBrick
|
|||
end
|
||||
|
||||
class FileHandler < AbstractServlet
|
||||
HandlerTable = Hash.new(DefaultFileHandler)
|
||||
HandlerTable = Hash.new
|
||||
|
||||
def self.add_handler(suffix, handler)
|
||||
HandlerTable[suffix] = handler
|
||||
|
@ -201,8 +201,7 @@ module WEBrick
|
|||
def exec_handler(req, res)
|
||||
raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
|
||||
if set_filename(req, res)
|
||||
suffix = (/\.(\w+)$/ =~ res.filename) && $1
|
||||
handler = @options[:HandlerTable][suffix] || HandlerTable[suffix]
|
||||
handler = get_handler(req)
|
||||
call_callback(:HandlerCallback, req, res)
|
||||
h = handler.get_instance(@config, res.filename)
|
||||
h.service(req, res)
|
||||
|
@ -212,41 +211,95 @@ module WEBrick
|
|||
return false
|
||||
end
|
||||
|
||||
def get_handler(req)
|
||||
suffix1 = (/\.(\w+)$/ =~ req.script_name) && $1.downcase
|
||||
suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ req.script_name) && $1.downcase
|
||||
handler_table = @options[:HandlerTable]
|
||||
return handler_table[suffix1] || handler_table[suffix2] ||
|
||||
HandlerTable[suffix1] || HandlerTable[suffix2] ||
|
||||
DefaultFileHandler
|
||||
end
|
||||
|
||||
def set_filename(req, res)
|
||||
handler = nil
|
||||
res.filename = @root.dup
|
||||
path_info = req.path_info.scan(%r|/[^/]*|)
|
||||
|
||||
while name = path_info.shift
|
||||
if name == "/"
|
||||
indices = @config[:DirectoryIndex]
|
||||
index = indices.find{|i| FileTest::file?("#{res.filename}/#{i}") }
|
||||
name = "/#{index}" if index
|
||||
end
|
||||
res.filename << name
|
||||
req.script_name << name
|
||||
req.path_info = path_info.join
|
||||
path_info.unshift("") # dummy for checking @root dir
|
||||
while base = path_info.first
|
||||
check_filename(base)
|
||||
break if base == "/"
|
||||
break unless File.directory?(res.filename + base)
|
||||
shift_path_info(req, res, path_info)
|
||||
call_callback(:DirectoryCallback, req, res)
|
||||
end
|
||||
|
||||
if File::fnmatch("/#{@options[:NondisclosureName]}", name)
|
||||
@logger.log(Log::WARN,
|
||||
"the request refers nondisclosure name `#{name}'.")
|
||||
raise HTTPStatus::Forbidden, "`#{req.path}' not found."
|
||||
end
|
||||
st = (File::stat(res.filename) rescue nil)
|
||||
raise HTTPStatus::NotFound, "`#{req.path}' not found." unless st
|
||||
raise HTTPStatus::Forbidden,
|
||||
"no access permission to `#{req.path}'." unless st.readable?
|
||||
|
||||
if st.directory?
|
||||
call_callback(:DirectoryCallback, req, res)
|
||||
else
|
||||
if base = path_info.first
|
||||
check_filename(base)
|
||||
if base == "/"
|
||||
if file = search_index_file(req, res)
|
||||
shift_path_info(req, res, path_info, file)
|
||||
call_callback(:FileCallback, req, res)
|
||||
return true
|
||||
end
|
||||
shift_path_info(req, res, path_info)
|
||||
elsif file = search_file(req, res, base)
|
||||
shift_path_info(req, res, path_info, file)
|
||||
call_callback(:FileCallback, req, res)
|
||||
return true
|
||||
else
|
||||
raise HTTPStatus::NotFound, "`#{req.path}' not found."
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
def check_filename(name)
|
||||
if File.fnmatch("/#{@options[:NondisclosureName]}", name)
|
||||
@logger.warn("the request refers nondisclosure name `#{name}'.")
|
||||
raise HTTPStatus::NotFound, "`#{req.path}' not found."
|
||||
end
|
||||
end
|
||||
|
||||
def shift_path_info(req, res, path_info, base=nil)
|
||||
tmp = path_info.shift
|
||||
base = base || tmp
|
||||
req.path_info = path_info.join
|
||||
req.script_name << base
|
||||
res.filename << base
|
||||
end
|
||||
|
||||
def search_index_file(req, res)
|
||||
@config[:DirectoryIndex].each{|index|
|
||||
if file = search_file(req, res, "/"+index)
|
||||
return file
|
||||
end
|
||||
}
|
||||
return nil
|
||||
end
|
||||
|
||||
def search_file(req, res, basename)
|
||||
langs = @options[:AcceptableLanguages]
|
||||
path = res.filename + basename
|
||||
if File.file?(path)
|
||||
return basename
|
||||
elsif langs.size > 0
|
||||
req.accept_language.each{|lang|
|
||||
path_with_lang = path + ".#{lang}"
|
||||
if langs.member?(lang) && File.file?(path_with_lang)
|
||||
return basename + ".#{lang}"
|
||||
end
|
||||
}
|
||||
(langs - req.accept_language).each{|lang|
|
||||
path_with_lang = path + ".#{lang}"
|
||||
if File.file?(path_with_lang)
|
||||
return basename + ".#{lang}"
|
||||
end
|
||||
}
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def call_callback(callback_name, req, res)
|
||||
if cb = @options[callback_name]
|
||||
cb.call(req, res)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue