| Class | WEBrick::HTTPServer |
| In: |
lib/webrick/httpserver.rb
|
| Parent: | ::WEBrick::GenericServer |
# File lib/webrick/httpserver.rb, line 23
23: def initialize(config={}, default=Config::HTTP)
24: super
25: @http_version = HTTPVersion::convert(@config[:HTTPVersion])
26:
27: @mount_tab = MountTable.new
28: if @config[:DocumentRoot]
29: mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot],
30: @config[:DocumentRootOptions])
31: end
32:
33: unless @config[:AccessLog]
34: @config[:AccessLog] = [
35: [ $stderr, AccessLog::COMMON_LOG_FORMAT ],
36: [ $stderr, AccessLog::REFERER_LOG_FORMAT ]
37: ]
38: end
39:
40: @virtual_hosts = Array.new
41: end
# File lib/webrick/httpserver.rb, line 156
156: def access_log(config, req, res)
157: param = AccessLog::setup_params(config, req, res)
158: @config[:AccessLog].each{|logger, fmt|
159: logger << AccessLog::format(fmt+"\n", param)
160: }
161: end
# File lib/webrick/httpserver.rb, line 107
107: def do_OPTIONS(req, res)
108: res["allow"] = "GET,HEAD,POST,OPTIONS"
109: end
# File lib/webrick/httpserver.rb, line 147
147: def lookup_server(req)
148: @virtual_hosts.find{|s|
149: (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
150: (s[:Port].nil? || req.port == s[:Port]) &&
151: ((s[:ServerName].nil? || req.host == s[:ServerName]) ||
152: (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))
153: }
154: end
# File lib/webrick/httpserver.rb, line 111
111: def mount(dir, servlet, *options)
112: @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir))
113: @mount_tab[dir] = [ servlet, options ]
114: end
# File lib/webrick/httpserver.rb, line 116
116: def mount_proc(dir, proc=nil, &block)
117: proc ||= block
118: raise HTTPServerError, "must pass a proc or block" unless proc
119: mount(dir, HTTPServlet::ProcHandler.new(proc))
120: end
# File lib/webrick/httpserver.rb, line 43
43: def run(sock)
44: while true
45: res = HTTPResponse.new(@config)
46: req = HTTPRequest.new(@config)
47: server = self
48: begin
49: timeout = @config[:RequestTimeout]
50: while timeout > 0
51: break if IO.select([sock], nil, nil, 0.5)
52: timeout = 0 if @status != :Running
53: timeout -= 0.5
54: end
55: raise HTTPStatus::EOFError if timeout <= 0 || sock.eof?
56: req.parse(sock)
57: res.request_method = req.request_method
58: res.request_uri = req.request_uri
59: res.request_http_version = req.http_version
60: res.keep_alive = req.keep_alive?
61: server = lookup_server(req) || self
62: if callback = server[:RequestCallback] || server[:RequestHandler]
63: callback.call(req, res)
64: end
65: server.service(req, res)
66: rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
67: res.set_error(ex)
68: rescue HTTPStatus::Error => ex
69: @logger.error(ex.message)
70: res.set_error(ex)
71: rescue HTTPStatus::Status => ex
72: res.status = ex.code
73: rescue StandardError => ex
74: @logger.error(ex)
75: res.set_error(ex, true)
76: ensure
77: if req.request_line
78: req.fixup()
79: res.send_response(sock)
80: server.access_log(@config, req, res)
81: end
82: end
83: break if @http_version < "1.1"
84: break unless req.keep_alive?
85: break unless res.keep_alive?
86: end
87: end
# File lib/webrick/httpserver.rb, line 128
128: def search_servlet(path)
129: script_name, path_info = @mount_tab.scan(path)
130: servlet, options = @mount_tab[script_name]
131: if servlet
132: [ servlet, options, script_name, path_info ]
133: end
134: end
# File lib/webrick/httpserver.rb, line 89
89: def service(req, res)
90: if req.unparsed_uri == "*"
91: if req.request_method == "OPTIONS"
92: do_OPTIONS(req, res)
93: raise HTTPStatus::OK
94: end
95: raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found."
96: end
97:
98: servlet, options, script_name, path_info = search_servlet(req.path)
99: raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet
100: req.script_name = script_name
101: req.path_info = path_info
102: si = servlet.get_instance(self, *options)
103: @logger.debug(format("%s is invoked.", si.class.name))
104: si.service(req, res)
105: end
# File lib/webrick/httpserver.rb, line 122
122: def unmount(dir)
123: @logger.debug(sprintf("unmount %s.", dir))
124: @mount_tab.delete(dir)
125: end