webrick 1.4.2 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|