webrick 1.4.0.beta1 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of webrick might be problematic. Click here for more details.
- checksums.yaml +5 -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/basicauth.rb +13 -5
- data/lib/webrick/httpauth/digestauth.rb +10 -23
- data/lib/webrick/httpauth/htdigest.rb +4 -4
- data/lib/webrick/httpauth/htgroup.rb +9 -6
- data/lib/webrick/httpauth/htpasswd.rb +39 -6
- data/lib/webrick/httpproxy.rb +48 -36
- data/lib/webrick/httprequest.rb +53 -14
- data/lib/webrick/httpresponse.rb +97 -49
- data/lib/webrick/https.rb +66 -1
- data/lib/webrick/httpserver.rb +25 -11
- data/lib/webrick/httpservlet.rb +5 -5
- data/lib/webrick/httpservlet/abstract.rb +3 -5
- data/lib/webrick/httpservlet/cgi_runner.rb +2 -2
- data/lib/webrick/httpservlet/cgihandler.rb +3 -5
- data/lib/webrick/httpservlet/erbhandler.rb +2 -2
- data/lib/webrick/httpservlet/filehandler.rb +49 -31
- data/lib/webrick/httpservlet/prochandler.rb +1 -1
- data/lib/webrick/httpstatus.rb +1 -5
- data/lib/webrick/httputils.rb +3 -0
- data/lib/webrick/log.rb +3 -3
- data/lib/webrick/server.rb +34 -17
- data/lib/webrick/ssl.rb +20 -7
- data/lib/webrick/utils.rb +1 -2
- data/lib/webrick/version.rb +1 -1
- metadata +17 -13
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,11 +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
|
-
|
15
|
-
require 'webrick/httputils'
|
16
|
-
require 'webrick/httpstatus'
|
12
|
+
require_relative '../htmlutils'
|
13
|
+
require_relative '../httputils'
|
14
|
+
require_relative '../httpstatus'
|
17
15
|
|
18
16
|
module WEBrick
|
19
17
|
module HTTPServlet
|
@@ -23,11 +23,11 @@ STDIN.binmode
|
|
23
23
|
|
24
24
|
len = sysread(STDIN, 8).to_i
|
25
25
|
out = sysread(STDIN, len)
|
26
|
-
STDOUT.reopen(open(out, "w"))
|
26
|
+
STDOUT.reopen(File.open(out, "w"))
|
27
27
|
|
28
28
|
len = sysread(STDIN, 8).to_i
|
29
29
|
err = sysread(STDIN, len)
|
30
|
-
STDERR.reopen(open(err, "w"))
|
30
|
+
STDERR.reopen(File.open(err, "w"))
|
31
31
|
|
32
32
|
len = sysread(STDIN, 8).to_i
|
33
33
|
dump = sysread(STDIN, len)
|
@@ -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
|
@@ -65,9 +65,7 @@ module WEBrick
|
|
65
65
|
cgi_in.write("%8d" % dump.bytesize)
|
66
66
|
cgi_in.write(dump)
|
67
67
|
|
68
|
-
|
69
|
-
cgi_in.write(req.body)
|
70
|
-
end
|
68
|
+
req.body { |chunk| cgi_in.write(chunk) }
|
71
69
|
ensure
|
72
70
|
cgi_in.close
|
73
71
|
status = $?.exitstatus
|
@@ -9,7 +9,7 @@
|
|
9
9
|
#
|
10
10
|
# $IPR: erbhandler.rb,v 1.25 2003/02/24 19:25:31 gotoyuzo Exp $
|
11
11
|
|
12
|
-
|
12
|
+
require_relative 'abstract'
|
13
13
|
|
14
14
|
require 'erb'
|
15
15
|
|
@@ -53,7 +53,7 @@ module WEBrick
|
|
53
53
|
raise HTTPStatus::Forbidden, "ERBHandler cannot work."
|
54
54
|
end
|
55
55
|
begin
|
56
|
-
data = open(@script_filename
|
56
|
+
data = File.open(@script_filename, &:read)
|
57
57
|
res.body = evaluate(ERB.new(data), req, res)
|
58
58
|
res['content-type'] ||=
|
59
59
|
HTTPUtils::mime_type(@script_filename, @config[:MimeTypes])
|
@@ -9,12 +9,11 @@
|
|
9
9
|
#
|
10
10
|
# $IPR: filehandler.rb,v 1.44 2003/06/07 01:34:51 gotoyuzo Exp $
|
11
11
|
|
12
|
-
require 'thread'
|
13
12
|
require 'time'
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
require_relative '../htmlutils'
|
15
|
+
require_relative '../httputils'
|
16
|
+
require_relative '../httpstatus'
|
18
17
|
|
19
18
|
module WEBrick
|
20
19
|
module HTTPServlet
|
@@ -56,9 +55,9 @@ module WEBrick
|
|
56
55
|
else
|
57
56
|
mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])
|
58
57
|
res['content-type'] = mtype
|
59
|
-
res['content-length'] = st.size
|
58
|
+
res['content-length'] = st.size.to_s
|
60
59
|
res['last-modified'] = mtime.httpdate
|
61
|
-
res.body = open(@local_path, "rb")
|
60
|
+
res.body = File.open(@local_path, "rb")
|
62
61
|
end
|
63
62
|
end
|
64
63
|
|
@@ -87,47 +86,66 @@ module WEBrick
|
|
87
86
|
return false
|
88
87
|
end
|
89
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
|
+
|
90
118
|
def make_partial_content(req, res, filename, filesize)
|
91
119
|
mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])
|
92
120
|
unless ranges = HTTPUtils::parse_range_header(req['range'])
|
93
121
|
raise HTTPStatus::BadRequest,
|
94
122
|
"Unrecognized range-spec: \"#{req['range']}\""
|
95
123
|
end
|
96
|
-
open(filename, "rb"){|io|
|
124
|
+
File.open(filename, "rb"){|io|
|
97
125
|
if ranges.size > 1
|
98
126
|
time = Time.now
|
99
127
|
boundary = "#{time.sec}_#{time.usec}_#{Process::pid}"
|
100
|
-
|
101
|
-
ranges.each{|range|
|
102
|
-
|
103
|
-
next if
|
104
|
-
|
105
|
-
content = io.read(last-first+1)
|
106
|
-
body << "--" << boundary << CRLF
|
107
|
-
body << "Content-Type: #{mtype}" << CRLF
|
108
|
-
body << "Content-Range: bytes #{first}-#{last}/#{filesize}" << CRLF
|
109
|
-
body << CRLF
|
110
|
-
body << content
|
111
|
-
body << CRLF
|
128
|
+
parts = []
|
129
|
+
ranges.each {|range|
|
130
|
+
prange = prepare_range(range, filesize)
|
131
|
+
next if prange[0] < 0
|
132
|
+
parts.concat(prange)
|
112
133
|
}
|
113
|
-
raise HTTPStatus::RequestRangeNotSatisfiable if
|
114
|
-
body << "--" << boundary << "--" << CRLF
|
134
|
+
raise HTTPStatus::RequestRangeNotSatisfiable if parts.empty?
|
115
135
|
res["content-type"] = "multipart/byteranges; boundary=#{boundary}"
|
116
|
-
|
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)
|
117
142
|
elsif range = ranges[0]
|
118
143
|
first, last = prepare_range(range, filesize)
|
119
144
|
raise HTTPStatus::RequestRangeNotSatisfiable if first < 0
|
120
|
-
if last == filesize - 1
|
121
|
-
content = io.dup
|
122
|
-
content.pos = first
|
123
|
-
else
|
124
|
-
io.pos = first
|
125
|
-
content = io.read(last-first+1)
|
126
|
-
end
|
127
145
|
res['content-type'] = mtype
|
128
146
|
res['content-range'] = "bytes #{first}-#{last}/#{filesize}"
|
129
|
-
res['content-length'] = last - first + 1
|
130
|
-
res.body =
|
147
|
+
res['content-length'] = (last - first + 1).to_s
|
148
|
+
res.body = io.dup
|
131
149
|
else
|
132
150
|
raise HTTPStatus::BadRequest
|
133
151
|
end
|
data/lib/webrick/httpstatus.rb
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
#
|
10
10
|
# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $
|
11
11
|
|
12
|
-
|
12
|
+
require_relative 'accesslog'
|
13
13
|
|
14
14
|
module WEBrick
|
15
15
|
|
@@ -23,10 +23,6 @@ module WEBrick
|
|
23
23
|
##
|
24
24
|
# Root of the HTTP status class hierarchy
|
25
25
|
class Status < StandardError
|
26
|
-
def initialize(*args) # :nodoc:
|
27
|
-
args[0] = AccessLog.escape(args[0]) unless args.empty?
|
28
|
-
super(*args)
|
29
|
-
end
|
30
26
|
class << self
|
31
27
|
attr_reader :code, :reason_phrase # :nodoc:
|
32
28
|
end
|
data/lib/webrick/httputils.rb
CHANGED
@@ -69,6 +69,7 @@ module WEBrick
|
|
69
69
|
"jpeg" => "image/jpeg",
|
70
70
|
"jpg" => "image/jpeg",
|
71
71
|
"js" => "application/javascript",
|
72
|
+
"json" => "application/json",
|
72
73
|
"lha" => "application/octet-stream",
|
73
74
|
"lzh" => "application/octet-stream",
|
74
75
|
"mov" => "video/quicktime",
|
@@ -107,6 +108,8 @@ module WEBrick
|
|
107
108
|
# Loads Apache-compatible mime.types in +file+.
|
108
109
|
|
109
110
|
def load_mime_types(file)
|
111
|
+
# note: +file+ may be a "| command" for now; some people may
|
112
|
+
# rely on this, but currently we do not use this method by default.
|
110
113
|
open(file){ |io|
|
111
114
|
hash = Hash.new
|
112
115
|
io.each{ |line|
|
data/lib/webrick/log.rb
CHANGED
@@ -51,7 +51,7 @@ module WEBrick
|
|
51
51
|
@level = level || INFO
|
52
52
|
case log_file
|
53
53
|
when String
|
54
|
-
@log = open(log_file, "a+")
|
54
|
+
@log = File.open(log_file, "a+")
|
55
55
|
@log.sync = true
|
56
56
|
@opened = true
|
57
57
|
when NilClass
|
@@ -118,10 +118,10 @@ module WEBrick
|
|
118
118
|
# * Otherwise it will return +arg+.inspect.
|
119
119
|
def format(arg)
|
120
120
|
if arg.is_a?(Exception)
|
121
|
-
"#{arg.class}: #{arg.message}\n\t" <<
|
121
|
+
"#{arg.class}: #{AccessLog.escape(arg.message)}\n\t" <<
|
122
122
|
arg.backtrace.join("\n\t") << "\n"
|
123
123
|
elsif arg.respond_to?(:to_str)
|
124
|
-
arg.to_str
|
124
|
+
AccessLog.escape(arg.to_str)
|
125
125
|
else
|
126
126
|
arg.inspect
|
127
127
|
end
|
data/lib/webrick/server.rb
CHANGED
@@ -9,10 +9,9 @@
|
|
9
9
|
#
|
10
10
|
# $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $
|
11
11
|
|
12
|
-
require 'thread'
|
13
12
|
require 'socket'
|
14
|
-
|
15
|
-
|
13
|
+
require_relative 'config'
|
14
|
+
require_relative 'log'
|
16
15
|
|
17
16
|
module WEBrick
|
18
17
|
|
@@ -104,7 +103,7 @@ module WEBrick
|
|
104
103
|
@shutdown_pipe = nil
|
105
104
|
unless @config[:DoNotListen]
|
106
105
|
if @config[:Listen]
|
107
|
-
warn(":Listen option is deprecated; use GenericServer#listen")
|
106
|
+
warn(":Listen option is deprecated; use GenericServer#listen", uplevel: 1)
|
108
107
|
end
|
109
108
|
listen(@config[:BindAddress], @config[:Port])
|
110
109
|
if @config[:Port] == 0
|
@@ -158,17 +157,17 @@ module WEBrick
|
|
158
157
|
server_type.start{
|
159
158
|
@logger.info \
|
160
159
|
"#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
|
160
|
+
@status = :Running
|
161
161
|
call_callback(:StartCallback)
|
162
162
|
|
163
163
|
shutdown_pipe = @shutdown_pipe
|
164
164
|
|
165
165
|
thgroup = ThreadGroup.new
|
166
|
-
@status = :Running
|
167
166
|
begin
|
168
167
|
while @status == :Running
|
169
168
|
begin
|
170
169
|
sp = shutdown_pipe[0]
|
171
|
-
if svrs = IO.select([sp, *@listeners]
|
170
|
+
if svrs = IO.select([sp, *@listeners])
|
172
171
|
if svrs[0].include? sp
|
173
172
|
# swallow shutdown pipe
|
174
173
|
buf = String.new
|
@@ -252,18 +251,26 @@ module WEBrick
|
|
252
251
|
# the client socket.
|
253
252
|
|
254
253
|
def accept_client(svr)
|
255
|
-
sock =
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
254
|
+
case sock = svr.to_io.accept_nonblock(exception: false)
|
255
|
+
when :wait_readable
|
256
|
+
nil
|
257
|
+
else
|
258
|
+
if svr.respond_to?(:start_immediately)
|
259
|
+
sock = OpenSSL::SSL::SSLSocket.new(sock, ssl_context)
|
260
|
+
sock.sync_close = true
|
261
|
+
# we cannot do OpenSSL::SSL::SSLSocket#accept here because
|
262
|
+
# a slow client can prevent us from accepting connections
|
263
|
+
# from other clients
|
264
|
+
end
|
265
|
+
sock
|
265
266
|
end
|
266
|
-
|
267
|
+
rescue Errno::ECONNRESET, Errno::ECONNABORTED,
|
268
|
+
Errno::EPROTO, Errno::EINVAL
|
269
|
+
nil
|
270
|
+
rescue StandardError => ex
|
271
|
+
msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
|
272
|
+
@logger.error msg
|
273
|
+
nil
|
267
274
|
end
|
268
275
|
|
269
276
|
##
|
@@ -286,6 +293,16 @@ module WEBrick
|
|
286
293
|
@logger.debug "accept: <address unknown>"
|
287
294
|
raise
|
288
295
|
end
|
296
|
+
if sock.respond_to?(:sync_close=) && @config[:SSLStartImmediately]
|
297
|
+
WEBrick::Utils.timeout(@config[:RequestTimeout]) do
|
298
|
+
begin
|
299
|
+
sock.accept # OpenSSL::SSL::SSLSocket#accept
|
300
|
+
rescue Errno::ECONNRESET, Errno::ECONNABORTED,
|
301
|
+
Errno::EPROTO, Errno::EINVAL
|
302
|
+
Thread.exit
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
289
306
|
call_callback(:AcceptCallback, sock)
|
290
307
|
block ? block.call(sock) : run(sock)
|
291
308
|
rescue Errno::ENOTCONN
|
data/lib/webrick/ssl.rb
CHANGED
@@ -48,6 +48,8 @@ module WEBrick
|
|
48
48
|
# Number of CA certificates to walk when verifying a certificate chain
|
49
49
|
# :SSLVerifyCallback ::
|
50
50
|
# Custom certificate verification callback
|
51
|
+
# :SSLServerNameCallback::
|
52
|
+
# Custom servername indication callback
|
51
53
|
# :SSLTimeout ::
|
52
54
|
# Maximum session lifetime
|
53
55
|
# :SSLOptions ::
|
@@ -128,7 +130,7 @@ module WEBrick
|
|
128
130
|
aki = ef.create_extension("authorityKeyIdentifier",
|
129
131
|
"keyid:always,issuer:always")
|
130
132
|
cert.add_extension(aki)
|
131
|
-
cert.sign(rsa, OpenSSL::Digest::
|
133
|
+
cert.sign(rsa, OpenSSL::Digest::SHA256.new)
|
132
134
|
|
133
135
|
return [ cert, rsa ]
|
134
136
|
end
|
@@ -145,7 +147,13 @@ module WEBrick
|
|
145
147
|
# SSL context for the server when run in SSL mode
|
146
148
|
|
147
149
|
def ssl_context # :nodoc:
|
148
|
-
@ssl_context ||=
|
150
|
+
@ssl_context ||= begin
|
151
|
+
if @config[:SSLEnable]
|
152
|
+
ssl_context = setup_ssl_context(@config)
|
153
|
+
@logger.info("\n" + @config[:SSLCertificate].to_text)
|
154
|
+
ssl_context
|
155
|
+
end
|
156
|
+
end
|
149
157
|
end
|
150
158
|
|
151
159
|
undef listen
|
@@ -156,10 +164,6 @@ module WEBrick
|
|
156
164
|
def listen(address, port) # :nodoc:
|
157
165
|
listeners = Utils::create_listeners(address, port)
|
158
166
|
if @config[:SSLEnable]
|
159
|
-
unless ssl_context
|
160
|
-
@ssl_context = setup_ssl_context(@config)
|
161
|
-
@logger.info("\n" + @config[:SSLCertificate].to_text)
|
162
|
-
end
|
163
167
|
listeners.collect!{|svr|
|
164
168
|
ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context)
|
165
169
|
ssvr.start_immediately = @config[:SSLStartImmediately]
|
@@ -177,7 +181,7 @@ module WEBrick
|
|
177
181
|
unless config[:SSLCertificate]
|
178
182
|
cn = config[:SSLCertName]
|
179
183
|
comment = config[:SSLCertComment]
|
180
|
-
cert, key = Utils::create_self_signed_cert(
|
184
|
+
cert, key = Utils::create_self_signed_cert(2048, cn, comment)
|
181
185
|
config[:SSLCertificate] = cert
|
182
186
|
config[:SSLPrivateKey] = key
|
183
187
|
end
|
@@ -193,10 +197,19 @@ module WEBrick
|
|
193
197
|
ctx.verify_mode = config[:SSLVerifyClient]
|
194
198
|
ctx.verify_depth = config[:SSLVerifyDepth]
|
195
199
|
ctx.verify_callback = config[:SSLVerifyCallback]
|
200
|
+
ctx.servername_cb = config[:SSLServerNameCallback] || proc { |args| ssl_servername_callback(*args) }
|
196
201
|
ctx.timeout = config[:SSLTimeout]
|
197
202
|
ctx.options = config[:SSLOptions]
|
198
203
|
ctx.ciphers = config[:SSLCiphers]
|
199
204
|
ctx
|
200
205
|
end
|
206
|
+
|
207
|
+
##
|
208
|
+
# ServerNameIndication callback
|
209
|
+
|
210
|
+
def ssl_servername_callback(sslsocket, hostname = nil)
|
211
|
+
# default
|
212
|
+
end
|
213
|
+
|
201
214
|
end
|
202
215
|
end
|
data/lib/webrick/utils.rb
CHANGED
@@ -37,7 +37,7 @@ module WEBrick
|
|
37
37
|
Process::Sys::setgid(pw.gid)
|
38
38
|
Process::Sys::setuid(pw.uid)
|
39
39
|
else
|
40
|
-
warn("WEBrick::Utils::su doesn't work on this platform")
|
40
|
+
warn("WEBrick::Utils::su doesn't work on this platform", uplevel: 1)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
module_function :su
|
@@ -91,7 +91,6 @@ module WEBrick
|
|
91
91
|
|
92
92
|
###########
|
93
93
|
|
94
|
-
require "thread"
|
95
94
|
require "timeout"
|
96
95
|
require "singleton"
|
97
96
|
|