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
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/webrick/httpserver.rb', line 46 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.
220 221 222 223 224 225 |
# File 'lib/webrick/httpserver.rb', line 220 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.
147 148 149 |
# File 'lib/webrick/httpserver.rb', line 147 def do_OPTIONS(req, res) res["allow"] = "GET,HEAD,POST,OPTIONS" end |
#lookup_server(req) ⇒ Object
Finds the appropriate virtual host to handle req
207 208 209 210 211 212 213 214 |
# File 'lib/webrick/httpserver.rb', line 207 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
155 156 157 158 |
# File 'lib/webrick/httpserver.rb', line 155 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
164 165 166 167 168 |
# File 'lib/webrick/httpserver.rb', line 164 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
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 119 120 |
# File 'lib/webrick/httpserver.rb', line 69 def run(sock) while true res = HTTPResponse.new(@config) req = HTTPRequest.new(@config) server = self begin timeout = @config[:RequestTimeout] while timeout > 0 break if sock.to_io.wait_readable(0.5) break if @status != :Running timeout -= 0.5 end raise HTTPStatus::EOFError if timeout <= 0 || @status != :Running 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
182 183 184 185 186 187 188 |
# File 'lib/webrick/httpserver.rb', line 182 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
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/webrick/httpserver.rb', line 125 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
173 174 175 176 |
# File 'lib/webrick/httpserver.rb', line 173 def unmount(dir) @logger.debug(sprintf("unmount %s.", dir)) @mount_tab.delete(dir) end |
#virtual_host(server) ⇒ Object
Adds server
as a virtual host.
193 194 195 196 197 198 199 200 201 202 |
# File 'lib/webrick/httpserver.rb', line 193 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 |