webrick 1.8.1 → 1.9.1
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.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/README.md +2 -0
- data/Rakefile +0 -7
- data/lib/webrick/cgi.rb +1 -1
- data/lib/webrick/httpauth/authenticator.rb +4 -4
- data/lib/webrick/httpauth/htgroup.rb +1 -1
- data/lib/webrick/httpauth/htpasswd.rb +2 -2
- data/lib/webrick/httpproxy.rb +4 -4
- data/lib/webrick/httprequest.rb +42 -14
- data/lib/webrick/httpresponse.rb +1 -1
- data/lib/webrick/httpserver.rb +2 -2
- data/lib/webrick/httpservlet/abstract.rb +1 -1
- data/lib/webrick/httpservlet/filehandler.rb +6 -6
- data/lib/webrick/httputils.rb +34 -14
- data/lib/webrick/server.rb +1 -1
- data/lib/webrick/version.rb +1 -1
- data/sig/accesslog.rbs +24 -0
- data/sig/cgi.rbs +92 -0
- data/sig/compat.rbs +18 -0
- data/sig/config.rbs +17 -0
- data/sig/cookie.rbs +37 -0
- data/sig/htmlutils.rbs +5 -0
- data/sig/httpauth/authenticator.rbs +55 -0
- data/sig/httpauth/basicauth.rbs +29 -0
- data/sig/httpauth/digestauth.rbs +85 -0
- data/sig/httpauth/htdigest.rbs +31 -0
- data/sig/httpauth/htgroup.rbs +21 -0
- data/sig/httpauth/htpasswd.rbs +31 -0
- data/sig/httpauth/userdb.rbs +13 -0
- data/sig/httpauth.rbs +13 -0
- data/sig/httpproxy.rbs +61 -0
- data/sig/httprequest.rbs +167 -0
- data/sig/httpresponse.rbs +117 -0
- data/sig/https.rbs +49 -0
- data/sig/httpserver.rbs +71 -0
- data/sig/httpservlet/abstract.rbs +36 -0
- data/sig/httpservlet/cgi_runner.rbs +3 -0
- data/sig/httpservlet/cgihandler.rbs +23 -0
- data/sig/httpservlet/erbhandler.rbs +17 -0
- data/sig/httpservlet/filehandler.rbs +76 -0
- data/sig/httpservlet/prochandler.rbs +21 -0
- data/sig/httpservlet.rbs +4 -0
- data/sig/httpstatus.rbs +255 -0
- data/sig/httputils.rbs +116 -0
- data/sig/httpversion.rbs +17 -0
- data/sig/log.rbs +93 -0
- data/sig/manifest.yaml +8 -0
- data/sig/server.rbs +57 -0
- data/sig/ssl.rbs +19 -0
- data/sig/utils.rbs +122 -0
- data/sig/version.rbs +3 -0
- data/webrick.gemspec +35 -0
- metadata +43 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d133a0575bc3ed8393d991def2829498130eac921b9485e47d00a6259ec00fe6
|
4
|
+
data.tar.gz: 2e8da0c038c346abc67b325c41408199eb6475ee7fad9a155c67330ca15c5aed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5f68a58deca28be7dbde1b557a17a16f9d69c244c567830b89b22c26689db8b28e6a69097e6f47fc3d50d9caea69c691ead0468ef13777081aaf03e0d7c46f2
|
7
|
+
data.tar.gz: b9c35a51cf9d662d2151dd40d79c2cceebe5404fe5e8464cd666eff3127729a7225b728e78f59bfc08ea545b4de1046dad1c08a65e1e2fd402e91a0c53a264e6
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,8 @@ A WEBrick server can be composed of multiple WEBrick servers or servlets to prov
|
|
10
10
|
|
11
11
|
WEBrick also includes tools for daemonizing a process and starting a process at a higher privilege level and dropping permissions.
|
12
12
|
|
13
|
+
WEBrick is suitable for use in testing and for development. However, while the developers of WEBrick will attempt to fix security issues, they do not encourage the use of WEBrick to serve production web applications that may be subject to hostile input.
|
14
|
+
|
13
15
|
## Installation
|
14
16
|
|
15
17
|
Add this line to your application's Gemfile:
|
data/Rakefile
CHANGED
@@ -7,11 +7,4 @@ Rake::TestTask.new(:test) do |t|
|
|
7
7
|
t.test_files = FileList["test/**/test_*.rb"]
|
8
8
|
end
|
9
9
|
|
10
|
-
task :sync_tool do
|
11
|
-
require 'fileutils'
|
12
|
-
FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
|
13
|
-
FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
|
14
|
-
FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
|
15
|
-
end
|
16
|
-
|
17
10
|
task :default => :test
|
data/lib/webrick/cgi.rb
CHANGED
@@ -108,10 +108,10 @@ module WEBrick
|
|
108
108
|
# authentication schemes for proxies.
|
109
109
|
|
110
110
|
module ProxyAuthenticator
|
111
|
-
RequestField
|
112
|
-
ResponseField
|
113
|
-
|
114
|
-
AuthException
|
111
|
+
RequestField = "Proxy-Authorization" # :nodoc:
|
112
|
+
ResponseField = "Proxy-Authenticate" # :nodoc:
|
113
|
+
ResponseInfoField = "Proxy-Authentication-Info" # :nodoc:
|
114
|
+
AuthException = HTTPStatus::ProxyAuthenticationRequired # :nodoc:
|
115
115
|
end
|
116
116
|
end
|
117
117
|
end
|
@@ -77,12 +77,12 @@ module WEBrick
|
|
77
77
|
if @password_hash == :bcrypt
|
78
78
|
raise StandardError, ".htpasswd file contains crypt password, only bcrypt passwords supported"
|
79
79
|
end
|
80
|
-
user, pass = line.split(":")
|
80
|
+
user, pass = line.split(":", 2)
|
81
81
|
when %r!\A[^:]+:\$2[aby]\$\d{2}\$.{53}\z!
|
82
82
|
if @password_hash == :crypt
|
83
83
|
raise StandardError, ".htpasswd file contains bcrypt password, only crypt passwords supported"
|
84
84
|
end
|
85
|
-
user, pass = line.split(":")
|
85
|
+
user, pass = line.split(":", 2)
|
86
86
|
when /:\$/, /:{SHA}/
|
87
87
|
raise NotImplementedError,
|
88
88
|
'MD5, SHA1 .htpasswd file not supported'
|
data/lib/webrick/httpproxy.rb
CHANGED
@@ -118,7 +118,7 @@ module WEBrick
|
|
118
118
|
public_send("do_#{req.request_method}", req, res)
|
119
119
|
rescue NoMethodError
|
120
120
|
raise HTTPStatus::MethodNotAllowed,
|
121
|
-
"unsupported method
|
121
|
+
"unsupported method '#{req.request_method}'."
|
122
122
|
rescue => err
|
123
123
|
logger.debug("#{err.class}: #{err.message}")
|
124
124
|
raise HTTPStatus::ServiceUnavailable, err.message
|
@@ -149,7 +149,7 @@ module WEBrick
|
|
149
149
|
end
|
150
150
|
|
151
151
|
begin
|
152
|
-
@logger.debug("CONNECT: upstream proxy is
|
152
|
+
@logger.debug("CONNECT: upstream proxy is '#{host}:#{port}'.")
|
153
153
|
os = TCPSocket.new(host, port) # origin server
|
154
154
|
|
155
155
|
if proxy
|
@@ -175,7 +175,7 @@ module WEBrick
|
|
175
175
|
@logger.debug("CONNECT #{host}:#{port}: succeeded")
|
176
176
|
res.status = HTTPStatus::RC_OK
|
177
177
|
rescue => ex
|
178
|
-
@logger.debug("CONNECT #{host}:#{port}: failed
|
178
|
+
@logger.debug("CONNECT #{host}:#{port}: failed '#{ex.message}'")
|
179
179
|
res.set_error(ex)
|
180
180
|
raise HTTPStatus::EOFError
|
181
181
|
ensure
|
@@ -241,7 +241,7 @@ module WEBrick
|
|
241
241
|
if HopByHop.member?(key) || # RFC2616: 13.5.1
|
242
242
|
connections.member?(key) || # RFC2616: 14.10
|
243
243
|
ShouldNotTransfer.member?(key) # pragmatics
|
244
|
-
@logger.debug("choose_header:
|
244
|
+
@logger.debug("choose_header: '#{key}: #{value}'")
|
245
245
|
next
|
246
246
|
end
|
247
247
|
dst[key] = value
|
data/lib/webrick/httprequest.rb
CHANGED
@@ -162,7 +162,6 @@ module WEBrick
|
|
162
162
|
@script_name = @path_info = nil
|
163
163
|
@query_string = nil
|
164
164
|
@query = nil
|
165
|
-
@form_data = nil
|
166
165
|
|
167
166
|
@raw_header = Array.new
|
168
167
|
@header = nil
|
@@ -173,7 +172,8 @@ module WEBrick
|
|
173
172
|
@accept_language = []
|
174
173
|
@body = +""
|
175
174
|
|
176
|
-
@addr =
|
175
|
+
@addr = []
|
176
|
+
@peeraddr = []
|
177
177
|
@attributes = {}
|
178
178
|
@user = nil
|
179
179
|
@keep_alive = false
|
@@ -224,7 +224,7 @@ module WEBrick
|
|
224
224
|
@script_name = ""
|
225
225
|
@path_info = @path.dup
|
226
226
|
rescue
|
227
|
-
raise HTTPStatus::BadRequest, "bad URI
|
227
|
+
raise HTTPStatus::BadRequest, "bad URI '#{@unparsed_uri}'."
|
228
228
|
end
|
229
229
|
|
230
230
|
if /\Aclose\z/io =~ self["connection"]
|
@@ -318,7 +318,7 @@ module WEBrick
|
|
318
318
|
def [](header_name)
|
319
319
|
if @header
|
320
320
|
value = @header[header_name.downcase]
|
321
|
-
value.empty? ? nil : value.join
|
321
|
+
value.empty? ? nil : value.join
|
322
322
|
end
|
323
323
|
end
|
324
324
|
|
@@ -329,7 +329,7 @@ module WEBrick
|
|
329
329
|
if @header
|
330
330
|
@header.each{|k, v|
|
331
331
|
value = @header[k]
|
332
|
-
yield(k, value.empty? ? nil : value.join
|
332
|
+
yield(k, value.empty? ? nil : value.join)
|
333
333
|
}
|
334
334
|
end
|
335
335
|
end
|
@@ -402,7 +402,7 @@ module WEBrick
|
|
402
402
|
# This method provides the metavariables defined by the revision 3
|
403
403
|
# of "The WWW Common Gateway Interface Version 1.1"
|
404
404
|
# To browse the current document of CGI Version 1.1, see below:
|
405
|
-
#
|
405
|
+
# https://www.rfc-editor.org/rfc/rfc3875
|
406
406
|
|
407
407
|
def meta_vars
|
408
408
|
meta = Hash.new
|
@@ -458,27 +458,46 @@ module WEBrick
|
|
458
458
|
end
|
459
459
|
|
460
460
|
@request_time = Time.now
|
461
|
-
if /^(\S+)
|
461
|
+
if /^(\S+) (\S++)(?: HTTP\/(\d+\.\d+))?\r\n/mo =~ @request_line
|
462
462
|
@request_method = $1
|
463
463
|
@unparsed_uri = $2
|
464
464
|
@http_version = HTTPVersion.new($3 ? $3 : "0.9")
|
465
465
|
else
|
466
466
|
rl = @request_line.sub(/\x0d?\x0a\z/o, '')
|
467
|
-
raise HTTPStatus::BadRequest, "bad Request-Line
|
467
|
+
raise HTTPStatus::BadRequest, "bad Request-Line '#{rl}'."
|
468
468
|
end
|
469
469
|
end
|
470
470
|
|
471
471
|
def read_header(socket)
|
472
472
|
if socket
|
473
|
+
end_of_headers = false
|
474
|
+
|
473
475
|
while line = read_line(socket)
|
474
|
-
|
476
|
+
if line == CRLF
|
477
|
+
end_of_headers = true
|
478
|
+
break
|
479
|
+
end
|
475
480
|
if (@request_bytes += line.bytesize) > MAX_HEADER_LENGTH
|
476
481
|
raise HTTPStatus::RequestEntityTooLarge, 'headers too large'
|
477
482
|
end
|
483
|
+
if line.include?("\x00")
|
484
|
+
raise HTTPStatus::BadRequest, 'null byte in header'
|
485
|
+
end
|
478
486
|
@raw_header << line
|
479
487
|
end
|
488
|
+
|
489
|
+
# Allow if @header already set to support chunked trailers
|
490
|
+
raise HTTPStatus::EOFError unless end_of_headers || @header
|
480
491
|
end
|
481
492
|
@header = HTTPUtils::parse_header(@raw_header.join)
|
493
|
+
|
494
|
+
if (content_length = @header['content-length']) && content_length.length != 0
|
495
|
+
if content_length.length > 1
|
496
|
+
raise HTTPStatus::BadRequest, "multiple content-length request headers"
|
497
|
+
elsif !/\A\d+\z/.match?(content_length[0])
|
498
|
+
raise HTTPStatus::BadRequest, "invalid content-length request header"
|
499
|
+
end
|
500
|
+
end
|
482
501
|
end
|
483
502
|
|
484
503
|
def parse_uri(str, scheme="http")
|
@@ -503,14 +522,19 @@ module WEBrick
|
|
503
522
|
return URI::parse(uri.to_s)
|
504
523
|
end
|
505
524
|
|
525
|
+
host_pattern = URI::RFC2396_Parser.new.pattern.fetch(:HOST)
|
526
|
+
HOST_PATTERN = /\A(#{host_pattern})(?::(\d+))?\z/n
|
506
527
|
def parse_host_request_line(host)
|
507
|
-
|
508
|
-
host.scan(pattern)[0]
|
528
|
+
host.scan(HOST_PATTERN)[0]
|
509
529
|
end
|
510
530
|
|
511
531
|
def read_body(socket, block)
|
512
532
|
return unless socket
|
513
533
|
if tc = self['transfer-encoding']
|
534
|
+
if self['content-length']
|
535
|
+
raise HTTPStatus::BadRequest, "request with both transfer-encoding and content-length, possible request smuggling"
|
536
|
+
end
|
537
|
+
|
514
538
|
case tc
|
515
539
|
when /\Achunked\z/io then read_chunked(socket, block)
|
516
540
|
else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
|
@@ -534,12 +558,12 @@ module WEBrick
|
|
534
558
|
|
535
559
|
def read_chunk_size(socket)
|
536
560
|
line = read_line(socket)
|
537
|
-
if
|
561
|
+
if /\A([0-9a-fA-F]+)(?:;(\S+(?:=\S+)?))?\r\n\z/ =~ line
|
538
562
|
chunk_size = $1.hex
|
539
563
|
chunk_ext = $2
|
540
564
|
[ chunk_size, chunk_ext ]
|
541
565
|
else
|
542
|
-
raise HTTPStatus::BadRequest, "bad chunk
|
566
|
+
raise HTTPStatus::BadRequest, "bad chunk '#{line}'."
|
543
567
|
end
|
544
568
|
end
|
545
569
|
|
@@ -555,7 +579,11 @@ module WEBrick
|
|
555
579
|
block.call(data)
|
556
580
|
end while (chunk_size -= sz) > 0
|
557
581
|
|
558
|
-
read_line(socket)
|
582
|
+
line = read_line(socket) # skip CRLF
|
583
|
+
unless line == "\r\n"
|
584
|
+
raise HTTPStatus::BadRequest, "extra data after chunk '#{line}'."
|
585
|
+
end
|
586
|
+
|
559
587
|
chunk_size, = read_chunk_size(socket)
|
560
588
|
end
|
561
589
|
read_header(socket) # trailer + CRLF
|
data/lib/webrick/httpresponse.rb
CHANGED
@@ -453,7 +453,7 @@ module WEBrick
|
|
453
453
|
_end_of_html_
|
454
454
|
|
455
455
|
if backtrace && $DEBUG
|
456
|
-
@body << "backtrace of
|
456
|
+
@body << "backtrace of '#{HTMLUtils::escape(ex.class.to_s)}' "
|
457
457
|
@body << "#{HTMLUtils::escape(ex.message)}"
|
458
458
|
@body << "<PRE>"
|
459
459
|
ex.backtrace.each{|line| @body << "\t#{line}\n"}
|
data/lib/webrick/httpserver.rb
CHANGED
@@ -128,11 +128,11 @@ module WEBrick
|
|
128
128
|
do_OPTIONS(req, res)
|
129
129
|
raise HTTPStatus::OK
|
130
130
|
end
|
131
|
-
raise HTTPStatus::NotFound, "
|
131
|
+
raise HTTPStatus::NotFound, "'#{req.unparsed_uri}' not found."
|
132
132
|
end
|
133
133
|
|
134
134
|
servlet, options, script_name, path_info = search_servlet(req.path)
|
135
|
-
raise HTTPStatus::NotFound, "
|
135
|
+
raise HTTPStatus::NotFound, "'#{req.path}' not found." unless servlet
|
136
136
|
req.script_name = script_name
|
137
137
|
req.path_info = path_info
|
138
138
|
si = servlet.get_instance(self, *options)
|
@@ -250,7 +250,7 @@ module WEBrick
|
|
250
250
|
|
251
251
|
def do_POST(req, res)
|
252
252
|
unless exec_handler(req, res)
|
253
|
-
raise HTTPStatus::NotFound, "
|
253
|
+
raise HTTPStatus::NotFound, "'#{req.path}' not found."
|
254
254
|
end
|
255
255
|
end
|
256
256
|
|
@@ -307,7 +307,7 @@ module WEBrick
|
|
307
307
|
end
|
308
308
|
|
309
309
|
def exec_handler(req, res)
|
310
|
-
raise HTTPStatus::NotFound, "
|
310
|
+
raise HTTPStatus::NotFound, "'#{req.path}' not found." unless @root
|
311
311
|
if set_filename(req, res)
|
312
312
|
handler = get_handler(req, res)
|
313
313
|
call_callback(:HandlerCallback, req, res)
|
@@ -359,7 +359,7 @@ module WEBrick
|
|
359
359
|
call_callback(:FileCallback, req, res)
|
360
360
|
return true
|
361
361
|
else
|
362
|
-
raise HTTPStatus::NotFound, "
|
362
|
+
raise HTTPStatus::NotFound, "'#{req.path}' not found."
|
363
363
|
end
|
364
364
|
end
|
365
365
|
|
@@ -368,8 +368,8 @@ module WEBrick
|
|
368
368
|
|
369
369
|
def check_filename(req, res, name)
|
370
370
|
if nondisclosure_name?(name) || windows_ambiguous_name?(name)
|
371
|
-
@logger.warn("the request refers nondisclosure name
|
372
|
-
raise HTTPStatus::NotFound, "
|
371
|
+
@logger.warn("the request refers nondisclosure name '#{name}'.")
|
372
|
+
raise HTTPStatus::NotFound, "'#{req.path}' not found."
|
373
373
|
end
|
374
374
|
end
|
375
375
|
|
@@ -437,7 +437,7 @@ module WEBrick
|
|
437
437
|
def set_dir_list(req, res)
|
438
438
|
redirect_to_directory_uri(req, res)
|
439
439
|
unless @options[:FancyIndexing]
|
440
|
-
raise HTTPStatus::Forbidden, "no access permission to
|
440
|
+
raise HTTPStatus::Forbidden, "no access permission to '#{req.path}'"
|
441
441
|
end
|
442
442
|
local_path = res.filename
|
443
443
|
list = Dir::entries(local_path).collect{|name|
|
data/lib/webrick/httputils.rb
CHANGED
@@ -29,14 +29,14 @@ module WEBrick
|
|
29
29
|
# normalized.
|
30
30
|
|
31
31
|
def normalize_path(path)
|
32
|
-
raise "abnormal path
|
32
|
+
raise "abnormal path '#{path}'" if path[0] != ?/
|
33
33
|
ret = path.dup
|
34
34
|
|
35
35
|
ret.gsub!(%r{/+}o, '/') # // => /
|
36
36
|
while ret.sub!(%r'/\.(?:/|\Z)', '/'); end # /. => /
|
37
37
|
while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo
|
38
38
|
|
39
|
-
raise "abnormal path
|
39
|
+
raise "abnormal path '#{path}'" if %r{/\.\.(/|\Z)} =~ ret
|
40
40
|
ret
|
41
41
|
end
|
42
42
|
module_function :normalize_path
|
@@ -55,7 +55,6 @@ module WEBrick
|
|
55
55
|
"cer" => "application/pkix-cert",
|
56
56
|
"crl" => "application/pkix-crl",
|
57
57
|
"crt" => "application/x-x509-ca-cert",
|
58
|
-
#"crl" => "application/x-pkcs7-crl",
|
59
58
|
"css" => "text/css",
|
60
59
|
"dms" => "application/octet-stream",
|
61
60
|
"doc" => "application/msword",
|
@@ -153,28 +152,49 @@ module WEBrick
|
|
153
152
|
# Parses an HTTP header +raw+ into a hash of header fields with an Array
|
154
153
|
# of values.
|
155
154
|
|
155
|
+
class SplitHeader < Array
|
156
|
+
def join(separator = ", ")
|
157
|
+
super
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class CookieHeader < Array
|
162
|
+
def join(separator = "; ")
|
163
|
+
super
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
HEADER_CLASSES = Hash.new(SplitHeader).update({
|
168
|
+
"cookie" => CookieHeader,
|
169
|
+
})
|
170
|
+
|
156
171
|
def parse_header(raw)
|
157
172
|
header = Hash.new([].freeze)
|
158
173
|
field = nil
|
159
174
|
raw.each_line{|line|
|
160
175
|
case line
|
161
|
-
when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+)
|
176
|
+
when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):([^\r\n\0]*?)\r\n\z/om
|
162
177
|
field, value = $1, $2
|
163
178
|
field.downcase!
|
164
|
-
header[field] = [] unless header.has_key?(field)
|
179
|
+
header[field] = HEADER_CLASSES[field].new unless header.has_key?(field)
|
165
180
|
header[field] << value
|
166
|
-
when
|
167
|
-
value = $1
|
181
|
+
when /^[ \t]+([^\r\n\0]*?)\r\n/om
|
168
182
|
unless field
|
169
183
|
raise HTTPStatus::BadRequest, "bad header '#{line}'."
|
170
184
|
end
|
185
|
+
value = line
|
186
|
+
value.gsub!(/\A[ \t]+/, '')
|
187
|
+
value.slice!(-2..-1)
|
171
188
|
header[field][-1] << " " << value
|
172
189
|
else
|
173
190
|
raise HTTPStatus::BadRequest, "bad header '#{line}'."
|
174
191
|
end
|
175
192
|
}
|
176
193
|
header.each{|key, values|
|
177
|
-
values.each
|
194
|
+
values.each{|value|
|
195
|
+
value.gsub!(/\A[ \t]+/, '')
|
196
|
+
value.gsub!(/[ \t]+\z/, '')
|
197
|
+
}
|
178
198
|
}
|
179
199
|
header
|
180
200
|
end
|
@@ -184,8 +204,8 @@ module WEBrick
|
|
184
204
|
# Splits a header value +str+ according to HTTP specification.
|
185
205
|
|
186
206
|
def split_header_value(str)
|
187
|
-
str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]
|
188
|
-
(
|
207
|
+
str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]++)+)
|
208
|
+
(?:,[ \t]*|\Z)'xn).flatten
|
189
209
|
end
|
190
210
|
module_function :split_header_value
|
191
211
|
|
@@ -213,9 +233,9 @@ module WEBrick
|
|
213
233
|
def parse_qvalues(value)
|
214
234
|
tmp = []
|
215
235
|
if value
|
216
|
-
parts = value.split(
|
236
|
+
parts = value.split(/,[ \t]*/)
|
217
237
|
parts.each {|part|
|
218
|
-
if m = %r{^([
|
238
|
+
if m = %r{^([^ \t,]+?)(?:;[ \t]*q=(\d+(?:\.\d+)?))?$}.match(part)
|
219
239
|
val = m[1]
|
220
240
|
q = (m[2] or 1).to_f
|
221
241
|
tmp.push([val, q])
|
@@ -314,8 +334,8 @@ module WEBrick
|
|
314
334
|
elsif str == CRLF
|
315
335
|
@header = HTTPUtils::parse_header(@raw_header.join)
|
316
336
|
if cd = self['content-disposition']
|
317
|
-
if
|
318
|
-
if
|
337
|
+
if /[ \t]+name="(.*?)"/ =~ cd then @name = $1 end
|
338
|
+
if /[ \t]+filename="(.*?)"/ =~ cd then @filename = $1 end
|
319
339
|
end
|
320
340
|
else
|
321
341
|
@raw_header << str
|
data/lib/webrick/server.rb
CHANGED
@@ -365,7 +365,7 @@ module WEBrick
|
|
365
365
|
begin
|
366
366
|
s.shutdown
|
367
367
|
rescue Errno::ENOTCONN
|
368
|
-
# when
|
368
|
+
# when 'Errno::ENOTCONN: Socket is not connected' on some platforms,
|
369
369
|
# call #close instead of #shutdown.
|
370
370
|
# (ignore @config[:ShutdownSocketWithoutClose])
|
371
371
|
s.close
|
data/lib/webrick/version.rb
CHANGED
data/sig/accesslog.rbs
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module WEBrick
|
2
|
+
module AccessLog
|
3
|
+
class AccessLogError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
CLF_TIME_FORMAT: String
|
7
|
+
|
8
|
+
COMMON_LOG_FORMAT: String
|
9
|
+
|
10
|
+
CLF: String
|
11
|
+
|
12
|
+
REFERER_LOG_FORMAT: String
|
13
|
+
|
14
|
+
AGENT_LOG_FORMAT: String
|
15
|
+
|
16
|
+
COMBINED_LOG_FORMAT: String
|
17
|
+
|
18
|
+
def self?.setup_params: (Hash[Symbol, untyped] config, HTTPRequest req, HTTPResponse res) -> Hash[String, untyped]
|
19
|
+
|
20
|
+
def self?.format: (String format_string, Hash[String, untyped] params) -> String
|
21
|
+
|
22
|
+
def self?.escape: (String data) -> String
|
23
|
+
end
|
24
|
+
end
|
data/sig/cgi.rbs
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
module WEBrick
|
2
|
+
class CGI
|
3
|
+
@options: Array[untyped]
|
4
|
+
|
5
|
+
class CGIError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader config: Hash[Symbol, untyped]
|
9
|
+
|
10
|
+
attr_reader logger: BasicLog
|
11
|
+
|
12
|
+
def initialize: (*untyped args) -> void
|
13
|
+
|
14
|
+
def []: (Symbol key) -> untyped
|
15
|
+
|
16
|
+
interface _Env
|
17
|
+
def []: (String) -> String?
|
18
|
+
end
|
19
|
+
|
20
|
+
def start: (?_Env env, ?IO stdin, ?IO stdout) -> void
|
21
|
+
|
22
|
+
def self.setup_header: () -> untyped
|
23
|
+
|
24
|
+
def self.status_line: () -> ""
|
25
|
+
|
26
|
+
def service: (HTTPRequest req, HTTPResponse res) -> void
|
27
|
+
|
28
|
+
class Socket
|
29
|
+
@config: Hash[Symbol, untyped]
|
30
|
+
|
31
|
+
@env: _Env
|
32
|
+
|
33
|
+
@header_part: StringIO
|
34
|
+
|
35
|
+
@body_part: IO
|
36
|
+
|
37
|
+
@out_port: IO
|
38
|
+
|
39
|
+
@server_addr: String
|
40
|
+
|
41
|
+
@server_name: String?
|
42
|
+
|
43
|
+
@server_port: String?
|
44
|
+
|
45
|
+
@remote_addr: String?
|
46
|
+
|
47
|
+
@remote_host: String?
|
48
|
+
|
49
|
+
@remote_port: (String | 0)
|
50
|
+
|
51
|
+
include Enumerable[String]
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def initialize: (Hash[Symbol, untyped] config, _Env env, IO stdin, IO stdout) -> void
|
56
|
+
|
57
|
+
def request_line: () -> String
|
58
|
+
|
59
|
+
def setup_header: () -> void
|
60
|
+
|
61
|
+
def add_header: (String hdrname, String value) -> void
|
62
|
+
|
63
|
+
def input: () -> (IO | StringIO)
|
64
|
+
|
65
|
+
public
|
66
|
+
|
67
|
+
def peeraddr: () -> [nil, (String | 0), String?, String?]
|
68
|
+
|
69
|
+
def addr: () -> [nil, String?, String?, String]
|
70
|
+
|
71
|
+
def gets: (?String eol, ?Integer? size) -> String?
|
72
|
+
|
73
|
+
def read: (?Integer? size) -> String?
|
74
|
+
|
75
|
+
def each: () { (String) -> void } -> void
|
76
|
+
|
77
|
+
def eof?: () -> bool
|
78
|
+
|
79
|
+
def <<: (_ToS data) -> IO
|
80
|
+
|
81
|
+
def write: (_ToS data) -> Integer
|
82
|
+
|
83
|
+
def cert: () -> OpenSSL::X509::Certificate?
|
84
|
+
|
85
|
+
def peer_cert: () -> OpenSSL::X509::Certificate?
|
86
|
+
|
87
|
+
def peer_cert_chain: () -> Array[OpenSSL::X509::Certificate]?
|
88
|
+
|
89
|
+
def cipher: () -> [String?, String?, String?, String?]?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/sig/compat.rbs
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# System call error module used by webrick for cross platform compatibility.
|
3
|
+
#
|
4
|
+
# EPROTO:: protocol error
|
5
|
+
# ECONNRESET:: remote host reset the connection request
|
6
|
+
# ECONNABORTED:: Client sent TCP reset (RST) before server has accepted the
|
7
|
+
# connection requested by client.
|
8
|
+
#
|
9
|
+
module Errno
|
10
|
+
class EPROTO < SystemCallError
|
11
|
+
end
|
12
|
+
|
13
|
+
class ECONNRESET < SystemCallError
|
14
|
+
end
|
15
|
+
|
16
|
+
class ECONNABORTED < SystemCallError
|
17
|
+
end
|
18
|
+
end
|
data/sig/config.rbs
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module WEBrick
|
2
|
+
module Config
|
3
|
+
LIBDIR: String
|
4
|
+
|
5
|
+
# for GenericServer
|
6
|
+
General: Hash[Symbol, untyped]
|
7
|
+
|
8
|
+
# for HTTPServer, HTTPRequest, HTTPResponse ...
|
9
|
+
HTTP: Hash[Symbol, untyped]
|
10
|
+
|
11
|
+
FileHandler: Hash[Symbol, untyped]
|
12
|
+
|
13
|
+
BasicAuth: Hash[Symbol, untyped]
|
14
|
+
|
15
|
+
DigestAuth: Hash[Symbol, untyped]
|
16
|
+
end
|
17
|
+
end
|