rubysl-webrick 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +14 -6
- data/.travis.yml +5 -6
- data/lib/rubysl/webrick/version.rb +1 -1
- data/lib/rubysl/webrick/webrick.rb +199 -2
- data/lib/webrick/accesslog.rb +96 -5
- data/lib/webrick/cgi.rb +80 -29
- data/lib/webrick/compat.rb +20 -0
- data/lib/webrick/config.rb +59 -5
- data/lib/webrick/cookie.rb +66 -5
- data/lib/webrick/htmlutils.rb +4 -1
- data/lib/webrick/httpauth.rb +53 -3
- data/lib/webrick/httpauth/authenticator.rb +53 -16
- data/lib/webrick/httpauth/basicauth.rb +45 -2
- data/lib/webrick/httpauth/digestauth.rb +82 -17
- data/lib/webrick/httpauth/htdigest.rb +38 -1
- data/lib/webrick/httpauth/htgroup.rb +32 -0
- data/lib/webrick/httpauth/htpasswd.rb +40 -2
- data/lib/webrick/httpauth/userdb.rb +27 -4
- data/lib/webrick/httpproxy.rb +197 -112
- data/lib/webrick/httprequest.rb +268 -50
- data/lib/webrick/httpresponse.rb +170 -33
- data/lib/webrick/https.rb +26 -3
- data/lib/webrick/httpserver.rb +75 -7
- data/lib/webrick/httpservlet/abstract.rb +88 -6
- data/lib/webrick/httpservlet/cgi_runner.rb +5 -4
- data/lib/webrick/httpservlet/cgihandler.rb +37 -18
- data/lib/webrick/httpservlet/erbhandler.rb +40 -7
- data/lib/webrick/httpservlet/filehandler.rb +116 -28
- data/lib/webrick/httpservlet/prochandler.rb +17 -4
- data/lib/webrick/httpstatus.rb +86 -18
- data/lib/webrick/httputils.rb +131 -23
- data/lib/webrick/httpversion.rb +28 -2
- data/lib/webrick/log.rb +72 -5
- data/lib/webrick/server.rb +158 -33
- data/lib/webrick/ssl.rb +78 -9
- data/lib/webrick/utils.rb +151 -5
- data/lib/webrick/version.rb +5 -1
- data/rubysl-webrick.gemspec +0 -1
- metadata +12 -24
data/lib/webrick/httpresponse.rb
CHANGED
@@ -15,21 +15,85 @@ require 'webrick/httputils'
|
|
15
15
|
require 'webrick/httpstatus'
|
16
16
|
|
17
17
|
module WEBrick
|
18
|
+
##
|
19
|
+
# An HTTP response. This is filled in by the service or do_* methods of a
|
20
|
+
# WEBrick HTTP Servlet.
|
21
|
+
|
18
22
|
class HTTPResponse
|
19
|
-
BUFSIZE = 1024*4
|
20
23
|
|
21
|
-
|
24
|
+
##
|
25
|
+
# HTTP Response version
|
26
|
+
|
27
|
+
attr_reader :http_version
|
28
|
+
|
29
|
+
##
|
30
|
+
# Response status code (200)
|
31
|
+
|
32
|
+
attr_reader :status
|
33
|
+
|
34
|
+
##
|
35
|
+
# Response header
|
36
|
+
|
37
|
+
attr_reader :header
|
38
|
+
|
39
|
+
##
|
40
|
+
# Response cookies
|
41
|
+
|
22
42
|
attr_reader :cookies
|
43
|
+
|
44
|
+
##
|
45
|
+
# Response reason phrase ("OK")
|
46
|
+
|
23
47
|
attr_accessor :reason_phrase
|
48
|
+
|
49
|
+
##
|
50
|
+
# Body may be a String or IO subclass.
|
51
|
+
|
24
52
|
attr_accessor :body
|
25
53
|
|
26
|
-
|
54
|
+
##
|
55
|
+
# Request method for this response
|
56
|
+
|
57
|
+
attr_accessor :request_method
|
58
|
+
|
59
|
+
##
|
60
|
+
# Request URI for this response
|
61
|
+
|
62
|
+
attr_accessor :request_uri
|
63
|
+
|
64
|
+
##
|
65
|
+
# Request HTTP version for this response
|
66
|
+
|
67
|
+
attr_accessor :request_http_version
|
68
|
+
|
69
|
+
##
|
70
|
+
# Filename of the static file in this response. Only used by the
|
71
|
+
# FileHandler servlet.
|
72
|
+
|
27
73
|
attr_accessor :filename
|
74
|
+
|
75
|
+
##
|
76
|
+
# Is this a keep-alive response?
|
77
|
+
|
28
78
|
attr_accessor :keep_alive
|
29
|
-
|
79
|
+
|
80
|
+
##
|
81
|
+
# Configuration for this response
|
82
|
+
|
83
|
+
attr_reader :config
|
84
|
+
|
85
|
+
##
|
86
|
+
# Bytes sent in this response
|
87
|
+
|
88
|
+
attr_reader :sent_size
|
89
|
+
|
90
|
+
##
|
91
|
+
# Creates a new HTTP response object. WEBrick::Config::HTTP is the
|
92
|
+
# default configuration.
|
30
93
|
|
31
94
|
def initialize(config)
|
32
95
|
@config = config
|
96
|
+
@buffer_size = config[:OutputBufferSize]
|
33
97
|
@logger = config[:Logger]
|
34
98
|
@header = Hash.new
|
35
99
|
@status = HTTPStatus::RC_OK
|
@@ -46,58 +110,97 @@ module WEBrick
|
|
46
110
|
@sent_size = 0
|
47
111
|
end
|
48
112
|
|
113
|
+
##
|
114
|
+
# The response's HTTP status line
|
115
|
+
|
49
116
|
def status_line
|
50
117
|
"HTTP/#@http_version #@status #@reason_phrase #{CRLF}"
|
51
118
|
end
|
52
119
|
|
120
|
+
##
|
121
|
+
# Sets the response's status to the +status+ code
|
122
|
+
|
53
123
|
def status=(status)
|
54
124
|
@status = status
|
55
125
|
@reason_phrase = HTTPStatus::reason_phrase(status)
|
56
126
|
end
|
57
127
|
|
128
|
+
##
|
129
|
+
# Retrieves the response header +field+
|
130
|
+
|
58
131
|
def [](field)
|
59
132
|
@header[field.downcase]
|
60
133
|
end
|
61
134
|
|
135
|
+
##
|
136
|
+
# Sets the response header +field+ to +value+
|
137
|
+
|
62
138
|
def []=(field, value)
|
63
139
|
@header[field.downcase] = value.to_s
|
64
140
|
end
|
65
141
|
|
142
|
+
##
|
143
|
+
# The content-length header
|
144
|
+
|
66
145
|
def content_length
|
67
146
|
if len = self['content-length']
|
68
147
|
return Integer(len)
|
69
148
|
end
|
70
149
|
end
|
71
150
|
|
151
|
+
##
|
152
|
+
# Sets the content-length header to +len+
|
153
|
+
|
72
154
|
def content_length=(len)
|
73
155
|
self['content-length'] = len.to_s
|
74
156
|
end
|
75
157
|
|
158
|
+
##
|
159
|
+
# The content-type header
|
160
|
+
|
76
161
|
def content_type
|
77
162
|
self['content-type']
|
78
163
|
end
|
79
164
|
|
165
|
+
##
|
166
|
+
# Sets the content-type header to +type+
|
167
|
+
|
80
168
|
def content_type=(type)
|
81
169
|
self['content-type'] = type
|
82
170
|
end
|
83
171
|
|
172
|
+
##
|
173
|
+
# Iterates over each header in the resopnse
|
174
|
+
|
84
175
|
def each
|
85
|
-
@header.each{|
|
176
|
+
@header.each{|field, value| yield(field, value) }
|
86
177
|
end
|
87
178
|
|
179
|
+
##
|
180
|
+
# Will this response body be returned using chunked transfer-encoding?
|
181
|
+
|
88
182
|
def chunked?
|
89
183
|
@chunked
|
90
184
|
end
|
91
185
|
|
186
|
+
##
|
187
|
+
# Enables chunked transfer encoding.
|
188
|
+
|
92
189
|
def chunked=(val)
|
93
190
|
@chunked = val ? true : false
|
94
191
|
end
|
95
192
|
|
193
|
+
##
|
194
|
+
# Will this response's connection be kept alive?
|
195
|
+
|
96
196
|
def keep_alive?
|
97
197
|
@keep_alive
|
98
198
|
end
|
99
199
|
|
100
|
-
|
200
|
+
##
|
201
|
+
# Sends the response on +socket+
|
202
|
+
|
203
|
+
def send_response(socket) # :nodoc:
|
101
204
|
begin
|
102
205
|
setup_header()
|
103
206
|
send_header(socket)
|
@@ -111,7 +214,10 @@ module WEBrick
|
|
111
214
|
end
|
112
215
|
end
|
113
216
|
|
114
|
-
|
217
|
+
##
|
218
|
+
# Sets up the headers for sending
|
219
|
+
|
220
|
+
def setup_header() # :nodoc:
|
115
221
|
@reason_phrase ||= HTTPStatus::reason_phrase(@status)
|
116
222
|
@header['server'] ||= @config[:ServerSoftware]
|
117
223
|
@header['date'] ||= Time.now.httpdate
|
@@ -143,7 +249,7 @@ module WEBrick
|
|
143
249
|
@header.delete('content-length')
|
144
250
|
elsif @header['content-length'].nil?
|
145
251
|
unless @body.is_a?(IO)
|
146
|
-
@header['content-length'] = @body ? @body.
|
252
|
+
@header['content-length'] = @body ? @body.bytesize : 0
|
147
253
|
end
|
148
254
|
end
|
149
255
|
|
@@ -151,8 +257,13 @@ module WEBrick
|
|
151
257
|
if @header['connection'] == "close"
|
152
258
|
@keep_alive = false
|
153
259
|
elsif keep_alive?
|
154
|
-
if chunked? || @header['content-length']
|
260
|
+
if chunked? || @header['content-length'] || @status == 304 || @status == 204 || HTTPStatus.info?(@status)
|
155
261
|
@header['connection'] = "Keep-Alive"
|
262
|
+
else
|
263
|
+
msg = "Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true"
|
264
|
+
@logger.warn(msg)
|
265
|
+
@header['connection'] = "close"
|
266
|
+
@keep_alive = false
|
156
267
|
end
|
157
268
|
else
|
158
269
|
@header['connection'] = "close"
|
@@ -166,11 +277,14 @@ module WEBrick
|
|
166
277
|
end
|
167
278
|
end
|
168
279
|
|
169
|
-
|
280
|
+
##
|
281
|
+
# Sends the headers on +socket+
|
282
|
+
|
283
|
+
def send_header(socket) # :nodoc:
|
170
284
|
if @http_version.major > 0
|
171
285
|
data = status_line()
|
172
286
|
@header.each{|key, value|
|
173
|
-
tmp = key.gsub(/\bwww|^te$|\b\w/){
|
287
|
+
tmp = key.gsub(/\bwww|^te$|\b\w/){ $&.upcase }
|
174
288
|
data << "#{tmp}: #{value}" << CRLF
|
175
289
|
}
|
176
290
|
@cookies.each{|cookie|
|
@@ -181,31 +295,44 @@ module WEBrick
|
|
181
295
|
end
|
182
296
|
end
|
183
297
|
|
184
|
-
|
298
|
+
##
|
299
|
+
# Sends the body on +socket+
|
300
|
+
|
301
|
+
def send_body(socket) # :nodoc:
|
185
302
|
case @body
|
186
303
|
when IO then send_body_io(socket)
|
187
304
|
else send_body_string(socket)
|
188
305
|
end
|
189
306
|
end
|
190
307
|
|
191
|
-
def to_s
|
308
|
+
def to_s # :nodoc:
|
192
309
|
ret = ""
|
193
310
|
send_response(ret)
|
194
311
|
ret
|
195
312
|
end
|
196
313
|
|
314
|
+
##
|
315
|
+
# Redirects to +url+ with a WEBrick::HTTPStatus::Redirect +status+.
|
316
|
+
#
|
317
|
+
# Example:
|
318
|
+
#
|
319
|
+
# res.set_redirect WEBrick::HTTPStatus::TemporaryRedirect
|
320
|
+
|
197
321
|
def set_redirect(status, url)
|
198
322
|
@body = "<HTML><A HREF=\"#{url.to_s}\">#{url.to_s}</A>.</HTML>\n"
|
199
323
|
@header['location'] = url.to_s
|
200
324
|
raise status
|
201
325
|
end
|
202
326
|
|
327
|
+
##
|
328
|
+
# Creates an error page for exception +ex+ with an optional +backtrace+
|
329
|
+
|
203
330
|
def set_error(ex, backtrace=false)
|
204
331
|
case ex
|
205
|
-
when HTTPStatus::Status
|
332
|
+
when HTTPStatus::Status
|
206
333
|
@keep_alive = false if HTTPStatus::error?(ex.code)
|
207
334
|
self.status = ex.code
|
208
|
-
else
|
335
|
+
else
|
209
336
|
@keep_alive = false
|
210
337
|
self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR
|
211
338
|
end
|
@@ -253,18 +380,25 @@ module WEBrick
|
|
253
380
|
|
254
381
|
private
|
255
382
|
|
383
|
+
# :stopdoc:
|
384
|
+
|
256
385
|
def send_body_io(socket)
|
257
386
|
begin
|
258
387
|
if @request_method == "HEAD"
|
259
388
|
# do nothing
|
260
389
|
elsif chunked?
|
261
|
-
|
262
|
-
|
263
|
-
data =
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
390
|
+
begin
|
391
|
+
buf = ''
|
392
|
+
data = ''
|
393
|
+
while true
|
394
|
+
@body.readpartial( @buffer_size, buf ) # there is no need to clear buf?
|
395
|
+
data << format("%x", buf.bytesize) << CRLF
|
396
|
+
data << buf << CRLF
|
397
|
+
_write_data(socket, data)
|
398
|
+
data.clear
|
399
|
+
@sent_size += buf.bytesize
|
400
|
+
end
|
401
|
+
rescue EOFError # do nothing
|
268
402
|
end
|
269
403
|
_write_data(socket, "0#{CRLF}#{CRLF}")
|
270
404
|
else
|
@@ -281,41 +415,41 @@ module WEBrick
|
|
281
415
|
if @request_method == "HEAD"
|
282
416
|
# do nothing
|
283
417
|
elsif chunked?
|
284
|
-
|
285
|
-
while buf = @body[@sent_size,
|
418
|
+
body ? @body.bytesize : 0
|
419
|
+
while buf = @body[@sent_size, @buffer_size]
|
286
420
|
break if buf.empty?
|
287
421
|
data = ""
|
288
|
-
data << format("%x", buf.
|
422
|
+
data << format("%x", buf.bytesize) << CRLF
|
289
423
|
data << buf << CRLF
|
290
424
|
_write_data(socket, data)
|
291
|
-
@sent_size += buf.
|
425
|
+
@sent_size += buf.bytesize
|
292
426
|
end
|
293
427
|
_write_data(socket, "0#{CRLF}#{CRLF}")
|
294
428
|
else
|
295
|
-
if @body && @body.
|
429
|
+
if @body && @body.bytesize > 0
|
296
430
|
_write_data(socket, @body)
|
297
|
-
@sent_size = @body.
|
431
|
+
@sent_size = @body.bytesize
|
298
432
|
end
|
299
433
|
end
|
300
434
|
end
|
301
435
|
|
302
436
|
def _send_file(output, input, offset, size)
|
303
437
|
while offset > 0
|
304
|
-
sz =
|
438
|
+
sz = @buffer_size < size ? @buffer_size : size
|
305
439
|
buf = input.read(sz)
|
306
|
-
offset -= buf.
|
440
|
+
offset -= buf.bytesize
|
307
441
|
end
|
308
442
|
|
309
443
|
if size == 0
|
310
|
-
while buf = input.read(
|
444
|
+
while buf = input.read(@buffer_size)
|
311
445
|
_write_data(output, buf)
|
312
446
|
end
|
313
447
|
else
|
314
448
|
while size > 0
|
315
|
-
sz =
|
449
|
+
sz = @buffer_size < size ? @buffer_size : size
|
316
450
|
buf = input.read(sz)
|
317
451
|
_write_data(output, buf)
|
318
|
-
size -= buf.
|
452
|
+
size -= buf.bytesize
|
319
453
|
end
|
320
454
|
end
|
321
455
|
end
|
@@ -323,5 +457,8 @@ module WEBrick
|
|
323
457
|
def _write_data(socket, data)
|
324
458
|
socket << data
|
325
459
|
end
|
460
|
+
|
461
|
+
# :startdoc:
|
326
462
|
end
|
463
|
+
|
327
464
|
end
|
data/lib/webrick/https.rb
CHANGED
@@ -15,8 +15,28 @@ module WEBrick
|
|
15
15
|
HTTP.update(SSL)
|
16
16
|
end
|
17
17
|
|
18
|
+
##
|
19
|
+
#--
|
20
|
+
# Adds SSL functionality to WEBrick::HTTPRequest
|
21
|
+
|
18
22
|
class HTTPRequest
|
19
|
-
|
23
|
+
|
24
|
+
##
|
25
|
+
# HTTP request SSL cipher
|
26
|
+
|
27
|
+
attr_reader :cipher
|
28
|
+
|
29
|
+
##
|
30
|
+
# HTTP request server certificate
|
31
|
+
|
32
|
+
attr_reader :server_cert
|
33
|
+
|
34
|
+
##
|
35
|
+
# HTTP request client certificate
|
36
|
+
|
37
|
+
attr_reader :client_cert
|
38
|
+
|
39
|
+
# :stopdoc:
|
20
40
|
|
21
41
|
alias orig_parse parse
|
22
42
|
|
@@ -33,17 +53,18 @@ module WEBrick
|
|
33
53
|
alias orig_parse_uri parse_uri
|
34
54
|
|
35
55
|
def parse_uri(str, scheme="https")
|
36
|
-
if
|
56
|
+
if server_cert
|
37
57
|
return orig_parse_uri(str, scheme)
|
38
58
|
end
|
39
59
|
return orig_parse_uri(str)
|
40
60
|
end
|
61
|
+
private :parse_uri
|
41
62
|
|
42
63
|
alias orig_meta_vars meta_vars
|
43
64
|
|
44
65
|
def meta_vars
|
45
66
|
meta = orig_meta_vars
|
46
|
-
if
|
67
|
+
if server_cert
|
47
68
|
meta["HTTPS"] = "on"
|
48
69
|
meta["SSL_SERVER_CERT"] = @server_cert.to_pem
|
49
70
|
meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : ""
|
@@ -59,5 +80,7 @@ module WEBrick
|
|
59
80
|
end
|
60
81
|
meta
|
61
82
|
end
|
83
|
+
|
84
|
+
# :startdoc:
|
62
85
|
end
|
63
86
|
end
|
data/lib/webrick/httpserver.rb
CHANGED
@@ -19,9 +19,30 @@ require 'webrick/accesslog'
|
|
19
19
|
module WEBrick
|
20
20
|
class HTTPServerError < ServerError; end
|
21
21
|
|
22
|
+
##
|
23
|
+
# An HTTP Server
|
24
|
+
|
22
25
|
class HTTPServer < ::WEBrick::GenericServer
|
26
|
+
##
|
27
|
+
# Creates a new HTTP server according to +config+
|
28
|
+
#
|
29
|
+
# An HTTP server uses the following attributes:
|
30
|
+
#
|
31
|
+
# :AccessLog:: An array of access logs. See WEBrick::AccessLog
|
32
|
+
# :BindAddress:: Local address for the server to bind to
|
33
|
+
# :DocumentRoot:: Root path to serve files from
|
34
|
+
# :DocumentRootOptions:: Options for the default HTTPServlet::FileHandler
|
35
|
+
# :HTTPVersion:: The HTTP version of this server
|
36
|
+
# :Port:: Port to listen on
|
37
|
+
# :RequestCallback:: Called with a request and response before each
|
38
|
+
# request is serviced.
|
39
|
+
# :RequestTimeout:: Maximum time to wait between requests
|
40
|
+
# :ServerAlias:: Array of alternate names for this server for virtual
|
41
|
+
# hosting
|
42
|
+
# :ServerName:: Name for this server for virtual hosting
|
43
|
+
|
23
44
|
def initialize(config={}, default=Config::HTTP)
|
24
|
-
super
|
45
|
+
super(config, default)
|
25
46
|
@http_version = HTTPVersion::convert(@config[:HTTPVersion])
|
26
47
|
|
27
48
|
@mount_tab = MountTable.new
|
@@ -36,12 +57,15 @@ module WEBrick
|
|
36
57
|
[ $stderr, AccessLog::REFERER_LOG_FORMAT ]
|
37
58
|
]
|
38
59
|
end
|
39
|
-
|
60
|
+
|
40
61
|
@virtual_hosts = Array.new
|
41
62
|
end
|
42
63
|
|
64
|
+
##
|
65
|
+
# Processes requests on +sock+
|
66
|
+
|
43
67
|
def run(sock)
|
44
|
-
while true
|
68
|
+
while true
|
45
69
|
res = HTTPResponse.new(@config)
|
46
70
|
req = HTTPRequest.new(@config)
|
47
71
|
server = self
|
@@ -52,14 +76,19 @@ module WEBrick
|
|
52
76
|
timeout = 0 if @status != :Running
|
53
77
|
timeout -= 0.5
|
54
78
|
end
|
55
|
-
raise HTTPStatus::EOFError if timeout <= 0
|
79
|
+
raise HTTPStatus::EOFError if timeout <= 0
|
80
|
+
raise HTTPStatus::EOFError if sock.eof?
|
56
81
|
req.parse(sock)
|
57
82
|
res.request_method = req.request_method
|
58
83
|
res.request_uri = req.request_uri
|
59
84
|
res.request_http_version = req.http_version
|
60
85
|
res.keep_alive = req.keep_alive?
|
61
86
|
server = lookup_server(req) || self
|
62
|
-
if callback = server[:RequestCallback]
|
87
|
+
if callback = server[:RequestCallback]
|
88
|
+
callback.call(req, res)
|
89
|
+
elsif callback = server[:RequestHandler]
|
90
|
+
msg = ":RequestHandler is deprecated, please use :RequestCallback"
|
91
|
+
@logger.warn(msg)
|
63
92
|
callback.call(req, res)
|
64
93
|
end
|
65
94
|
server.service(req, res)
|
@@ -75,7 +104,9 @@ module WEBrick
|
|
75
104
|
res.set_error(ex, true)
|
76
105
|
ensure
|
77
106
|
if req.request_line
|
78
|
-
req.
|
107
|
+
if req.keep_alive? && res.keep_alive?
|
108
|
+
req.fixup()
|
109
|
+
end
|
79
110
|
res.send_response(sock)
|
80
111
|
server.access_log(@config, req, res)
|
81
112
|
end
|
@@ -86,6 +117,9 @@ module WEBrick
|
|
86
117
|
end
|
87
118
|
end
|
88
119
|
|
120
|
+
##
|
121
|
+
# Services +req+ and fills in +res+
|
122
|
+
|
89
123
|
def service(req, res)
|
90
124
|
if req.unparsed_uri == "*"
|
91
125
|
if req.request_method == "OPTIONS"
|
@@ -104,27 +138,45 @@ module WEBrick
|
|
104
138
|
si.service(req, res)
|
105
139
|
end
|
106
140
|
|
141
|
+
##
|
142
|
+
# The default OPTIONS request handler says GET, HEAD, POST and OPTIONS
|
143
|
+
# requests are allowed.
|
144
|
+
|
107
145
|
def do_OPTIONS(req, res)
|
108
146
|
res["allow"] = "GET,HEAD,POST,OPTIONS"
|
109
147
|
end
|
110
148
|
|
149
|
+
##
|
150
|
+
# Mounts +servlet+ on +dir+ passing +options+ to the servlet at creation
|
151
|
+
# time
|
152
|
+
|
111
153
|
def mount(dir, servlet, *options)
|
112
154
|
@logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir))
|
113
155
|
@mount_tab[dir] = [ servlet, options ]
|
114
156
|
end
|
115
157
|
|
158
|
+
##
|
159
|
+
# Mounts +proc+ or +block+ on +dir+ and calls it with a
|
160
|
+
# WEBrick::HTTPRequest and WEBrick::HTTPResponse
|
161
|
+
|
116
162
|
def mount_proc(dir, proc=nil, &block)
|
117
163
|
proc ||= block
|
118
164
|
raise HTTPServerError, "must pass a proc or block" unless proc
|
119
165
|
mount(dir, HTTPServlet::ProcHandler.new(proc))
|
120
166
|
end
|
121
167
|
|
168
|
+
##
|
169
|
+
# Unmounts +dir+
|
170
|
+
|
122
171
|
def unmount(dir)
|
123
172
|
@logger.debug(sprintf("unmount %s.", dir))
|
124
173
|
@mount_tab.delete(dir)
|
125
174
|
end
|
126
175
|
alias umount unmount
|
127
176
|
|
177
|
+
##
|
178
|
+
# Finds a servlet for +path+
|
179
|
+
|
128
180
|
def search_servlet(path)
|
129
181
|
script_name, path_info = @mount_tab.scan(path)
|
130
182
|
servlet, options = @mount_tab[script_name]
|
@@ -133,6 +185,9 @@ module WEBrick
|
|
133
185
|
end
|
134
186
|
end
|
135
187
|
|
188
|
+
##
|
189
|
+
# Adds +server+ as a virtual host.
|
190
|
+
|
136
191
|
def virtual_host(server)
|
137
192
|
@virtual_hosts << server
|
138
193
|
@virtual_hosts = @virtual_hosts.sort_by{|s|
|
@@ -144,6 +199,9 @@ module WEBrick
|
|
144
199
|
}
|
145
200
|
end
|
146
201
|
|
202
|
+
##
|
203
|
+
# Finds the appropriate virtual host to handle +req+
|
204
|
+
|
147
205
|
def lookup_server(req)
|
148
206
|
@virtual_hosts.find{|s|
|
149
207
|
(s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
|
@@ -153,6 +211,10 @@ module WEBrick
|
|
153
211
|
}
|
154
212
|
end
|
155
213
|
|
214
|
+
##
|
215
|
+
# Logs +req+ and +res+ in the access logs. +config+ is used for the
|
216
|
+
# server name.
|
217
|
+
|
156
218
|
def access_log(config, req, res)
|
157
219
|
param = AccessLog::setup_params(config, req, res)
|
158
220
|
@config[:AccessLog].each{|logger, fmt|
|
@@ -160,7 +222,13 @@ module WEBrick
|
|
160
222
|
}
|
161
223
|
end
|
162
224
|
|
163
|
-
|
225
|
+
##
|
226
|
+
# Mount table for the path a servlet is mounted on in the directory space
|
227
|
+
# of the server. Users of WEBrick can only access this indirectly via
|
228
|
+
# WEBrick::HTTPServer#mount, WEBrick::HTTPServer#unmount and
|
229
|
+
# WEBrick::HTTPServer#search_servlet
|
230
|
+
|
231
|
+
class MountTable # :nodoc:
|
164
232
|
def initialize
|
165
233
|
@tab = Hash.new
|
166
234
|
compile
|