webrick 1.3.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of webrick might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +63 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/webrick/accesslog.rb +9 -1
- data/lib/webrick/cgi.rb +58 -5
- data/lib/webrick/compat.rb +2 -1
- data/lib/webrick/config.rb +47 -10
- data/lib/webrick/cookie.rb +69 -7
- data/lib/webrick/htmlutils.rb +4 -2
- data/lib/webrick/httpauth/authenticator.rb +13 -8
- data/lib/webrick/httpauth/basicauth.rb +16 -8
- data/lib/webrick/httpauth/digestauth.rb +35 -32
- data/lib/webrick/httpauth/htdigest.rb +12 -8
- data/lib/webrick/httpauth/htgroup.rb +10 -6
- data/lib/webrick/httpauth/htpasswd.rb +46 -9
- data/lib/webrick/httpauth/userdb.rb +1 -0
- data/lib/webrick/httpauth.rb +6 -5
- data/lib/webrick/httpproxy.rb +93 -48
- data/lib/webrick/httprequest.rb +192 -27
- data/lib/webrick/httpresponse.rb +221 -70
- data/lib/webrick/https.rb +90 -2
- data/lib/webrick/httpserver.rb +45 -15
- data/lib/webrick/httpservlet/abstract.rb +5 -6
- data/lib/webrick/httpservlet/cgi_runner.rb +3 -2
- data/lib/webrick/httpservlet/cgihandler.rb +22 -10
- data/lib/webrick/httpservlet/erbhandler.rb +4 -3
- data/lib/webrick/httpservlet/filehandler.rb +136 -65
- data/lib/webrick/httpservlet/prochandler.rb +15 -1
- data/lib/webrick/httpservlet.rb +6 -5
- data/lib/webrick/httpstatus.rb +24 -14
- data/lib/webrick/httputils.rb +133 -13
- data/lib/webrick/httpversion.rb +28 -1
- data/lib/webrick/log.rb +25 -5
- data/lib/webrick/server.rb +234 -74
- data/lib/webrick/ssl.rb +100 -12
- data/lib/webrick/utils.rb +98 -69
- data/lib/webrick/version.rb +6 -1
- data/lib/webrick.rb +7 -7
- data/webrick.gemspec +76 -0
- metadata +70 -69
- data/README.txt +0 -21
- data/sample/webrick/demo-app.rb +0 -66
- data/sample/webrick/demo-multipart.cgi +0 -12
- data/sample/webrick/demo-servlet.rb +0 -6
- data/sample/webrick/demo-urlencoded.cgi +0 -12
- data/sample/webrick/hello.cgi +0 -11
- data/sample/webrick/hello.rb +0 -8
- data/sample/webrick/httpd.rb +0 -23
- data/sample/webrick/httpproxy.rb +0 -25
- data/sample/webrick/httpsd.rb +0 -33
- data/test/openssl/utils.rb +0 -313
- data/test/ruby/envutil.rb +0 -208
- data/test/webrick/test_cgi.rb +0 -134
- data/test/webrick/test_cookie.rb +0 -131
- data/test/webrick/test_filehandler.rb +0 -285
- data/test/webrick/test_httpauth.rb +0 -167
- data/test/webrick/test_httpproxy.rb +0 -282
- data/test/webrick/test_httprequest.rb +0 -411
- data/test/webrick/test_httpresponse.rb +0 -49
- data/test/webrick/test_httpserver.rb +0 -305
- data/test/webrick/test_httputils.rb +0 -96
- data/test/webrick/test_httpversion.rb +0 -40
- data/test/webrick/test_server.rb +0 -67
- data/test/webrick/test_utils.rb +0 -64
- data/test/webrick/utils.rb +0 -58
- data/test/webrick/webrick.cgi +0 -36
- data/test/webrick/webrick_long_filename.cgi +0 -36
data/lib/webrick/httpresponse.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httpresponse.rb -- HTTPResponse Class
|
3
4
|
#
|
@@ -9,32 +10,91 @@
|
|
9
10
|
# $IPR: httpresponse.rb,v 1.45 2003/07/11 11:02:25 gotoyuzo Exp $
|
10
11
|
|
11
12
|
require 'time'
|
12
|
-
require '
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
require 'uri'
|
14
|
+
require_relative 'httpversion'
|
15
|
+
require_relative 'htmlutils'
|
16
|
+
require_relative 'httputils'
|
17
|
+
require_relative 'httpstatus'
|
16
18
|
|
17
19
|
module WEBrick
|
18
20
|
##
|
19
|
-
# An HTTP response.
|
21
|
+
# An HTTP response. This is filled in by the service or do_* methods of a
|
22
|
+
# WEBrick HTTP Servlet.
|
20
23
|
|
21
24
|
class HTTPResponse
|
22
|
-
|
25
|
+
class InvalidHeader < StandardError
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# HTTP Response version
|
30
|
+
|
31
|
+
attr_reader :http_version
|
32
|
+
|
33
|
+
##
|
34
|
+
# Response status code (200)
|
35
|
+
|
36
|
+
attr_reader :status
|
37
|
+
|
38
|
+
##
|
39
|
+
# Response header
|
40
|
+
|
41
|
+
attr_reader :header
|
42
|
+
|
43
|
+
##
|
44
|
+
# Response cookies
|
45
|
+
|
23
46
|
attr_reader :cookies
|
47
|
+
|
48
|
+
##
|
49
|
+
# Response reason phrase ("OK")
|
50
|
+
|
24
51
|
attr_accessor :reason_phrase
|
25
52
|
|
26
53
|
##
|
27
|
-
# Body may be a String or IO
|
54
|
+
# Body may be a String or IO-like object that responds to #read and
|
55
|
+
# #readpartial.
|
28
56
|
|
29
57
|
attr_accessor :body
|
30
58
|
|
31
|
-
|
59
|
+
##
|
60
|
+
# Request method for this response
|
61
|
+
|
62
|
+
attr_accessor :request_method
|
63
|
+
|
64
|
+
##
|
65
|
+
# Request URI for this response
|
66
|
+
|
67
|
+
attr_accessor :request_uri
|
68
|
+
|
69
|
+
##
|
70
|
+
# Request HTTP version for this response
|
71
|
+
|
72
|
+
attr_accessor :request_http_version
|
73
|
+
|
74
|
+
##
|
75
|
+
# Filename of the static file in this response. Only used by the
|
76
|
+
# FileHandler servlet.
|
77
|
+
|
32
78
|
attr_accessor :filename
|
79
|
+
|
80
|
+
##
|
81
|
+
# Is this a keep-alive response?
|
82
|
+
|
33
83
|
attr_accessor :keep_alive
|
34
|
-
attr_reader :config, :sent_size
|
35
84
|
|
36
85
|
##
|
37
|
-
#
|
86
|
+
# Configuration for this response
|
87
|
+
|
88
|
+
attr_reader :config
|
89
|
+
|
90
|
+
##
|
91
|
+
# Bytes sent in this response
|
92
|
+
|
93
|
+
attr_reader :sent_size
|
94
|
+
|
95
|
+
##
|
96
|
+
# Creates a new HTTP response object. WEBrick::Config::HTTP is the
|
97
|
+
# default configuration.
|
38
98
|
|
39
99
|
def initialize(config)
|
40
100
|
@config = config
|
@@ -53,13 +113,14 @@ module WEBrick
|
|
53
113
|
@chunked = false
|
54
114
|
@filename = nil
|
55
115
|
@sent_size = 0
|
116
|
+
@bodytempfile = nil
|
56
117
|
end
|
57
118
|
|
58
119
|
##
|
59
120
|
# The response's HTTP status line
|
60
121
|
|
61
122
|
def status_line
|
62
|
-
"HTTP/#@http_version #@status #@reason_phrase
|
123
|
+
"HTTP/#@http_version #@status #@reason_phrase".rstrip << CRLF
|
63
124
|
end
|
64
125
|
|
65
126
|
##
|
@@ -115,7 +176,7 @@ module WEBrick
|
|
115
176
|
end
|
116
177
|
|
117
178
|
##
|
118
|
-
# Iterates over each header in the
|
179
|
+
# Iterates over each header in the response
|
119
180
|
|
120
181
|
def each
|
121
182
|
@header.each{|field, value| yield(field, value) }
|
@@ -145,7 +206,7 @@ module WEBrick
|
|
145
206
|
##
|
146
207
|
# Sends the response on +socket+
|
147
208
|
|
148
|
-
def send_response(socket)
|
209
|
+
def send_response(socket) # :nodoc:
|
149
210
|
begin
|
150
211
|
setup_header()
|
151
212
|
send_header(socket)
|
@@ -162,7 +223,7 @@ module WEBrick
|
|
162
223
|
##
|
163
224
|
# Sets up the headers for sending
|
164
225
|
|
165
|
-
def setup_header()
|
226
|
+
def setup_header() # :nodoc:
|
166
227
|
@reason_phrase ||= HTTPStatus::reason_phrase(@status)
|
167
228
|
@header['server'] ||= @config[:ServerSoftware]
|
168
229
|
@header['date'] ||= Time.now.httpdate
|
@@ -193,8 +254,11 @@ module WEBrick
|
|
193
254
|
elsif %r{^multipart/byteranges} =~ @header['content-type']
|
194
255
|
@header.delete('content-length')
|
195
256
|
elsif @header['content-length'].nil?
|
196
|
-
|
197
|
-
|
257
|
+
if @body.respond_to? :readpartial
|
258
|
+
elsif @body.respond_to? :call
|
259
|
+
make_body_tempfile
|
260
|
+
else
|
261
|
+
@header['content-length'] = (@body ? @body.bytesize : 0).to_s
|
198
262
|
end
|
199
263
|
end
|
200
264
|
|
@@ -217,45 +281,74 @@ module WEBrick
|
|
217
281
|
# Location is a single absoluteURI.
|
218
282
|
if location = @header['location']
|
219
283
|
if @request_uri
|
220
|
-
@header['location'] = @request_uri.merge(location)
|
284
|
+
@header['location'] = @request_uri.merge(location).to_s
|
221
285
|
end
|
222
286
|
end
|
223
287
|
end
|
224
288
|
|
289
|
+
def make_body_tempfile # :nodoc:
|
290
|
+
return if @bodytempfile
|
291
|
+
bodytempfile = Tempfile.create("webrick")
|
292
|
+
if @body.nil?
|
293
|
+
# nothing
|
294
|
+
elsif @body.respond_to? :readpartial
|
295
|
+
IO.copy_stream(@body, bodytempfile)
|
296
|
+
@body.close
|
297
|
+
elsif @body.respond_to? :call
|
298
|
+
@body.call(bodytempfile)
|
299
|
+
else
|
300
|
+
bodytempfile.write @body
|
301
|
+
end
|
302
|
+
bodytempfile.rewind
|
303
|
+
@body = @bodytempfile = bodytempfile
|
304
|
+
@header['content-length'] = bodytempfile.stat.size.to_s
|
305
|
+
end
|
306
|
+
|
307
|
+
def remove_body_tempfile # :nodoc:
|
308
|
+
if @bodytempfile
|
309
|
+
@bodytempfile.close
|
310
|
+
File.unlink @bodytempfile.path
|
311
|
+
@bodytempfile = nil
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
|
225
316
|
##
|
226
317
|
# Sends the headers on +socket+
|
227
318
|
|
228
|
-
def send_header(socket)
|
319
|
+
def send_header(socket) # :nodoc:
|
229
320
|
if @http_version.major > 0
|
230
321
|
data = status_line()
|
231
322
|
@header.each{|key, value|
|
232
323
|
tmp = key.gsub(/\bwww|^te$|\b\w/){ $&.upcase }
|
233
|
-
data << "#{tmp}: #{value}" << CRLF
|
324
|
+
data << "#{tmp}: #{check_header(value)}" << CRLF
|
234
325
|
}
|
235
326
|
@cookies.each{|cookie|
|
236
|
-
data << "Set-Cookie: " << cookie.to_s << CRLF
|
327
|
+
data << "Set-Cookie: " << check_header(cookie.to_s) << CRLF
|
237
328
|
}
|
238
329
|
data << CRLF
|
239
|
-
|
330
|
+
socket.write(data)
|
240
331
|
end
|
332
|
+
rescue InvalidHeader => e
|
333
|
+
@header.clear
|
334
|
+
@cookies.clear
|
335
|
+
set_error e
|
336
|
+
retry
|
241
337
|
end
|
242
338
|
|
243
339
|
##
|
244
340
|
# Sends the body on +socket+
|
245
341
|
|
246
|
-
def send_body(socket)
|
247
|
-
|
248
|
-
|
249
|
-
|
342
|
+
def send_body(socket) # :nodoc:
|
343
|
+
if @body.respond_to? :readpartial then
|
344
|
+
send_body_io(socket)
|
345
|
+
elsif @body.respond_to?(:call) then
|
346
|
+
send_body_proc(socket)
|
347
|
+
else
|
348
|
+
send_body_string(socket)
|
250
349
|
end
|
251
350
|
end
|
252
351
|
|
253
|
-
def to_s # :nodoc:
|
254
|
-
ret = ""
|
255
|
-
send_response(ret)
|
256
|
-
ret
|
257
|
-
end
|
258
|
-
|
259
352
|
##
|
260
353
|
# Redirects to +url+ with a WEBrick::HTTPStatus::Redirect +status+.
|
261
354
|
#
|
@@ -264,8 +357,9 @@ module WEBrick
|
|
264
357
|
# res.set_redirect WEBrick::HTTPStatus::TemporaryRedirect
|
265
358
|
|
266
359
|
def set_redirect(status, url)
|
267
|
-
|
268
|
-
@
|
360
|
+
url = URI(url).to_s
|
361
|
+
@body = "<HTML><A HREF=\"#{url}\">#{url}</A>.</HTML>\n"
|
362
|
+
@header['location'] = url
|
269
363
|
raise status
|
270
364
|
end
|
271
365
|
|
@@ -294,6 +388,23 @@ module WEBrick
|
|
294
388
|
host, port = @config[:ServerName], @config[:Port]
|
295
389
|
end
|
296
390
|
|
391
|
+
error_body(backtrace, ex, host, port)
|
392
|
+
end
|
393
|
+
|
394
|
+
private
|
395
|
+
|
396
|
+
def check_header(header_value)
|
397
|
+
header_value = header_value.to_s
|
398
|
+
if /[\r\n]/ =~ header_value
|
399
|
+
raise InvalidHeader
|
400
|
+
else
|
401
|
+
header_value
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
# :stopdoc:
|
406
|
+
|
407
|
+
def error_body(backtrace, ex, host, port)
|
297
408
|
@body = ''
|
298
409
|
@body << <<-_end_of_html_
|
299
410
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
@@ -323,30 +434,44 @@ module WEBrick
|
|
323
434
|
_end_of_html_
|
324
435
|
end
|
325
436
|
|
326
|
-
private
|
327
|
-
|
328
437
|
def send_body_io(socket)
|
329
438
|
begin
|
330
439
|
if @request_method == "HEAD"
|
331
440
|
# do nothing
|
332
441
|
elsif chunked?
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
data
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
442
|
+
buf = ''
|
443
|
+
begin
|
444
|
+
@body.readpartial(@buffer_size, buf)
|
445
|
+
size = buf.bytesize
|
446
|
+
data = "#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}"
|
447
|
+
socket.write(data)
|
448
|
+
data.clear
|
449
|
+
@sent_size += size
|
450
|
+
rescue EOFError
|
451
|
+
break
|
452
|
+
end while true
|
453
|
+
buf.clear
|
454
|
+
socket.write("0#{CRLF}#{CRLF}")
|
342
455
|
else
|
343
|
-
|
344
|
-
|
345
|
-
|
456
|
+
if %r{\Abytes (\d+)-(\d+)/\d+\z} =~ @header['content-range']
|
457
|
+
offset = $1.to_i
|
458
|
+
size = $2.to_i - offset + 1
|
459
|
+
else
|
460
|
+
offset = nil
|
461
|
+
size = @header['content-length']
|
462
|
+
size = size.to_i if size
|
463
|
+
end
|
464
|
+
begin
|
465
|
+
@sent_size = IO.copy_stream(@body, socket, size, offset)
|
466
|
+
rescue NotImplementedError
|
467
|
+
@body.seek(offset, IO::SEEK_SET)
|
468
|
+
@sent_size = IO.copy_stream(@body, socket, size)
|
469
|
+
end
|
346
470
|
end
|
347
471
|
ensure
|
348
472
|
@body.close
|
349
473
|
end
|
474
|
+
remove_body_tempfile
|
350
475
|
end
|
351
476
|
|
352
477
|
def send_body_string(socket)
|
@@ -356,44 +481,70 @@ module WEBrick
|
|
356
481
|
body ? @body.bytesize : 0
|
357
482
|
while buf = @body[@sent_size, @buffer_size]
|
358
483
|
break if buf.empty?
|
359
|
-
|
360
|
-
data
|
361
|
-
|
362
|
-
|
363
|
-
@sent_size +=
|
484
|
+
size = buf.bytesize
|
485
|
+
data = "#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}"
|
486
|
+
buf.clear
|
487
|
+
socket.write(data)
|
488
|
+
@sent_size += size
|
364
489
|
end
|
365
|
-
|
490
|
+
socket.write("0#{CRLF}#{CRLF}")
|
366
491
|
else
|
367
492
|
if @body && @body.bytesize > 0
|
368
|
-
|
493
|
+
socket.write(@body)
|
369
494
|
@sent_size = @body.bytesize
|
370
495
|
end
|
371
496
|
end
|
372
497
|
end
|
373
498
|
|
374
|
-
def
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
if size == 0
|
382
|
-
while buf = input.read(@buffer_size)
|
383
|
-
_write_data(output, buf)
|
384
|
-
end
|
499
|
+
def send_body_proc(socket)
|
500
|
+
if @request_method == "HEAD"
|
501
|
+
# do nothing
|
502
|
+
elsif chunked?
|
503
|
+
@body.call(ChunkedWrapper.new(socket, self))
|
504
|
+
socket.write("0#{CRLF}#{CRLF}")
|
385
505
|
else
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
506
|
+
size = @header['content-length'].to_i
|
507
|
+
if @bodytempfile
|
508
|
+
@bodytempfile.rewind
|
509
|
+
IO.copy_stream(@bodytempfile, socket)
|
510
|
+
else
|
511
|
+
@body.call(socket)
|
391
512
|
end
|
513
|
+
@sent_size = size
|
392
514
|
end
|
393
515
|
end
|
394
516
|
|
517
|
+
class ChunkedWrapper
|
518
|
+
def initialize(socket, resp)
|
519
|
+
@socket = socket
|
520
|
+
@resp = resp
|
521
|
+
end
|
522
|
+
|
523
|
+
def write(buf)
|
524
|
+
return 0 if buf.empty?
|
525
|
+
socket = @socket
|
526
|
+
@resp.instance_eval {
|
527
|
+
size = buf.bytesize
|
528
|
+
data = "#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}"
|
529
|
+
socket.write(data)
|
530
|
+
data.clear
|
531
|
+
@sent_size += size
|
532
|
+
size
|
533
|
+
}
|
534
|
+
end
|
535
|
+
|
536
|
+
def <<(*buf)
|
537
|
+
write(buf)
|
538
|
+
self
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
# preserved for compatibility with some 3rd-party handlers
|
395
543
|
def _write_data(socket, data)
|
396
544
|
socket << data
|
397
545
|
end
|
546
|
+
|
547
|
+
# :startdoc:
|
398
548
|
end
|
549
|
+
|
399
550
|
end
|
data/lib/webrick/https.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# https.rb -- SSL/TLS enhancement for HTTPServer
|
3
4
|
#
|
@@ -8,15 +9,36 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $
|
10
11
|
|
11
|
-
|
12
|
+
require_relative 'ssl'
|
13
|
+
require_relative 'httpserver'
|
12
14
|
|
13
15
|
module WEBrick
|
14
16
|
module Config
|
15
17
|
HTTP.update(SSL)
|
16
18
|
end
|
17
19
|
|
20
|
+
##
|
21
|
+
#--
|
22
|
+
# Adds SSL functionality to WEBrick::HTTPRequest
|
23
|
+
|
18
24
|
class HTTPRequest
|
19
|
-
|
25
|
+
|
26
|
+
##
|
27
|
+
# HTTP request SSL cipher
|
28
|
+
|
29
|
+
attr_reader :cipher
|
30
|
+
|
31
|
+
##
|
32
|
+
# HTTP request server certificate
|
33
|
+
|
34
|
+
attr_reader :server_cert
|
35
|
+
|
36
|
+
##
|
37
|
+
# HTTP request client certificate
|
38
|
+
|
39
|
+
attr_reader :client_cert
|
40
|
+
|
41
|
+
# :stopdoc:
|
20
42
|
|
21
43
|
alias orig_parse parse
|
22
44
|
|
@@ -60,5 +82,71 @@ module WEBrick
|
|
60
82
|
end
|
61
83
|
meta
|
62
84
|
end
|
85
|
+
|
86
|
+
# :startdoc:
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
#--
|
91
|
+
# Fake WEBrick::HTTPRequest for lookup_server
|
92
|
+
|
93
|
+
class SNIRequest
|
94
|
+
|
95
|
+
##
|
96
|
+
# The SNI hostname
|
97
|
+
|
98
|
+
attr_reader :host
|
99
|
+
|
100
|
+
##
|
101
|
+
# The socket address of the server
|
102
|
+
|
103
|
+
attr_reader :addr
|
104
|
+
|
105
|
+
##
|
106
|
+
# The port this request is for
|
107
|
+
|
108
|
+
attr_reader :port
|
109
|
+
|
110
|
+
##
|
111
|
+
# Creates a new SNIRequest.
|
112
|
+
|
113
|
+
def initialize(sslsocket, hostname)
|
114
|
+
@host = hostname
|
115
|
+
@addr = sslsocket.addr
|
116
|
+
@port = @addr[1]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
##
|
122
|
+
#--
|
123
|
+
# Adds SSL functionality to WEBrick::HTTPServer
|
124
|
+
|
125
|
+
class HTTPServer < ::WEBrick::GenericServer
|
126
|
+
##
|
127
|
+
# ServerNameIndication callback
|
128
|
+
|
129
|
+
def ssl_servername_callback(sslsocket, hostname = nil)
|
130
|
+
req = SNIRequest.new(sslsocket, hostname)
|
131
|
+
server = lookup_server(req)
|
132
|
+
server ? server.ssl_context : nil
|
133
|
+
end
|
134
|
+
|
135
|
+
# :stopdoc:
|
136
|
+
|
137
|
+
##
|
138
|
+
# Check whether +server+ is also SSL server.
|
139
|
+
# Also +server+'s SSL context will be created.
|
140
|
+
|
141
|
+
alias orig_virtual_host virtual_host
|
142
|
+
|
143
|
+
def virtual_host(server)
|
144
|
+
if @config[:SSLEnable] && !server.ssl_context
|
145
|
+
raise ArgumentError, "virtual host must set SSLEnable to true"
|
146
|
+
end
|
147
|
+
orig_virtual_host(server)
|
148
|
+
end
|
149
|
+
|
150
|
+
# :startdoc:
|
63
151
|
end
|
64
152
|
end
|
data/lib/webrick/httpserver.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httpserver.rb -- HTTPServer Class
|
3
4
|
#
|
@@ -8,13 +9,14 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $
|
10
11
|
|
11
|
-
require '
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
require 'io/wait'
|
13
|
+
require_relative 'server'
|
14
|
+
require_relative 'httputils'
|
15
|
+
require_relative 'httpstatus'
|
16
|
+
require_relative 'httprequest'
|
17
|
+
require_relative 'httpresponse'
|
18
|
+
require_relative 'httpservlet'
|
19
|
+
require_relative 'accesslog'
|
18
20
|
|
19
21
|
module WEBrick
|
20
22
|
class HTTPServerError < ServerError; end
|
@@ -66,17 +68,17 @@ module WEBrick
|
|
66
68
|
|
67
69
|
def run(sock)
|
68
70
|
while true
|
69
|
-
|
70
|
-
|
71
|
+
req = create_request(@config)
|
72
|
+
res = create_response(@config)
|
71
73
|
server = self
|
72
74
|
begin
|
73
75
|
timeout = @config[:RequestTimeout]
|
74
76
|
while timeout > 0
|
75
|
-
break if
|
76
|
-
|
77
|
+
break if sock.to_io.wait_readable(0.5)
|
78
|
+
break if @status != :Running
|
77
79
|
timeout -= 0.5
|
78
80
|
end
|
79
|
-
raise HTTPStatus::EOFError if timeout <= 0
|
81
|
+
raise HTTPStatus::EOFError if timeout <= 0 || @status != :Running
|
80
82
|
raise HTTPStatus::EOFError if sock.eof?
|
81
83
|
req.parse(sock)
|
82
84
|
res.request_method = req.request_method
|
@@ -138,6 +140,10 @@ module WEBrick
|
|
138
140
|
si.service(req, res)
|
139
141
|
end
|
140
142
|
|
143
|
+
##
|
144
|
+
# The default OPTIONS request handler says GET, HEAD, POST and OPTIONS
|
145
|
+
# requests are allowed.
|
146
|
+
|
141
147
|
def do_OPTIONS(req, res)
|
142
148
|
res["allow"] = "GET,HEAD,POST,OPTIONS"
|
143
149
|
end
|
@@ -207,6 +213,10 @@ module WEBrick
|
|
207
213
|
}
|
208
214
|
end
|
209
215
|
|
216
|
+
##
|
217
|
+
# Logs +req+ and +res+ in the access logs. +config+ is used for the
|
218
|
+
# server name.
|
219
|
+
|
210
220
|
def access_log(config, req, res)
|
211
221
|
param = AccessLog::setup_params(config, req, res)
|
212
222
|
@config[:AccessLog].each{|logger, fmt|
|
@@ -214,7 +224,27 @@ module WEBrick
|
|
214
224
|
}
|
215
225
|
end
|
216
226
|
|
217
|
-
|
227
|
+
##
|
228
|
+
# Creates the HTTPRequest used when handling the HTTP
|
229
|
+
# request. Can be overridden by subclasses.
|
230
|
+
def create_request(with_webrick_config)
|
231
|
+
HTTPRequest.new(with_webrick_config)
|
232
|
+
end
|
233
|
+
|
234
|
+
##
|
235
|
+
# Creates the HTTPResponse used when handling the HTTP
|
236
|
+
# request. Can be overridden by subclasses.
|
237
|
+
def create_response(with_webrick_config)
|
238
|
+
HTTPResponse.new(with_webrick_config)
|
239
|
+
end
|
240
|
+
|
241
|
+
##
|
242
|
+
# Mount table for the path a servlet is mounted on in the directory space
|
243
|
+
# of the server. Users of WEBrick can only access this indirectly via
|
244
|
+
# WEBrick::HTTPServer#mount, WEBrick::HTTPServer#unmount and
|
245
|
+
# WEBrick::HTTPServer#search_servlet
|
246
|
+
|
247
|
+
class MountTable # :nodoc:
|
218
248
|
def initialize
|
219
249
|
@tab = Hash.new
|
220
250
|
compile
|
@@ -251,12 +281,12 @@ module WEBrick
|
|
251
281
|
k.sort!
|
252
282
|
k.reverse!
|
253
283
|
k.collect!{|path| Regexp.escape(path) }
|
254
|
-
@scanner = Regexp.new("
|
284
|
+
@scanner = Regexp.new("\\A(" + k.join("|") +")(?=/|\\z)")
|
255
285
|
end
|
256
286
|
|
257
287
|
def normalize(dir)
|
258
288
|
ret = dir ? dir.dup : ""
|
259
|
-
ret.sub!(%r
|
289
|
+
ret.sub!(%r|/+\z|, "")
|
260
290
|
ret
|
261
291
|
end
|
262
292
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httpservlet.rb -- HTTPServlet Module
|
3
4
|
#
|
@@ -8,11 +9,9 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
require 'webrick/httputils'
|
15
|
-
require 'webrick/httpstatus'
|
12
|
+
require_relative '../htmlutils'
|
13
|
+
require_relative '../httputils'
|
14
|
+
require_relative '../httpstatus'
|
16
15
|
|
17
16
|
module WEBrick
|
18
17
|
module HTTPServlet
|
@@ -54,7 +53,7 @@ module WEBrick
|
|
54
53
|
# Servlets can be configured via initialize. The first argument is the
|
55
54
|
# HTTP server the servlet is being initialized for.
|
56
55
|
#
|
57
|
-
# class
|
56
|
+
# class Configurable < Simple
|
58
57
|
# def initialize server, color, size
|
59
58
|
# super server
|
60
59
|
# @color = color
|