rubysl-webrick 1.0.0 → 2.0.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.
- checksums.yaml +14 -6
- data/.travis.yml +5 -6
- data/lib/rubysl/webrick/version.rb +1 -1
- data/lib/rubysl/webrick/webrick.rb +199 -2
- data/lib/webrick/accesslog.rb +96 -5
- data/lib/webrick/cgi.rb +80 -29
- data/lib/webrick/compat.rb +20 -0
- data/lib/webrick/config.rb +59 -5
- data/lib/webrick/cookie.rb +66 -5
- data/lib/webrick/htmlutils.rb +4 -1
- data/lib/webrick/httpauth.rb +53 -3
- data/lib/webrick/httpauth/authenticator.rb +53 -16
- data/lib/webrick/httpauth/basicauth.rb +45 -2
- data/lib/webrick/httpauth/digestauth.rb +82 -17
- data/lib/webrick/httpauth/htdigest.rb +38 -1
- data/lib/webrick/httpauth/htgroup.rb +32 -0
- data/lib/webrick/httpauth/htpasswd.rb +40 -2
- data/lib/webrick/httpauth/userdb.rb +27 -4
- data/lib/webrick/httpproxy.rb +197 -112
- data/lib/webrick/httprequest.rb +268 -50
- data/lib/webrick/httpresponse.rb +170 -33
- data/lib/webrick/https.rb +26 -3
- data/lib/webrick/httpserver.rb +75 -7
- data/lib/webrick/httpservlet/abstract.rb +88 -6
- data/lib/webrick/httpservlet/cgi_runner.rb +5 -4
- data/lib/webrick/httpservlet/cgihandler.rb +37 -18
- data/lib/webrick/httpservlet/erbhandler.rb +40 -7
- data/lib/webrick/httpservlet/filehandler.rb +116 -28
- data/lib/webrick/httpservlet/prochandler.rb +17 -4
- data/lib/webrick/httpstatus.rb +86 -18
- data/lib/webrick/httputils.rb +131 -23
- data/lib/webrick/httpversion.rb +28 -2
- data/lib/webrick/log.rb +72 -5
- data/lib/webrick/server.rb +158 -33
- data/lib/webrick/ssl.rb +78 -9
- data/lib/webrick/utils.rb +151 -5
- data/lib/webrick/version.rb +5 -1
- data/rubysl-webrick.gemspec +0 -1
- metadata +12 -24
data/lib/webrick/ssl.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
# ssl.rb -- SSL/TLS enhancement for GenericServer
|
3
3
|
#
|
4
4
|
# Copyright (c) 2003 GOTOU Yuuzou All rights reserved.
|
5
|
-
#
|
6
|
-
# $Id
|
5
|
+
#
|
6
|
+
# $Id$
|
7
7
|
|
8
8
|
require 'webrick'
|
9
9
|
require 'openssl'
|
@@ -12,6 +12,53 @@ module WEBrick
|
|
12
12
|
module Config
|
13
13
|
svrsoft = General[:ServerSoftware]
|
14
14
|
osslv = ::OpenSSL::OPENSSL_VERSION.split[1]
|
15
|
+
|
16
|
+
##
|
17
|
+
# Default SSL server configuration.
|
18
|
+
#
|
19
|
+
# WEBrick can automatically create a self-signed certificate if
|
20
|
+
# <code>:SSLCertName</code> is set. For more information on the various
|
21
|
+
# SSL options see OpenSSL::SSL::SSLContext.
|
22
|
+
#
|
23
|
+
# :ServerSoftware ::
|
24
|
+
# The server software name used in the Server: header.
|
25
|
+
# :SSLEnable :: false,
|
26
|
+
# Enable SSL for this server. Defaults to false.
|
27
|
+
# :SSLCertificate ::
|
28
|
+
# The SSL certificate for the server.
|
29
|
+
# :SSLPrivateKey ::
|
30
|
+
# The SSL private key for the server certificate.
|
31
|
+
# :SSLClientCA :: nil,
|
32
|
+
# Array of certificates that will be sent to the client.
|
33
|
+
# :SSLExtraChainCert :: nil,
|
34
|
+
# Array of certificates that willbe added to the certificate chain
|
35
|
+
# :SSLCACertificateFile :: nil,
|
36
|
+
# Path to a CA certificate file
|
37
|
+
# :SSLCACertificatePath :: nil,
|
38
|
+
# Path to a directory containing CA certificates
|
39
|
+
# :SSLCertificateStore :: nil,
|
40
|
+
# OpenSSL::X509::Store used for certificate validation of the client
|
41
|
+
# :SSLTmpDhCallback :: nil,
|
42
|
+
# Callback invoked when DH parameters are required.
|
43
|
+
# :SSLVerifyClient ::
|
44
|
+
# Sets whether the client is verified. This defaults to VERIFY_NONE
|
45
|
+
# which is typical for an HTTPS server.
|
46
|
+
# :SSLVerifyDepth ::
|
47
|
+
# Number of CA certificates to walk when verifying a certificate chain
|
48
|
+
# :SSLVerifyCallback ::
|
49
|
+
# Custom certificate verification callback
|
50
|
+
# :SSLTimeout ::
|
51
|
+
# Maximum session lifetime
|
52
|
+
# :SSLOptions ::
|
53
|
+
# Various SSL options
|
54
|
+
# :SSLStartImmediately ::
|
55
|
+
# Immediately start SSL upon connection? Defaults to true
|
56
|
+
# :SSLCertName ::
|
57
|
+
# SSL certificate name. Must be set to enable automatic certificate
|
58
|
+
# creation.
|
59
|
+
# :SSLCertComment ::
|
60
|
+
# Comment used during automatic certificate creation.
|
61
|
+
|
15
62
|
SSL = {
|
16
63
|
:ServerSoftware => "#{svrsoft} OpenSSL/#{osslv}",
|
17
64
|
:SSLEnable => false,
|
@@ -22,6 +69,7 @@ module WEBrick
|
|
22
69
|
:SSLCACertificateFile => nil,
|
23
70
|
:SSLCACertificatePath => nil,
|
24
71
|
:SSLCertificateStore => nil,
|
72
|
+
:SSLTmpDhCallback => nil,
|
25
73
|
:SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
|
26
74
|
:SSLVerifyDepth => nil,
|
27
75
|
:SSLVerifyCallback => nil, # custom verification
|
@@ -36,12 +84,16 @@ module WEBrick
|
|
36
84
|
end
|
37
85
|
|
38
86
|
module Utils
|
87
|
+
##
|
88
|
+
# Creates a self-signed certificate with the given number of +bits+,
|
89
|
+
# the issuer +cn+ and a +comment+ to be stored in the certificate.
|
90
|
+
|
39
91
|
def create_self_signed_cert(bits, cn, comment)
|
40
92
|
rsa = OpenSSL::PKey::RSA.new(bits){|p, n|
|
41
93
|
case p
|
42
94
|
when 0; $stderr.putc "." # BN_generate_prime
|
43
95
|
when 1; $stderr.putc "+" # BN_generate_prime
|
44
|
-
when 2; $stderr.putc "*" # searching good prime,
|
96
|
+
when 2; $stderr.putc "*" # searching good prime,
|
45
97
|
# n = #of try,
|
46
98
|
# but also data from BN_generate_prime
|
47
99
|
when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
|
@@ -50,8 +102,8 @@ module WEBrick
|
|
50
102
|
end
|
51
103
|
}
|
52
104
|
cert = OpenSSL::X509::Certificate.new
|
53
|
-
cert.version =
|
54
|
-
cert.serial =
|
105
|
+
cert.version = 2
|
106
|
+
cert.serial = 1
|
55
107
|
name = OpenSSL::X509::Name.new(cn)
|
56
108
|
cert.subject = name
|
57
109
|
cert.issuer = name
|
@@ -78,17 +130,30 @@ module WEBrick
|
|
78
130
|
module_function :create_self_signed_cert
|
79
131
|
end
|
80
132
|
|
133
|
+
##
|
134
|
+
#--
|
135
|
+
# Updates WEBrick::GenericServer with SSL functionality
|
136
|
+
|
81
137
|
class GenericServer
|
82
|
-
|
138
|
+
|
139
|
+
##
|
140
|
+
# SSL context for the server when run in SSL mode
|
141
|
+
|
142
|
+
def ssl_context # :nodoc:
|
83
143
|
@ssl_context ||= nil
|
84
144
|
end
|
85
145
|
|
86
|
-
|
146
|
+
undef listen
|
147
|
+
|
148
|
+
##
|
149
|
+
# Updates +listen+ to enable SSL when the SSL configuration is active.
|
150
|
+
|
151
|
+
def listen(address, port) # :nodoc:
|
87
152
|
listeners = Utils::create_listeners(address, port, @logger)
|
88
153
|
if @config[:SSLEnable]
|
89
154
|
unless ssl_context
|
90
155
|
@ssl_context = setup_ssl_context(@config)
|
91
|
-
@logger.info("\n" + @config[:SSLCertificate].to_text)
|
156
|
+
@logger.info("\n" + @config[:SSLCertificate].to_text)
|
92
157
|
end
|
93
158
|
listeners.collect!{|svr|
|
94
159
|
ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context)
|
@@ -99,7 +164,10 @@ module WEBrick
|
|
99
164
|
@listeners += listeners
|
100
165
|
end
|
101
166
|
|
102
|
-
|
167
|
+
##
|
168
|
+
# Sets up an SSL context for +config+
|
169
|
+
|
170
|
+
def setup_ssl_context(config) # :nodoc:
|
103
171
|
unless config[:SSLCertificate]
|
104
172
|
cn = config[:SSLCertName]
|
105
173
|
comment = config[:SSLCertComment]
|
@@ -115,6 +183,7 @@ module WEBrick
|
|
115
183
|
ctx.ca_file = config[:SSLCACertificateFile]
|
116
184
|
ctx.ca_path = config[:SSLCACertificatePath]
|
117
185
|
ctx.cert_store = config[:SSLCertificateStore]
|
186
|
+
ctx.tmp_dh_callback = config[:SSLTmpDhCallback]
|
118
187
|
ctx.verify_mode = config[:SSLVerifyClient]
|
119
188
|
ctx.verify_depth = config[:SSLVerifyDepth]
|
120
189
|
ctx.verify_callback = config[:SSLVerifyCallback]
|
data/lib/webrick/utils.rb
CHANGED
@@ -18,6 +18,8 @@ end
|
|
18
18
|
|
19
19
|
module WEBrick
|
20
20
|
module Utils
|
21
|
+
##
|
22
|
+
# Sets IO operations on +io+ to be non-blocking
|
21
23
|
def set_non_blocking(io)
|
22
24
|
flag = File::NONBLOCK
|
23
25
|
if defined?(Fcntl::F_GETFL)
|
@@ -27,13 +29,17 @@ module WEBrick
|
|
27
29
|
end
|
28
30
|
module_function :set_non_blocking
|
29
31
|
|
32
|
+
##
|
33
|
+
# Sets the close on exec flag for +io+
|
30
34
|
def set_close_on_exec(io)
|
31
35
|
if defined?(Fcntl::FD_CLOEXEC)
|
32
|
-
io.fcntl(Fcntl::
|
36
|
+
io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
33
37
|
end
|
34
38
|
end
|
35
39
|
module_function :set_close_on_exec
|
36
40
|
|
41
|
+
##
|
42
|
+
# Changes the process's uid and gid to the ones of +user+
|
37
43
|
def su(user)
|
38
44
|
if defined?(Etc)
|
39
45
|
pw = Etc.getpwnam(user)
|
@@ -46,6 +52,8 @@ module WEBrick
|
|
46
52
|
end
|
47
53
|
module_function :su
|
48
54
|
|
55
|
+
##
|
56
|
+
# The server hostname
|
49
57
|
def getservername
|
50
58
|
host = Socket::gethostname
|
51
59
|
begin
|
@@ -56,6 +64,10 @@ module WEBrick
|
|
56
64
|
end
|
57
65
|
module_function :getservername
|
58
66
|
|
67
|
+
##
|
68
|
+
# Creates TCP server sockets bound to +address+:+port+ and returns them.
|
69
|
+
#
|
70
|
+
# It will create IPV4 and IPV6 sockets on all interfaces.
|
59
71
|
def create_listeners(address, port, logger=nil)
|
60
72
|
unless port
|
61
73
|
raise ArgumentError, "must specify port"
|
@@ -84,17 +96,151 @@ module WEBrick
|
|
84
96
|
end
|
85
97
|
module_function :create_listeners
|
86
98
|
|
99
|
+
##
|
100
|
+
# Characters used to generate random strings
|
87
101
|
RAND_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
|
88
102
|
"0123456789" +
|
89
|
-
"abcdefghijklmnopqrstuvwxyz"
|
103
|
+
"abcdefghijklmnopqrstuvwxyz"
|
90
104
|
|
105
|
+
##
|
106
|
+
# Generates a random string of length +len+
|
91
107
|
def random_string(len)
|
92
|
-
rand_max = RAND_CHARS.
|
93
|
-
ret = ""
|
108
|
+
rand_max = RAND_CHARS.bytesize
|
109
|
+
ret = ""
|
94
110
|
len.times{ ret << RAND_CHARS[rand(rand_max)] }
|
95
|
-
ret
|
111
|
+
ret
|
96
112
|
end
|
97
113
|
module_function :random_string
|
98
114
|
|
115
|
+
###########
|
116
|
+
|
117
|
+
require "thread"
|
118
|
+
require "timeout"
|
119
|
+
require "singleton"
|
120
|
+
|
121
|
+
##
|
122
|
+
# Class used to manage timeout handlers across multiple threads.
|
123
|
+
#
|
124
|
+
# Timeout handlers should be managed by using the class methods which are
|
125
|
+
# synchronized.
|
126
|
+
#
|
127
|
+
# id = TimeoutHandler.register(10, Timeout::Error)
|
128
|
+
# begin
|
129
|
+
# sleep 20
|
130
|
+
# puts 'foo'
|
131
|
+
# ensure
|
132
|
+
# TimeoutHandler.cancel(id)
|
133
|
+
# end
|
134
|
+
#
|
135
|
+
# will raise Timeout::Error
|
136
|
+
#
|
137
|
+
# id = TimeoutHandler.register(10, Timeout::Error)
|
138
|
+
# begin
|
139
|
+
# sleep 5
|
140
|
+
# puts 'foo'
|
141
|
+
# ensure
|
142
|
+
# TimeoutHandler.cancel(id)
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# will print 'foo'
|
146
|
+
#
|
147
|
+
class TimeoutHandler
|
148
|
+
include Singleton
|
149
|
+
|
150
|
+
##
|
151
|
+
# Mutex used to synchronize access across threads
|
152
|
+
TimeoutMutex = Mutex.new # :nodoc:
|
153
|
+
|
154
|
+
##
|
155
|
+
# Registers a new timeout handler
|
156
|
+
#
|
157
|
+
# +time+:: Timeout in seconds
|
158
|
+
# +exception+:: Exception to raise when timeout elapsed
|
159
|
+
def TimeoutHandler.register(seconds, exception)
|
160
|
+
TimeoutMutex.synchronize{
|
161
|
+
instance.register(Thread.current, Time.now + seconds, exception)
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# Cancels the timeout handler +id+
|
167
|
+
def TimeoutHandler.cancel(id)
|
168
|
+
TimeoutMutex.synchronize{
|
169
|
+
instance.cancel(Thread.current, id)
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# Creates a new TimeoutHandler. You should use ::register and ::cancel
|
175
|
+
# instead of creating the timeout handler directly.
|
176
|
+
def initialize
|
177
|
+
@timeout_info = Hash.new
|
178
|
+
Thread.start{
|
179
|
+
while true
|
180
|
+
now = Time.now
|
181
|
+
@timeout_info.keys.each{|thread|
|
182
|
+
ary = @timeout_info[thread]
|
183
|
+
next unless ary
|
184
|
+
ary.dup.each{|info|
|
185
|
+
time, exception = *info
|
186
|
+
interrupt(thread, info.object_id, exception) if time < now
|
187
|
+
}
|
188
|
+
}
|
189
|
+
sleep 0.5
|
190
|
+
end
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
194
|
+
##
|
195
|
+
# Interrupts the timeout handler +id+ and raises +exception+
|
196
|
+
def interrupt(thread, id, exception)
|
197
|
+
TimeoutMutex.synchronize{
|
198
|
+
if cancel(thread, id) && thread.alive?
|
199
|
+
thread.raise(exception, "execution timeout")
|
200
|
+
end
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Registers a new timeout handler
|
206
|
+
#
|
207
|
+
# +time+:: Timeout in seconds
|
208
|
+
# +exception+:: Exception to raise when timeout elapsed
|
209
|
+
def register(thread, time, exception)
|
210
|
+
@timeout_info[thread] ||= Array.new
|
211
|
+
@timeout_info[thread] << [time, exception]
|
212
|
+
return @timeout_info[thread].last.object_id
|
213
|
+
end
|
214
|
+
|
215
|
+
##
|
216
|
+
# Cancels the timeout handler +id+
|
217
|
+
def cancel(thread, id)
|
218
|
+
if ary = @timeout_info[thread]
|
219
|
+
ary.delete_if{|info| info.object_id == id }
|
220
|
+
if ary.empty?
|
221
|
+
@timeout_info.delete(thread)
|
222
|
+
end
|
223
|
+
return true
|
224
|
+
end
|
225
|
+
return false
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
##
|
230
|
+
# Executes the passed block and raises +exception+ if execution takes more
|
231
|
+
# than +seconds+.
|
232
|
+
#
|
233
|
+
# If +seconds+ is zero or nil, simply executes the block
|
234
|
+
def timeout(seconds, exception=Timeout::Error)
|
235
|
+
return yield if seconds.nil? or seconds.zero?
|
236
|
+
# raise ThreadError, "timeout within critical session" if Thread.critical
|
237
|
+
id = TimeoutHandler.register(seconds, exception)
|
238
|
+
begin
|
239
|
+
yield(seconds)
|
240
|
+
ensure
|
241
|
+
TimeoutHandler.cancel(id)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
module_function :timeout
|
99
245
|
end
|
100
246
|
end
|
data/lib/webrick/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#--
|
2
2
|
# version.rb -- version and release date
|
3
3
|
#
|
4
4
|
# Author: IPR -- Internet Programming with Ruby -- writers
|
@@ -9,5 +9,9 @@
|
|
9
9
|
# $IPR: version.rb,v 1.74 2003/07/22 19:20:43 gotoyuzo Exp $
|
10
10
|
|
11
11
|
module WEBrick
|
12
|
+
|
13
|
+
##
|
14
|
+
# The WEBrick version
|
15
|
+
|
12
16
|
VERSION = "1.3.1"
|
13
17
|
end
|
data/rubysl-webrick.gemspec
CHANGED
metadata
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubysl-webrick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Shirai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
+
prerelease: false
|
14
15
|
name: bundler
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
@@ -18,13 +19,13 @@ dependencies:
|
|
18
19
|
- !ruby/object:Gem::Version
|
19
20
|
version: '1.3'
|
20
21
|
type: :development
|
21
|
-
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
+
prerelease: false
|
28
29
|
name: rake
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
@@ -32,13 +33,13 @@ dependencies:
|
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: '10.0'
|
34
35
|
type: :development
|
35
|
-
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
+
prerelease: false
|
42
43
|
name: mspec
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
@@ -46,26 +47,11 @@ dependencies:
|
|
46
47
|
- !ruby/object:Gem::Version
|
47
48
|
version: '1.5'
|
48
49
|
type: :development
|
49
|
-
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.5'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rubysl-prettyprint
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ~>
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.0'
|
69
55
|
description: Ruby standard library webrick.
|
70
56
|
email:
|
71
57
|
- brixen@gmail.com
|
@@ -128,17 +114,19 @@ require_paths:
|
|
128
114
|
- lib
|
129
115
|
required_ruby_version: !ruby/object:Gem::Requirement
|
130
116
|
requirements:
|
131
|
-
- - '>='
|
117
|
+
- - ! '>='
|
132
118
|
- !ruby/object:Gem::Version
|
133
|
-
version:
|
119
|
+
version: !binary |-
|
120
|
+
MA==
|
134
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
122
|
requirements:
|
136
|
-
- - '>='
|
123
|
+
- - ! '>='
|
137
124
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
125
|
+
version: !binary |-
|
126
|
+
MA==
|
139
127
|
requirements: []
|
140
128
|
rubyforge_project:
|
141
|
-
rubygems_version: 2.0.
|
129
|
+
rubygems_version: 2.0.6
|
142
130
|
signing_key:
|
143
131
|
specification_version: 4
|
144
132
|
summary: Ruby standard library webrick.
|