Maintenance of Ruby 2.0.0 ended on February 24, 2016. Read more
An HTTP Server
Creates a new HTTP server according to config
An HTTP server uses the following attributes:
An array of access logs. See WEBrick::AccessLog
Local address for the server to bind to
Root path to serve files from
Options for the default HTTPServlet::FileHandler
The HTTP version of this server
Port to listen on
Called with a request and response before each request is serviced.
Maximum time to wait between requests
Array of alternate names for this server for virtual hosting
Name for this server for virtual hosting
# File webrick/httpserver.rb, line 44 def initialize(config={}, default=Config::HTTP) super(config, default) @http_version = HTTPVersion::convert(@config[:HTTPVersion]) @mount_tab = MountTable.new if @config[:DocumentRoot] mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot], @config[:DocumentRootOptions]) end unless @config[:AccessLog] @config[:AccessLog] = [ [ $stderr, AccessLog::COMMON_LOG_FORMAT ], [ $stderr, AccessLog::REFERER_LOG_FORMAT ] ] end @virtual_hosts = Array.new end
Logs req
and res
in the access logs.
config
is used for the server name.
# File webrick/httpserver.rb, line 218 def access_log(config, req, res) param = AccessLog::setup_params(config, req, res) @config[:AccessLog].each{|logger, fmt| logger << AccessLog::format(fmt+"\n", param) } end
The default OPTIONS request handler says GET, HEAD, POST and OPTIONS requests are allowed.
# File webrick/httpserver.rb, line 145 def do_OPTIONS(req, res) res["allow"] = "GET,HEAD,POST,OPTIONS" end
Finds the appropriate virtual host to handle req
# File webrick/httpserver.rb, line 205 def lookup_server(req) @virtual_hosts.find{|s| (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) && (s[:Port].nil? || req.port == s[:Port]) && ((s[:ServerName].nil? || req.host == s[:ServerName]) || (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host})) } end
Mounts servlet
on dir
passing
options
to the servlet at creation time
# File webrick/httpserver.rb, line 153 def mount(dir, servlet, *options) @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir)) @mount_tab[dir] = [ servlet, options ] end
Mounts proc
or block
on dir
and
calls it with a WEBrick::HTTPRequest and WEBrick::HTTPResponse
# File webrick/httpserver.rb, line 162 def mount_proc(dir, proc=nil, &block) proc ||= block raise HTTPServerError, "must pass a proc or block" unless proc mount(dir, HTTPServlet::ProcHandler.new(proc)) end
Processes requests on sock
# File webrick/httpserver.rb, line 67 def run(sock) while true res = HTTPResponse.new(@config) req = HTTPRequest.new(@config) server = self begin timeout = @config[:RequestTimeout] while timeout > 0 break if IO.select([sock], nil, nil, 0.5) timeout = 0 if @status != :Running timeout -= 0.5 end raise HTTPStatus::EOFError if timeout <= 0 raise HTTPStatus::EOFError if sock.eof? req.parse(sock) res.request_method = req.request_method res.request_uri = req.request_uri res.request_http_version = req.http_version res.keep_alive = req.keep_alive? server = lookup_server(req) || self if callback = server[:RequestCallback] callback.call(req, res) elsif callback = server[:RequestHandler] msg = ":RequestHandler is deprecated, please use :RequestCallback" @logger.warn(msg) callback.call(req, res) end server.service(req, res) rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex res.set_error(ex) rescue HTTPStatus::Error => ex @logger.error(ex.message) res.set_error(ex) rescue HTTPStatus::Status => ex res.status = ex.code rescue StandardError => ex @logger.error(ex) res.set_error(ex, true) ensure if req.request_line if req.keep_alive? && res.keep_alive? req.fixup() end res.send_response(sock) server.access_log(@config, req, res) end end break if @http_version < "1.1" break unless req.keep_alive? break unless res.keep_alive? end end
Finds a servlet for path
# File webrick/httpserver.rb, line 180 def search_servlet(path) script_name, path_info = @mount_tab.scan(path) servlet, options = @mount_tab[script_name] if servlet [ servlet, options, script_name, path_info ] end end
Services req
and fills in res
# File webrick/httpserver.rb, line 123 def service(req, res) if req.unparsed_uri == "*" if req.request_method == "OPTIONS" do_OPTIONS(req, res) raise HTTPStatus::OK end raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found." end servlet, options, script_name, path_info = search_servlet(req.path) raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet req.script_name = script_name req.path_info = path_info si = servlet.get_instance(self, *options) @logger.debug(format("%s is invoked.", si.class.name)) si.service(req, res) end
Unmounts dir
# File webrick/httpserver.rb, line 171 def unmount(dir) @logger.debug(sprintf("unmount %s.", dir)) @mount_tab.delete(dir) end
Adds server
as a virtual host.
# File webrick/httpserver.rb, line 191 def virtual_host(server) @virtual_hosts << server @virtual_hosts = @virtual_hosts.sort_by{|s| num = 0 num -= 4 if s[:BindAddress] num -= 2 if s[:Port] num -= 1 if s[:ServerName] num } end