webrick 1.8.1 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/README.md +2 -0
- data/Rakefile +0 -7
- data/lib/webrick/httprequest.rb +37 -9
- data/lib/webrick/httputils.rb +32 -12
- 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 +169 -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: 706b97607998e5b9d2a966fd09af6f7fa6a5b40f2df22977b111e5afa2bbc0f6
|
4
|
+
data.tar.gz: e4376566540a86f896f31b61ed924d69f0fb415fe491273b0365169c16663ef7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4321cb073b84fc0e32211b4fa1510520ec396a62b3165761638e84471a1e56915f751d46aceae6ac8d13aafd09b9066a05928a5b76abf3c82bc8501e74a9029
|
7
|
+
data.tar.gz: 9f66a53d89839da69abb3afd75a48f746e4023f888db3afd404a903bebde1f878318f08dff470e3006e1fa0637185f9f5bdc9e59c627f162e3664a482b149d06
|
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/httprequest.rb
CHANGED
@@ -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,7 +458,7 @@ 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")
|
@@ -470,15 +470,34 @@ module WEBrick
|
|
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,7 +558,7 @@ 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 ]
|
@@ -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/httputils.rb
CHANGED
@@ -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/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
|
data/sig/cookie.rbs
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module WEBrick
|
2
|
+
class Cookie
|
3
|
+
@expires: String?
|
4
|
+
|
5
|
+
attr_reader name: String?
|
6
|
+
|
7
|
+
attr_accessor value: String?
|
8
|
+
|
9
|
+
attr_accessor version: Integer
|
10
|
+
|
11
|
+
#
|
12
|
+
# The cookie domain
|
13
|
+
attr_accessor domain: String?
|
14
|
+
|
15
|
+
attr_accessor path: String?
|
16
|
+
|
17
|
+
attr_accessor secure: true?
|
18
|
+
|
19
|
+
attr_accessor comment: String?
|
20
|
+
|
21
|
+
attr_accessor max_age: Integer?
|
22
|
+
|
23
|
+
def initialize: (untyped name, untyped value) -> void
|
24
|
+
|
25
|
+
def expires=: ((Time | _ToS)? t) -> untyped
|
26
|
+
|
27
|
+
def expires: () -> Time?
|
28
|
+
|
29
|
+
def to_s: () -> String
|
30
|
+
|
31
|
+
def self.parse: (String? str) -> Array[instance]?
|
32
|
+
|
33
|
+
def self.parse_set_cookie: (String str) -> instance
|
34
|
+
|
35
|
+
def self.parse_set_cookies: (String str) -> Array[instance]
|
36
|
+
end
|
37
|
+
end
|
data/sig/htmlutils.rbs
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module WEBrick
|
2
|
+
module HTTPAuth
|
3
|
+
module Authenticator
|
4
|
+
@reload_db: bool?
|
5
|
+
|
6
|
+
@request_field: String
|
7
|
+
|
8
|
+
@response_field: String
|
9
|
+
|
10
|
+
@resp_info_field: String
|
11
|
+
|
12
|
+
@auth_exception: singleton(HTTPStatus::ClientError)
|
13
|
+
|
14
|
+
@auth_scheme: String
|
15
|
+
|
16
|
+
RequestField: String
|
17
|
+
|
18
|
+
ResponseField: String
|
19
|
+
|
20
|
+
ResponseInfoField: String
|
21
|
+
|
22
|
+
AuthException: singleton(HTTPStatus::ClientError)
|
23
|
+
|
24
|
+
AuthScheme: String?
|
25
|
+
|
26
|
+
attr_reader realm: String?
|
27
|
+
|
28
|
+
attr_reader userdb: UserDB
|
29
|
+
|
30
|
+
attr_reader logger: Log
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def check_init: (Hash[Symbol, untyped] config) -> void
|
35
|
+
|
36
|
+
def check_scheme: (HTTPRequest req) -> String?
|
37
|
+
|
38
|
+
def log: (interned meth, String fmt, *untyped args) -> void
|
39
|
+
|
40
|
+
def error: (String fmt, *untyped args) -> void
|
41
|
+
|
42
|
+
def info: (String fmt, *untyped args) -> void
|
43
|
+
end
|
44
|
+
|
45
|
+
module ProxyAuthenticator
|
46
|
+
RequestField: String
|
47
|
+
|
48
|
+
ResponseField: String
|
49
|
+
|
50
|
+
InfoField: String
|
51
|
+
|
52
|
+
AuthException: singleton(HTTPStatus::ClientError)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module WEBrick
|
2
|
+
module HTTPAuth
|
3
|
+
class BasicAuth
|
4
|
+
@config: Hash[Symbol, untyped]
|
5
|
+
|
6
|
+
include Authenticator
|
7
|
+
|
8
|
+
AuthScheme: String
|
9
|
+
|
10
|
+
def self.make_passwd: (String? realm, String? user, String? pass) -> String
|
11
|
+
|
12
|
+
attr_reader realm: String?
|
13
|
+
|
14
|
+
attr_reader userdb: UserDB
|
15
|
+
|
16
|
+
attr_reader logger: Log
|
17
|
+
|
18
|
+
def initialize: (Hash[Symbol, untyped] config, ?Hash[Symbol, untyped] default) -> void
|
19
|
+
|
20
|
+
def authenticate: (HTTPRequest req, HTTPResponse res) -> void
|
21
|
+
|
22
|
+
def challenge: (HTTPRequest req, HTTPResponse res) -> bot
|
23
|
+
end
|
24
|
+
|
25
|
+
class ProxyBasicAuth < BasicAuth
|
26
|
+
include ProxyAuthenticator
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module WEBrick
|
2
|
+
module HTTPAuth
|
3
|
+
class DigestAuth
|
4
|
+
@config: Hash[Symbol, untyped]
|
5
|
+
|
6
|
+
@domain: Array[String]?
|
7
|
+
|
8
|
+
@use_opaque: bool
|
9
|
+
|
10
|
+
@use_next_nonce: bool
|
11
|
+
|
12
|
+
@check_nc: bool
|
13
|
+
|
14
|
+
@use_auth_info_header: bool
|
15
|
+
|
16
|
+
@nonce_expire_period: Integer
|
17
|
+
|
18
|
+
@nonce_expire_delta: Integer
|
19
|
+
|
20
|
+
@internet_explorer_hack: bool
|
21
|
+
|
22
|
+
@h: singleton(Digest::Base)
|
23
|
+
|
24
|
+
@instance_key: String
|
25
|
+
|
26
|
+
@opaques: Hash[String, OpaqueInfo]
|
27
|
+
|
28
|
+
@last_nonce_expire: Time
|
29
|
+
|
30
|
+
@mutex: Thread::Mutex
|
31
|
+
|
32
|
+
include Authenticator
|
33
|
+
|
34
|
+
AuthScheme: String
|
35
|
+
|
36
|
+
class OpaqueInfo < Struct[untyped]
|
37
|
+
attr_accessor time(): Time
|
38
|
+
attr_accessor nonce(): String?
|
39
|
+
attr_accessor nc(): String
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader algorithm: String?
|
43
|
+
|
44
|
+
attr_reader qop: Array[String]
|
45
|
+
|
46
|
+
def self.make_passwd: (String realm, String user, String pass) -> untyped
|
47
|
+
|
48
|
+
def initialize: (Hash[Symbol, untyped] config, ?Hash[Symbol, untyped] default) -> void
|
49
|
+
|
50
|
+
def authenticate: (HTTPRequest req, HTTPResponse res) -> void
|
51
|
+
|
52
|
+
def challenge: (HTTPRequest req, HTTPResponse res, ?bool stale) -> bot
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
MustParams: Array[String]
|
57
|
+
|
58
|
+
MustParamsAuth: Array[String]
|
59
|
+
|
60
|
+
def _authenticate: (HTTPRequest req, HTTPResponse res) -> (:nonce_is_stale | bool)
|
61
|
+
|
62
|
+
def split_param_value: (String string) -> Hash[String, String]
|
63
|
+
|
64
|
+
def generate_next_nonce: (HTTPRequest req) -> String
|
65
|
+
|
66
|
+
def check_nonce: (HTTPRequest req, Hash[String, String] auth_req) -> bool
|
67
|
+
|
68
|
+
def generate_opaque: (HTTPRequest req) -> String
|
69
|
+
|
70
|
+
def check_opaque: (OpaqueInfo opaque_struct, untyped req, Hash[String, String] auth_req) -> bool
|
71
|
+
|
72
|
+
def check_uri: (HTTPRequest req, Hash[String, String] auth_req) -> bool
|
73
|
+
|
74
|
+
def hexdigest: (*_ToS? args) -> String
|
75
|
+
end
|
76
|
+
|
77
|
+
class ProxyDigestAuth < DigestAuth
|
78
|
+
include ProxyAuthenticator
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def check_uri: (HTTPRequest req, Hash[String, String] auth_req) -> true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module WEBrick
|
2
|
+
module HTTPAuth
|
3
|
+
class Htdigest
|
4
|
+
@path: String
|
5
|
+
|
6
|
+
@mtime: Time
|
7
|
+
|
8
|
+
@digest: Hash[String, Hash[String, String]]
|
9
|
+
|
10
|
+
@mutex: Thread::Mutex
|
11
|
+
|
12
|
+
@auth_type: String
|
13
|
+
|
14
|
+
include UserDB
|
15
|
+
|
16
|
+
def initialize: (String path) -> void
|
17
|
+
|
18
|
+
def reload: () -> void
|
19
|
+
|
20
|
+
def flush: (?String? output) -> void
|
21
|
+
|
22
|
+
def get_passwd: (String realm, String user, bool reload_db) -> String?
|
23
|
+
|
24
|
+
def set_passwd: (String realm, String user, String pass) -> String
|
25
|
+
|
26
|
+
def delete_passwd: (String realm, String user) -> String?
|
27
|
+
|
28
|
+
def each: () { (String user, String realm, String password_hash) -> void } -> void
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module WEBrick
|
2
|
+
module HTTPAuth
|
3
|
+
class Htgroup
|
4
|
+
@path: String
|
5
|
+
|
6
|
+
@mtime: Time
|
7
|
+
|
8
|
+
@group: Hash[String, Array[String]]
|
9
|
+
|
10
|
+
def initialize: (String path) -> void
|
11
|
+
|
12
|
+
def reload: () -> void
|
13
|
+
|
14
|
+
def flush: (?String? output) -> void
|
15
|
+
|
16
|
+
def members: (String group) -> Array[String]
|
17
|
+
|
18
|
+
def add: (String group, Array[String] members) -> void
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|