Class: WEBrick::HTTPServer
- Inherits:
-
GenericServer
- Object
- GenericServer
- WEBrick::HTTPServer
- Defined in:
- lib/webrick/httpserver.rb
Overview
An HTTP Server
Direct Known Subclasses
Defined Under Namespace
Classes: MountTable
Instance Attribute Summary
Attributes inherited from GenericServer
#config, #listeners, #logger, #status, #tokens
Instance Method Summary collapse
-
#access_log(config, req, res) ⇒ Object
Logs
req
andres
in the access logs. -
#do_OPTIONS(req, res) ⇒ Object
The default OPTIONS request handler says GET, HEAD, POST and OPTIONS requests are allowed.
-
#initialize(config = {}, default = Config::HTTP) ⇒ HTTPServer
constructor
Creates a new HTTP server according to
config
. -
#lookup_server(req) ⇒ Object
Finds the appropriate virtual host to handle
req
. -
#mount(dir, servlet, *options) ⇒ Object
Mounts
servlet
ondir
passingoptions
to the servlet at creation time. -
#mount_proc(dir, proc = nil, &block) ⇒ Object
Mounts
proc
orblock
ondir
and calls it with a WEBrick::HTTPRequest and WEBrick::HTTPResponse. -
#run(sock) ⇒ Object
Processes requests on
sock
. -
#search_servlet(path) ⇒ Object
Finds a servlet for
path
. -
#service(req, res) ⇒ Object
Services
req
and fills inres
. -
#unmount(dir) ⇒ Object
(also: #umount)
Unmounts
dir
. -
#virtual_host(server) ⇒ Object
Adds
server
as a virtual host.
Methods inherited from GenericServer
#[], #listen, #setup_ssl_context, #shutdown, #ssl_context, #start, #stop
Constructor Details
#initialize(config = {}, default = Config::HTTP) ⇒ HTTPServer
Creates a new HTTP server according to config
An HTTP server uses the following attributes:
- :AccessLog
-
An array of access logs. See WEBrick::AccessLog
- :BindAddress
-
Local address for the server to bind to
- :DocumentRoot
-
Root path to serve files from
- :DocumentRootOptions
-
Options for the default HTTPServlet::FileHandler
- :HTTPVersion
-
The HTTP version of this server
- :Port
-
Port to listen on
- :RequestCallback
-
Called with a request and response before each request is serviced.
- :RequestTimeout
-
Maximum time to wait between requests
- :ServerAlias
-
Array of alternate names for this server for virtual hosting
- :ServerName
-
Name for this server for virtual hosting
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/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 |
Instance Method Details
#access_log(config, req, res) ⇒ Object
Logs req
and res
in the access logs. config
is used for the server name.
218 219 220 221 222 223 |
# File 'lib/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 |
#do_OPTIONS(req, res) ⇒ Object
The default OPTIONS request handler says GET, HEAD, POST and OPTIONS requests are allowed.
145 146 147 |
# File 'lib/webrick/httpserver.rb', line 145 def do_OPTIONS(req, res) res["allow"] = "GET,HEAD,POST,OPTIONS" end |
#lookup_server(req) ⇒ Object
Finds the appropriate virtual host to handle req
205 206 207 208 209 210 211 212 |
# File 'lib/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 |
#mount(dir, servlet, *options) ⇒ Object
Mounts servlet
on dir
passing options
to the servlet at creation time
153 154 155 156 |
# File 'lib/webrick/httpserver.rb', line 153 def mount(dir, servlet, *) @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir)) @mount_tab[dir] = [ servlet, ] end |
#mount_proc(dir, proc = nil, &block) ⇒ Object
Mounts proc
or block
on dir
and calls it with a WEBrick::HTTPRequest and WEBrick::HTTPResponse
162 163 164 165 166 |
# File 'lib/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 |
#run(sock) ⇒ Object
Processes requests on sock
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/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.) 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 |
#search_servlet(path) ⇒ Object
Finds a servlet for path
180 181 182 183 184 185 186 |
# File 'lib/webrick/httpserver.rb', line 180 def search_servlet(path) script_name, path_info = @mount_tab.scan(path) servlet, = @mount_tab[script_name] if servlet [ servlet, , script_name, path_info ] end end |
#service(req, res) ⇒ Object
Services req
and fills in res
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/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, , 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, *) @logger.debug(format("%s is invoked.", si.class.name)) si.service(req, res) end |
#unmount(dir) ⇒ Object Also known as: umount
Unmounts dir
171 172 173 174 |
# File 'lib/webrick/httpserver.rb', line 171 def unmount(dir) @logger.debug(sprintf("unmount %s.", dir)) @mount_tab.delete(dir) end |
#virtual_host(server) ⇒ Object
Adds server
as a virtual host.
191 192 193 194 195 196 197 198 199 200 |
# File 'lib/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 |