webrick 1.4.2 → 1.7.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 +4 -4
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +61 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/webrick.rb +8 -3
- data/lib/webrick/accesslog.rb +3 -5
- data/lib/webrick/cgi.rb +7 -3
- data/lib/webrick/config.rb +5 -5
- data/lib/webrick/cookie.rb +1 -1
- data/lib/webrick/httpauth.rb +5 -5
- data/lib/webrick/httpauth/authenticator.rb +1 -1
- data/lib/webrick/httpauth/basicauth.rb +13 -5
- data/lib/webrick/httpauth/digestauth.rb +10 -23
- data/lib/webrick/httpauth/htdigest.rb +2 -2
- data/lib/webrick/httpauth/htgroup.rb +7 -4
- data/lib/webrick/httpauth/htpasswd.rb +37 -4
- data/lib/webrick/httpproxy.rb +51 -35
- data/lib/webrick/httprequest.rb +65 -16
- data/lib/webrick/httpresponse.rb +111 -52
- data/lib/webrick/https.rb +2 -2
- data/lib/webrick/httpserver.rb +23 -9
- data/lib/webrick/httpservlet.rb +5 -5
- data/lib/webrick/httpservlet/abstract.rb +3 -3
- data/lib/webrick/httpservlet/cgihandler.rb +10 -6
- data/lib/webrick/httpservlet/erbhandler.rb +1 -1
- data/lib/webrick/httpservlet/filehandler.rb +62 -32
- data/lib/webrick/httpservlet/prochandler.rb +1 -1
- data/lib/webrick/httpstatus.rb +1 -1
- data/lib/webrick/httputils.rb +3 -4
- data/lib/webrick/server.rb +5 -2
- data/lib/webrick/ssl.rb +3 -3
- data/lib/webrick/utils.rb +1 -6
- data/lib/webrick/version.rb +1 -1
- data/webrick.gemspec +74 -0
- metadata +18 -13
data/lib/webrick/https.rb
CHANGED
data/lib/webrick/httpserver.rb
CHANGED
@@ -10,13 +10,13 @@
|
|
10
10
|
# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $
|
11
11
|
|
12
12
|
require 'io/wait'
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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'
|
20
20
|
|
21
21
|
module WEBrick
|
22
22
|
class HTTPServerError < ServerError; end
|
@@ -68,8 +68,8 @@ module WEBrick
|
|
68
68
|
|
69
69
|
def run(sock)
|
70
70
|
while true
|
71
|
-
|
72
|
-
|
71
|
+
req = create_request(@config)
|
72
|
+
res = create_response(@config)
|
73
73
|
server = self
|
74
74
|
begin
|
75
75
|
timeout = @config[:RequestTimeout]
|
@@ -224,6 +224,20 @@ module WEBrick
|
|
224
224
|
}
|
225
225
|
end
|
226
226
|
|
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
|
+
|
227
241
|
##
|
228
242
|
# Mount table for the path a servlet is mounted on in the directory space
|
229
243
|
# of the server. Users of WEBrick can only access this indirectly via
|
data/lib/webrick/httpservlet.rb
CHANGED
@@ -9,11 +9,11 @@
|
|
9
9
|
#
|
10
10
|
# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
require_relative 'httpservlet/abstract'
|
13
|
+
require_relative 'httpservlet/filehandler'
|
14
|
+
require_relative 'httpservlet/cgihandler'
|
15
|
+
require_relative 'httpservlet/erbhandler'
|
16
|
+
require_relative 'httpservlet/prochandler'
|
17
17
|
|
18
18
|
module WEBrick
|
19
19
|
module HTTPServlet
|
@@ -9,9 +9,9 @@
|
|
9
9
|
#
|
10
10
|
# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
require_relative '../htmlutils'
|
13
|
+
require_relative '../httputils'
|
14
|
+
require_relative '../httpstatus'
|
15
15
|
|
16
16
|
module WEBrick
|
17
17
|
module HTTPServlet
|
@@ -11,8 +11,8 @@
|
|
11
11
|
|
12
12
|
require 'rbconfig'
|
13
13
|
require 'tempfile'
|
14
|
-
|
15
|
-
|
14
|
+
require_relative '../config'
|
15
|
+
require_relative 'abstract'
|
16
16
|
|
17
17
|
module WEBrick
|
18
18
|
module HTTPServlet
|
@@ -28,6 +28,7 @@ module WEBrick
|
|
28
28
|
class CGIHandler < AbstractServlet
|
29
29
|
Ruby = RbConfig.ruby # :nodoc:
|
30
30
|
CGIRunner = "\"#{Ruby}\" \"#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb\"" # :nodoc:
|
31
|
+
CGIRunnerArray = [Ruby, "#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb".freeze].freeze # :nodoc:
|
31
32
|
|
32
33
|
##
|
33
34
|
# Creates a new CGI script servlet for the script at +name+
|
@@ -36,7 +37,12 @@ module WEBrick
|
|
36
37
|
super(server, name)
|
37
38
|
@script_filename = name
|
38
39
|
@tempdir = server[:TempDir]
|
39
|
-
|
40
|
+
interpreter = server[:CGIInterpreter]
|
41
|
+
if interpreter.is_a?(Array)
|
42
|
+
@cgicmd = CGIRunnerArray + interpreter
|
43
|
+
else
|
44
|
+
@cgicmd = "#{CGIRunner} #{interpreter}"
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
42
48
|
# :stopdoc:
|
@@ -65,9 +71,7 @@ module WEBrick
|
|
65
71
|
cgi_in.write("%8d" % dump.bytesize)
|
66
72
|
cgi_in.write(dump)
|
67
73
|
|
68
|
-
|
69
|
-
cgi_in.write(req.body)
|
70
|
-
end
|
74
|
+
req.body { |chunk| cgi_in.write(chunk) }
|
71
75
|
ensure
|
72
76
|
cgi_in.close
|
73
77
|
status = $?.exitstatus
|
@@ -11,9 +11,9 @@
|
|
11
11
|
|
12
12
|
require 'time'
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
require_relative '../htmlutils'
|
15
|
+
require_relative '../httputils'
|
16
|
+
require_relative '../httpstatus'
|
17
17
|
|
18
18
|
module WEBrick
|
19
19
|
module HTTPServlet
|
@@ -55,7 +55,7 @@ module WEBrick
|
|
55
55
|
else
|
56
56
|
mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])
|
57
57
|
res['content-type'] = mtype
|
58
|
-
res['content-length'] = st.size
|
58
|
+
res['content-length'] = st.size.to_s
|
59
59
|
res['last-modified'] = mtime.httpdate
|
60
60
|
res.body = File.open(@local_path, "rb")
|
61
61
|
end
|
@@ -86,6 +86,35 @@ module WEBrick
|
|
86
86
|
return false
|
87
87
|
end
|
88
88
|
|
89
|
+
# returns a lambda for webrick/httpresponse.rb send_body_proc
|
90
|
+
def multipart_body(body, parts, boundary, mtype, filesize)
|
91
|
+
lambda do |socket|
|
92
|
+
begin
|
93
|
+
begin
|
94
|
+
first = parts.shift
|
95
|
+
last = parts.shift
|
96
|
+
socket.write(
|
97
|
+
"--#{boundary}#{CRLF}" \
|
98
|
+
"Content-Type: #{mtype}#{CRLF}" \
|
99
|
+
"Content-Range: bytes #{first}-#{last}/#{filesize}#{CRLF}" \
|
100
|
+
"#{CRLF}"
|
101
|
+
)
|
102
|
+
|
103
|
+
begin
|
104
|
+
IO.copy_stream(body, socket, last - first + 1, first)
|
105
|
+
rescue NotImplementedError
|
106
|
+
body.seek(first, IO::SEEK_SET)
|
107
|
+
IO.copy_stream(body, socket, last - first + 1)
|
108
|
+
end
|
109
|
+
socket.write(CRLF)
|
110
|
+
end while parts[0]
|
111
|
+
socket.write("--#{boundary}--#{CRLF}")
|
112
|
+
ensure
|
113
|
+
body.close
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
89
118
|
def make_partial_content(req, res, filename, filesize)
|
90
119
|
mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])
|
91
120
|
unless ranges = HTTPUtils::parse_range_header(req['range'])
|
@@ -96,37 +125,27 @@ module WEBrick
|
|
96
125
|
if ranges.size > 1
|
97
126
|
time = Time.now
|
98
127
|
boundary = "#{time.sec}_#{time.usec}_#{Process::pid}"
|
99
|
-
|
100
|
-
ranges.each{|range|
|
101
|
-
|
102
|
-
next if
|
103
|
-
|
104
|
-
content = io.read(last-first+1)
|
105
|
-
body << "--" << boundary << CRLF
|
106
|
-
body << "Content-Type: #{mtype}" << CRLF
|
107
|
-
body << "Content-Range: bytes #{first}-#{last}/#{filesize}" << CRLF
|
108
|
-
body << CRLF
|
109
|
-
body << content
|
110
|
-
body << CRLF
|
128
|
+
parts = []
|
129
|
+
ranges.each {|range|
|
130
|
+
prange = prepare_range(range, filesize)
|
131
|
+
next if prange[0] < 0
|
132
|
+
parts.concat(prange)
|
111
133
|
}
|
112
|
-
raise HTTPStatus::RequestRangeNotSatisfiable if
|
113
|
-
body << "--" << boundary << "--" << CRLF
|
134
|
+
raise HTTPStatus::RequestRangeNotSatisfiable if parts.empty?
|
114
135
|
res["content-type"] = "multipart/byteranges; boundary=#{boundary}"
|
115
|
-
|
136
|
+
if req.http_version < '1.1'
|
137
|
+
res['connection'] = 'close'
|
138
|
+
else
|
139
|
+
res.chunked = true
|
140
|
+
end
|
141
|
+
res.body = multipart_body(io.dup, parts, boundary, mtype, filesize)
|
116
142
|
elsif range = ranges[0]
|
117
143
|
first, last = prepare_range(range, filesize)
|
118
144
|
raise HTTPStatus::RequestRangeNotSatisfiable if first < 0
|
119
|
-
if last == filesize - 1
|
120
|
-
content = io.dup
|
121
|
-
content.pos = first
|
122
|
-
else
|
123
|
-
io.pos = first
|
124
|
-
content = io.read(last-first+1)
|
125
|
-
end
|
126
145
|
res['content-type'] = mtype
|
127
146
|
res['content-range'] = "bytes #{first}-#{last}/#{filesize}"
|
128
|
-
res['content-length'] = last - first + 1
|
129
|
-
res.body =
|
147
|
+
res['content-length'] = (last - first + 1).to_s
|
148
|
+
res.body = io.dup
|
130
149
|
else
|
131
150
|
raise HTTPStatus::BadRequest
|
132
151
|
end
|
@@ -193,9 +212,18 @@ module WEBrick
|
|
193
212
|
|
194
213
|
# :stopdoc:
|
195
214
|
|
215
|
+
def set_filesystem_encoding(str)
|
216
|
+
enc = Encoding.find('filesystem')
|
217
|
+
if enc == Encoding::US_ASCII
|
218
|
+
str.b
|
219
|
+
else
|
220
|
+
str.dup.force_encoding(enc)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
196
224
|
def service(req, res)
|
197
225
|
# if this class is mounted on "/" and /~username is requested.
|
198
|
-
# we're going to override path
|
226
|
+
# we're going to override path information before invoking service.
|
199
227
|
if defined?(Etc) && @options[:UserDir] && req.script_name.empty?
|
200
228
|
if %r|^(/~([^/]+))| =~ req.path_info
|
201
229
|
script_name, user = $1, $2
|
@@ -279,7 +307,7 @@ module WEBrick
|
|
279
307
|
end
|
280
308
|
|
281
309
|
def exec_handler(req, res)
|
282
|
-
raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
|
310
|
+
raise HTTPStatus::NotFound, "`#{req.path}' not found." unless @root
|
283
311
|
if set_filename(req, res)
|
284
312
|
handler = get_handler(req, res)
|
285
313
|
call_callback(:HandlerCallback, req, res)
|
@@ -305,11 +333,12 @@ module WEBrick
|
|
305
333
|
end
|
306
334
|
|
307
335
|
def set_filename(req, res)
|
308
|
-
res.filename = @root
|
336
|
+
res.filename = @root
|
309
337
|
path_info = req.path_info.scan(%r|/[^/]*|)
|
310
338
|
|
311
339
|
path_info.unshift("") # dummy for checking @root dir
|
312
340
|
while base = path_info.first
|
341
|
+
base = set_filesystem_encoding(base)
|
313
342
|
break if base == "/"
|
314
343
|
break unless File.directory?(File.expand_path(res.filename + base))
|
315
344
|
shift_path_info(req, res, path_info)
|
@@ -317,6 +346,7 @@ module WEBrick
|
|
317
346
|
end
|
318
347
|
|
319
348
|
if base = path_info.first
|
349
|
+
base = set_filesystem_encoding(base)
|
320
350
|
if base == "/"
|
321
351
|
if file = search_index_file(req, res)
|
322
352
|
shift_path_info(req, res, path_info, file)
|
@@ -345,7 +375,7 @@ module WEBrick
|
|
345
375
|
|
346
376
|
def shift_path_info(req, res, path_info, base=nil)
|
347
377
|
tmp = path_info.shift
|
348
|
-
base = base || tmp
|
378
|
+
base = base || set_filesystem_encoding(tmp)
|
349
379
|
req.path_info = path_info.join
|
350
380
|
req.script_name << base
|
351
381
|
res.filename = File.expand_path(res.filename + base)
|
data/lib/webrick/httpstatus.rb
CHANGED
data/lib/webrick/httputils.rb
CHANGED
@@ -72,6 +72,7 @@ module WEBrick
|
|
72
72
|
"json" => "application/json",
|
73
73
|
"lha" => "application/octet-stream",
|
74
74
|
"lzh" => "application/octet-stream",
|
75
|
+
"mjs" => "application/javascript",
|
75
76
|
"mov" => "video/quicktime",
|
76
77
|
"mpe" => "video/mpeg",
|
77
78
|
"mpeg" => "video/mpeg",
|
@@ -95,6 +96,7 @@ module WEBrick
|
|
95
96
|
"tif" => "image/tiff",
|
96
97
|
"tiff" => "image/tiff",
|
97
98
|
"txt" => "text/plain",
|
99
|
+
"wasm" => "application/wasm",
|
98
100
|
"xbm" => "image/x-xbitmap",
|
99
101
|
"xhtml" => "text/html",
|
100
102
|
"xls" => "application/vnd.ms-excel",
|
@@ -161,10 +163,7 @@ module WEBrick
|
|
161
163
|
end
|
162
164
|
}
|
163
165
|
header.each{|key, values|
|
164
|
-
values.each
|
165
|
-
value.strip!
|
166
|
-
value.gsub!(/\s+/, " ")
|
167
|
-
}
|
166
|
+
values.each(&:strip!)
|
168
167
|
}
|
169
168
|
header
|
170
169
|
end
|
data/lib/webrick/server.rb
CHANGED
@@ -10,8 +10,8 @@
|
|
10
10
|
# $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $
|
11
11
|
|
12
12
|
require 'socket'
|
13
|
-
|
14
|
-
|
13
|
+
require_relative 'config'
|
14
|
+
require_relative 'log'
|
15
15
|
|
16
16
|
module WEBrick
|
17
17
|
|
@@ -102,6 +102,9 @@ module WEBrick
|
|
102
102
|
@listeners = []
|
103
103
|
@shutdown_pipe = nil
|
104
104
|
unless @config[:DoNotListen]
|
105
|
+
raise ArgumentError, "Port must an integer" unless @config[:Port].to_s == @config[:Port].to_i.to_s
|
106
|
+
|
107
|
+
@config[:Port] = @config[:Port].to_i
|
105
108
|
if @config[:Listen]
|
106
109
|
warn(":Listen option is deprecated; use GenericServer#listen", uplevel: 1)
|
107
110
|
end
|
data/lib/webrick/ssl.rb
CHANGED
@@ -122,7 +122,7 @@ module WEBrick
|
|
122
122
|
ef.issuer_certificate = cert
|
123
123
|
cert.extensions = [
|
124
124
|
ef.create_extension("basicConstraints","CA:FALSE"),
|
125
|
-
ef.create_extension("keyUsage", "keyEncipherment"),
|
125
|
+
ef.create_extension("keyUsage", "keyEncipherment, digitalSignature, keyAgreement, dataEncipherment"),
|
126
126
|
ef.create_extension("subjectKeyIdentifier", "hash"),
|
127
127
|
ef.create_extension("extendedKeyUsage", "serverAuth"),
|
128
128
|
ef.create_extension("nsComment", comment),
|
@@ -130,7 +130,7 @@ module WEBrick
|
|
130
130
|
aki = ef.create_extension("authorityKeyIdentifier",
|
131
131
|
"keyid:always,issuer:always")
|
132
132
|
cert.add_extension(aki)
|
133
|
-
cert.sign(rsa,
|
133
|
+
cert.sign(rsa, "SHA256")
|
134
134
|
|
135
135
|
return [ cert, rsa ]
|
136
136
|
end
|
@@ -181,7 +181,7 @@ module WEBrick
|
|
181
181
|
unless config[:SSLCertificate]
|
182
182
|
cn = config[:SSLCertName]
|
183
183
|
comment = config[:SSLCertComment]
|
184
|
-
cert, key = Utils::create_self_signed_cert(
|
184
|
+
cert, key = Utils::create_self_signed_cert(2048, cn, comment)
|
185
185
|
config[:SSLCertificate] = cert
|
186
186
|
config[:SSLPrivateKey] = key
|
187
187
|
end
|
data/lib/webrick/utils.rb
CHANGED
data/lib/webrick/version.rb
CHANGED
data/webrick.gemspec
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
begin
|
3
|
+
require_relative 'lib/webrick/version'
|
4
|
+
rescue LoadError
|
5
|
+
# for Ruby core repository
|
6
|
+
require_relative 'version'
|
7
|
+
end
|
8
|
+
|
9
|
+
Gem::Specification.new do |s|
|
10
|
+
s.name = "webrick"
|
11
|
+
s.version = WEBrick::VERSION
|
12
|
+
s.summary = "HTTP server toolkit"
|
13
|
+
s.description = "WEBrick is an HTTP server toolkit that can be configured as an HTTPS server, a proxy server, and a virtual-host server."
|
14
|
+
|
15
|
+
s.require_path = %w{lib}
|
16
|
+
s.files = [
|
17
|
+
"Gemfile",
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.md",
|
20
|
+
"Rakefile",
|
21
|
+
"bin/console",
|
22
|
+
"bin/setup",
|
23
|
+
"lib/webrick.rb",
|
24
|
+
"lib/webrick/accesslog.rb",
|
25
|
+
"lib/webrick/cgi.rb",
|
26
|
+
"lib/webrick/compat.rb",
|
27
|
+
"lib/webrick/config.rb",
|
28
|
+
"lib/webrick/cookie.rb",
|
29
|
+
"lib/webrick/htmlutils.rb",
|
30
|
+
"lib/webrick/httpauth.rb",
|
31
|
+
"lib/webrick/httpauth/authenticator.rb",
|
32
|
+
"lib/webrick/httpauth/basicauth.rb",
|
33
|
+
"lib/webrick/httpauth/digestauth.rb",
|
34
|
+
"lib/webrick/httpauth/htdigest.rb",
|
35
|
+
"lib/webrick/httpauth/htgroup.rb",
|
36
|
+
"lib/webrick/httpauth/htpasswd.rb",
|
37
|
+
"lib/webrick/httpauth/userdb.rb",
|
38
|
+
"lib/webrick/httpproxy.rb",
|
39
|
+
"lib/webrick/httprequest.rb",
|
40
|
+
"lib/webrick/httpresponse.rb",
|
41
|
+
"lib/webrick/https.rb",
|
42
|
+
"lib/webrick/httpserver.rb",
|
43
|
+
"lib/webrick/httpservlet.rb",
|
44
|
+
"lib/webrick/httpservlet/abstract.rb",
|
45
|
+
"lib/webrick/httpservlet/cgi_runner.rb",
|
46
|
+
"lib/webrick/httpservlet/cgihandler.rb",
|
47
|
+
"lib/webrick/httpservlet/erbhandler.rb",
|
48
|
+
"lib/webrick/httpservlet/filehandler.rb",
|
49
|
+
"lib/webrick/httpservlet/prochandler.rb",
|
50
|
+
"lib/webrick/httpstatus.rb",
|
51
|
+
"lib/webrick/httputils.rb",
|
52
|
+
"lib/webrick/httpversion.rb",
|
53
|
+
"lib/webrick/log.rb",
|
54
|
+
"lib/webrick/server.rb",
|
55
|
+
"lib/webrick/ssl.rb",
|
56
|
+
"lib/webrick/utils.rb",
|
57
|
+
"lib/webrick/version.rb",
|
58
|
+
"webrick.gemspec",
|
59
|
+
]
|
60
|
+
s.required_ruby_version = ">= 2.3.0"
|
61
|
+
|
62
|
+
s.authors = ["TAKAHASHI Masayoshi", "GOTOU YUUZOU", "Eric Wong"]
|
63
|
+
s.email = [nil, nil, 'normal@ruby-lang.org']
|
64
|
+
s.homepage = "https://github.com/ruby/webrick"
|
65
|
+
s.licenses = ["Ruby", "BSD-2-Clause"]
|
66
|
+
|
67
|
+
if s.respond_to?(:metadata=)
|
68
|
+
s.metadata = {
|
69
|
+
"bug_tracker_uri" => "https://github.com/ruby/webrick/issues",
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
s.add_development_dependency "rake"
|
74
|
+
end
|