webrick 1.3.1 → 1.5.0

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.

Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +63 -0
  5. data/Rakefile +10 -0
  6. data/bin/console +14 -0
  7. data/bin/setup +8 -0
  8. data/lib/webrick/accesslog.rb +9 -1
  9. data/lib/webrick/cgi.rb +58 -5
  10. data/lib/webrick/compat.rb +2 -1
  11. data/lib/webrick/config.rb +47 -10
  12. data/lib/webrick/cookie.rb +69 -7
  13. data/lib/webrick/htmlutils.rb +4 -2
  14. data/lib/webrick/httpauth/authenticator.rb +13 -8
  15. data/lib/webrick/httpauth/basicauth.rb +16 -8
  16. data/lib/webrick/httpauth/digestauth.rb +35 -32
  17. data/lib/webrick/httpauth/htdigest.rb +12 -8
  18. data/lib/webrick/httpauth/htgroup.rb +10 -6
  19. data/lib/webrick/httpauth/htpasswd.rb +46 -9
  20. data/lib/webrick/httpauth/userdb.rb +1 -0
  21. data/lib/webrick/httpauth.rb +6 -5
  22. data/lib/webrick/httpproxy.rb +93 -48
  23. data/lib/webrick/httprequest.rb +192 -27
  24. data/lib/webrick/httpresponse.rb +221 -70
  25. data/lib/webrick/https.rb +90 -2
  26. data/lib/webrick/httpserver.rb +45 -15
  27. data/lib/webrick/httpservlet/abstract.rb +5 -6
  28. data/lib/webrick/httpservlet/cgi_runner.rb +3 -2
  29. data/lib/webrick/httpservlet/cgihandler.rb +22 -10
  30. data/lib/webrick/httpservlet/erbhandler.rb +4 -3
  31. data/lib/webrick/httpservlet/filehandler.rb +136 -65
  32. data/lib/webrick/httpservlet/prochandler.rb +15 -1
  33. data/lib/webrick/httpservlet.rb +6 -5
  34. data/lib/webrick/httpstatus.rb +24 -14
  35. data/lib/webrick/httputils.rb +133 -13
  36. data/lib/webrick/httpversion.rb +28 -1
  37. data/lib/webrick/log.rb +25 -5
  38. data/lib/webrick/server.rb +234 -74
  39. data/lib/webrick/ssl.rb +100 -12
  40. data/lib/webrick/utils.rb +98 -69
  41. data/lib/webrick/version.rb +6 -1
  42. data/lib/webrick.rb +7 -7
  43. data/webrick.gemspec +76 -0
  44. metadata +70 -69
  45. data/README.txt +0 -21
  46. data/sample/webrick/demo-app.rb +0 -66
  47. data/sample/webrick/demo-multipart.cgi +0 -12
  48. data/sample/webrick/demo-servlet.rb +0 -6
  49. data/sample/webrick/demo-urlencoded.cgi +0 -12
  50. data/sample/webrick/hello.cgi +0 -11
  51. data/sample/webrick/hello.rb +0 -8
  52. data/sample/webrick/httpd.rb +0 -23
  53. data/sample/webrick/httpproxy.rb +0 -25
  54. data/sample/webrick/httpsd.rb +0 -33
  55. data/test/openssl/utils.rb +0 -313
  56. data/test/ruby/envutil.rb +0 -208
  57. data/test/webrick/test_cgi.rb +0 -134
  58. data/test/webrick/test_cookie.rb +0 -131
  59. data/test/webrick/test_filehandler.rb +0 -285
  60. data/test/webrick/test_httpauth.rb +0 -167
  61. data/test/webrick/test_httpproxy.rb +0 -282
  62. data/test/webrick/test_httprequest.rb +0 -411
  63. data/test/webrick/test_httpresponse.rb +0 -49
  64. data/test/webrick/test_httpserver.rb +0 -305
  65. data/test/webrick/test_httputils.rb +0 -96
  66. data/test/webrick/test_httpversion.rb +0 -40
  67. data/test/webrick/test_server.rb +0 -67
  68. data/test/webrick/test_utils.rb +0 -64
  69. data/test/webrick/utils.rb +0 -58
  70. data/test/webrick/webrick.cgi +0 -36
  71. data/test/webrick/webrick_long_filename.cgi +0 -36
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: false
1
2
  #
2
3
  # server.rb -- GenericServer Class
3
4
  #
@@ -8,16 +9,25 @@
8
9
  #
9
10
  # $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $
10
11
 
11
- require 'thread'
12
12
  require 'socket'
13
- require 'webrick/config'
14
- require 'webrick/log'
13
+ require_relative 'config'
14
+ require_relative 'log'
15
15
 
16
16
  module WEBrick
17
17
 
18
+ ##
19
+ # Server error exception
20
+
18
21
  class ServerError < StandardError; end
19
22
 
23
+ ##
24
+ # Base server class
25
+
20
26
  class SimpleServer
27
+
28
+ ##
29
+ # A SimpleServer only yields when you start it
30
+
21
31
  def SimpleServer.start
22
32
  yield
23
33
  end
@@ -33,20 +43,47 @@ module WEBrick
33
43
  # block, if given.
34
44
 
35
45
  def Daemon.start
36
- exit!(0) if fork
37
- Process::setsid
38
- exit!(0) if fork
39
- Dir::chdir("/")
40
- File::umask(0)
41
- STDIN.reopen("/dev/null")
42
- STDOUT.reopen("/dev/null", "w")
43
- STDERR.reopen("/dev/null", "w")
46
+ Process.daemon
47
+ File.umask(0)
44
48
  yield if block_given?
45
49
  end
46
50
  end
47
51
 
52
+ ##
53
+ # Base TCP server class. You must subclass GenericServer and provide a #run
54
+ # method.
55
+
48
56
  class GenericServer
49
- attr_reader :status, :config, :logger, :tokens, :listeners
57
+
58
+ ##
59
+ # The server status. One of :Stop, :Running or :Shutdown
60
+
61
+ attr_reader :status
62
+
63
+ ##
64
+ # The server configuration
65
+
66
+ attr_reader :config
67
+
68
+ ##
69
+ # The server logger. This is independent from the HTTP access log.
70
+
71
+ attr_reader :logger
72
+
73
+ ##
74
+ # Tokens control the number of outstanding clients. The
75
+ # <code>:MaxClients</code> configuration sets this.
76
+
77
+ attr_reader :tokens
78
+
79
+ ##
80
+ # Sockets listening for connections.
81
+
82
+ attr_reader :listeners
83
+
84
+ ##
85
+ # Creates a new generic server from +config+. The default configuration
86
+ # comes from +default+.
50
87
 
51
88
  def initialize(config={}, default=Config::General)
52
89
  @config = default.dup.update(config)
@@ -54,7 +91,7 @@ module WEBrick
54
91
  @config[:Logger] ||= Log::new
55
92
  @logger = @config[:Logger]
56
93
 
57
- @tokens = SizedQueue.new(@config[:MaxClients])
94
+ @tokens = Thread::SizedQueue.new(@config[:MaxClients])
58
95
  @config[:MaxClients].times{ @tokens.push(nil) }
59
96
 
60
97
  webrickv = WEBrick::VERSION
@@ -63,9 +100,10 @@ module WEBrick
63
100
  @logger.info("ruby #{rubyv}")
64
101
 
65
102
  @listeners = []
103
+ @shutdown_pipe = nil
66
104
  unless @config[:DoNotListen]
67
105
  if @config[:Listen]
68
- warn(":Listen option is deprecated; use GenericServer#listen")
106
+ warn(":Listen option is deprecated; use GenericServer#listen", uplevel: 1)
69
107
  end
70
108
  listen(@config[:BindAddress], @config[:Port])
71
109
  if @config[:Port] == 0
@@ -74,108 +112,176 @@ module WEBrick
74
112
  end
75
113
  end
76
114
 
115
+ ##
116
+ # Retrieves +key+ from the configuration
117
+
77
118
  def [](key)
78
119
  @config[key]
79
120
  end
80
121
 
122
+ ##
123
+ # Adds listeners from +address+ and +port+ to the server. See
124
+ # WEBrick::Utils::create_listeners for details.
125
+
81
126
  def listen(address, port)
82
- @listeners += Utils::create_listeners(address, port, @logger)
127
+ @listeners += Utils::create_listeners(address, port)
83
128
  end
84
129
 
130
+ ##
131
+ # Starts the server and runs the +block+ for each connection. This method
132
+ # does not return until the server is stopped from a signal handler or
133
+ # another thread using #stop or #shutdown.
134
+ #
135
+ # If the block raises a subclass of StandardError the exception is logged
136
+ # and ignored. If an IOError or Errno::EBADF exception is raised the
137
+ # exception is ignored. If an Exception subclass is raised the exception
138
+ # is logged and re-raised which stops the server.
139
+ #
140
+ # To completely shut down a server call #shutdown from ensure:
141
+ #
142
+ # server = WEBrick::GenericServer.new
143
+ # # or WEBrick::HTTPServer.new
144
+ #
145
+ # begin
146
+ # server.start
147
+ # ensure
148
+ # server.shutdown
149
+ # end
150
+
85
151
  def start(&block)
86
152
  raise ServerError, "already started." if @status != :Stop
87
153
  server_type = @config[:ServerType] || SimpleServer
88
154
 
155
+ setup_shutdown_pipe
156
+
89
157
  server_type.start{
90
158
  @logger.info \
91
159
  "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
160
+ @status = :Running
92
161
  call_callback(:StartCallback)
93
162
 
163
+ shutdown_pipe = @shutdown_pipe
164
+
94
165
  thgroup = ThreadGroup.new
95
- @status = :Running
96
- while @status == :Running
97
- begin
98
- if svrs = IO.select(@listeners, nil, nil, 2.0)
99
- svrs[0].each{|svr|
100
- @tokens.pop # blocks while no token is there.
101
- if sock = accept_client(svr)
102
- sock.do_not_reverse_lookup = config[:DoNotReverseLookup]
103
- th = start_thread(sock, &block)
104
- th[:WEBrickThread] = true
105
- thgroup.add(th)
106
- else
107
- @tokens.push(nil)
166
+ begin
167
+ while @status == :Running
168
+ begin
169
+ sp = shutdown_pipe[0]
170
+ if svrs = IO.select([sp, *@listeners])
171
+ if svrs[0].include? sp
172
+ # swallow shutdown pipe
173
+ buf = String.new
174
+ nil while String ===
175
+ sp.read_nonblock([sp.nread, 8].max, buf, exception: false)
176
+ break
108
177
  end
109
- }
178
+ svrs[0].each{|svr|
179
+ @tokens.pop # blocks while no token is there.
180
+ if sock = accept_client(svr)
181
+ unless config[:DoNotReverseLookup].nil?
182
+ sock.do_not_reverse_lookup = !!config[:DoNotReverseLookup]
183
+ end
184
+ th = start_thread(sock, &block)
185
+ th[:WEBrickThread] = true
186
+ thgroup.add(th)
187
+ else
188
+ @tokens.push(nil)
189
+ end
190
+ }
191
+ end
192
+ rescue Errno::EBADF, Errno::ENOTSOCK, IOError => ex
193
+ # if the listening socket was closed in GenericServer#shutdown,
194
+ # IO::select raise it.
195
+ rescue StandardError => ex
196
+ msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
197
+ @logger.error msg
198
+ rescue Exception => ex
199
+ @logger.fatal ex
200
+ raise
110
201
  end
111
- rescue Errno::EBADF, IOError => ex
112
- # if the listening socket was closed in GenericServer#shutdown,
113
- # IO::select raise it.
114
- rescue Exception => ex
115
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
116
- @logger.error msg
117
202
  end
203
+ ensure
204
+ cleanup_shutdown_pipe(shutdown_pipe)
205
+ cleanup_listener
206
+ @status = :Shutdown
207
+ @logger.info "going to shutdown ..."
208
+ thgroup.list.each{|th| th.join if th[:WEBrickThread] }
209
+ call_callback(:StopCallback)
210
+ @logger.info "#{self.class}#start done."
211
+ @status = :Stop
118
212
  end
119
-
120
- @logger.info "going to shutdown ..."
121
- thgroup.list.each{|th| th.join if th[:WEBrickThread] }
122
- call_callback(:StopCallback)
123
- @logger.info "#{self.class}#start done."
124
- @status = :Stop
125
213
  }
126
214
  end
127
215
 
216
+ ##
217
+ # Stops the server from accepting new connections.
218
+
128
219
  def stop
129
220
  if @status == :Running
130
221
  @status = :Shutdown
131
222
  end
223
+
224
+ alarm_shutdown_pipe {|f| f.write_nonblock("\0")}
132
225
  end
133
226
 
227
+ ##
228
+ # Shuts down the server and all listening sockets. New listeners must be
229
+ # provided to restart the server.
230
+
134
231
  def shutdown
135
232
  stop
136
- @listeners.each{|s|
137
- if @logger.debug?
138
- addr = s.addr
139
- @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})")
140
- end
141
- begin
142
- s.shutdown
143
- rescue Errno::ENOTCONN
144
- # when `Errno::ENOTCONN: Socket is not connected' on some platforms,
145
- # call #close instead of #shutdown.
146
- # (ignore @config[:ShutdownSocketWithoutClose])
147
- s.close
148
- else
149
- unless @config[:ShutdownSocketWithoutClose]
150
- s.close
151
- end
152
- end
153
- }
154
- @listeners.clear
233
+
234
+ alarm_shutdown_pipe(&:close)
155
235
  end
156
236
 
237
+ ##
238
+ # You must subclass GenericServer and implement \#run which accepts a TCP
239
+ # client socket
240
+
157
241
  def run(sock)
158
242
  @logger.fatal "run() must be provided by user."
159
243
  end
160
244
 
161
245
  private
162
246
 
247
+ # :stopdoc:
248
+
249
+ ##
250
+ # Accepts a TCP client socket from the TCP server socket +svr+ and returns
251
+ # the client socket.
252
+
163
253
  def accept_client(svr)
164
- sock = nil
165
- begin
166
- sock = svr.accept
167
- sock.sync = true
168
- Utils::set_non_blocking(sock)
169
- Utils::set_close_on_exec(sock)
170
- rescue Errno::ECONNRESET, Errno::ECONNABORTED,
171
- Errno::EPROTO, Errno::EINVAL => ex
172
- rescue Exception => ex
173
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
174
- @logger.error msg
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
175
266
  end
176
- return sock
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
177
274
  end
178
275
 
276
+ ##
277
+ # Starts a server thread for the client socket +sock+ that runs the given
278
+ # +block+.
279
+ #
280
+ # Sets the socket to the <code>:WEBrickSocket</code> thread local variable
281
+ # in the thread.
282
+ #
283
+ # If any errors occur in the block they are logged and handled.
284
+
179
285
  def start_thread(sock, &block)
180
286
  Thread.start{
181
287
  begin
@@ -187,6 +293,16 @@ module WEBrick
187
293
  @logger.debug "accept: <address unknown>"
188
294
  raise
189
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
190
306
  call_callback(:AcceptCallback, sock)
191
307
  block ? block.call(sock) : run(sock)
192
308
  rescue Errno::ENOTCONN
@@ -209,10 +325,54 @@ module WEBrick
209
325
  }
210
326
  end
211
327
 
328
+ ##
329
+ # Calls the callback +callback_name+ from the configuration with +args+
330
+
212
331
  def call_callback(callback_name, *args)
213
- if cb = @config[callback_name]
214
- cb.call(*args)
332
+ @config[callback_name]&.call(*args)
333
+ end
334
+
335
+ def setup_shutdown_pipe
336
+ return @shutdown_pipe ||= IO.pipe
337
+ end
338
+
339
+ def cleanup_shutdown_pipe(shutdown_pipe)
340
+ @shutdown_pipe = nil
341
+ shutdown_pipe&.each(&:close)
342
+ end
343
+
344
+ def alarm_shutdown_pipe
345
+ _, pipe = @shutdown_pipe # another thread may modify @shutdown_pipe.
346
+ if pipe
347
+ if !pipe.closed?
348
+ begin
349
+ yield pipe
350
+ rescue IOError # closed by another thread.
351
+ end
352
+ end
215
353
  end
216
354
  end
355
+
356
+ def cleanup_listener
357
+ @listeners.each{|s|
358
+ if @logger.debug?
359
+ addr = s.addr
360
+ @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})")
361
+ end
362
+ begin
363
+ s.shutdown
364
+ rescue Errno::ENOTCONN
365
+ # when `Errno::ENOTCONN: Socket is not connected' on some platforms,
366
+ # call #close instead of #shutdown.
367
+ # (ignore @config[:ShutdownSocketWithoutClose])
368
+ s.close
369
+ else
370
+ unless @config[:ShutdownSocketWithoutClose]
371
+ s.close
372
+ end
373
+ end
374
+ }
375
+ @listeners.clear
376
+ end
217
377
  end # end of GenericServer
218
378
  end
data/lib/webrick/ssl.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: false
1
2
  #
2
3
  # ssl.rb -- SSL/TLS enhancement for GenericServer
3
4
  #
@@ -12,6 +13,57 @@ module WEBrick
12
13
  module Config
13
14
  svrsoft = General[:ServerSoftware]
14
15
  osslv = ::OpenSSL::OPENSSL_VERSION.split[1]
16
+
17
+ ##
18
+ # Default SSL server configuration.
19
+ #
20
+ # WEBrick can automatically create a self-signed certificate if
21
+ # <code>:SSLCertName</code> is set. For more information on the various
22
+ # SSL options see OpenSSL::SSL::SSLContext.
23
+ #
24
+ # :ServerSoftware ::
25
+ # The server software name used in the Server: header.
26
+ # :SSLEnable :: false,
27
+ # Enable SSL for this server. Defaults to false.
28
+ # :SSLCertificate ::
29
+ # The SSL certificate for the server.
30
+ # :SSLPrivateKey ::
31
+ # The SSL private key for the server certificate.
32
+ # :SSLClientCA :: nil,
33
+ # Array of certificates that will be sent to the client.
34
+ # :SSLExtraChainCert :: nil,
35
+ # Array of certificates that will be added to the certificate chain
36
+ # :SSLCACertificateFile :: nil,
37
+ # Path to a CA certificate file
38
+ # :SSLCACertificatePath :: nil,
39
+ # Path to a directory containing CA certificates
40
+ # :SSLCertificateStore :: nil,
41
+ # OpenSSL::X509::Store used for certificate validation of the client
42
+ # :SSLTmpDhCallback :: nil,
43
+ # Callback invoked when DH parameters are required.
44
+ # :SSLVerifyClient ::
45
+ # Sets whether the client is verified. This defaults to VERIFY_NONE
46
+ # which is typical for an HTTPS server.
47
+ # :SSLVerifyDepth ::
48
+ # Number of CA certificates to walk when verifying a certificate chain
49
+ # :SSLVerifyCallback ::
50
+ # Custom certificate verification callback
51
+ # :SSLServerNameCallback::
52
+ # Custom servername indication callback
53
+ # :SSLTimeout ::
54
+ # Maximum session lifetime
55
+ # :SSLOptions ::
56
+ # Various SSL options
57
+ # :SSLCiphers ::
58
+ # Ciphers to be used
59
+ # :SSLStartImmediately ::
60
+ # Immediately start SSL upon connection? Defaults to true
61
+ # :SSLCertName ::
62
+ # SSL certificate name. Must be set to enable automatic certificate
63
+ # creation.
64
+ # :SSLCertComment ::
65
+ # Comment used during automatic certificate creation.
66
+
15
67
  SSL = {
16
68
  :ServerSoftware => "#{svrsoft} OpenSSL/#{osslv}",
17
69
  :SSLEnable => false,
@@ -22,11 +74,13 @@ module WEBrick
22
74
  :SSLCACertificateFile => nil,
23
75
  :SSLCACertificatePath => nil,
24
76
  :SSLCertificateStore => nil,
77
+ :SSLTmpDhCallback => nil,
25
78
  :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
26
79
  :SSLVerifyDepth => nil,
27
80
  :SSLVerifyCallback => nil, # custom verification
28
81
  :SSLTimeout => nil,
29
82
  :SSLOptions => nil,
83
+ :SSLCiphers => nil,
30
84
  :SSLStartImmediately => true,
31
85
  # Must specify if you use auto generated certificate.
32
86
  :SSLCertName => nil,
@@ -36,6 +90,10 @@ module WEBrick
36
90
  end
37
91
 
38
92
  module Utils
93
+ ##
94
+ # Creates a self-signed certificate with the given number of +bits+,
95
+ # the issuer +cn+ and a +comment+ to be stored in the certificate.
96
+
39
97
  def create_self_signed_cert(bits, cn, comment)
40
98
  rsa = OpenSSL::PKey::RSA.new(bits){|p, n|
41
99
  case p
@@ -52,7 +110,8 @@ module WEBrick
52
110
  cert = OpenSSL::X509::Certificate.new
53
111
  cert.version = 2
54
112
  cert.serial = 1
55
- name = OpenSSL::X509::Name.new(cn)
113
+ name = (cn.kind_of? String) ? OpenSSL::X509::Name.parse(cn)
114
+ : OpenSSL::X509::Name.new(cn)
56
115
  cert.subject = name
57
116
  cert.issuer = name
58
117
  cert.not_before = Time.now
@@ -71,26 +130,40 @@ module WEBrick
71
130
  aki = ef.create_extension("authorityKeyIdentifier",
72
131
  "keyid:always,issuer:always")
73
132
  cert.add_extension(aki)
74
- cert.sign(rsa, OpenSSL::Digest::SHA1.new)
133
+ cert.sign(rsa, OpenSSL::Digest::SHA256.new)
75
134
 
76
135
  return [ cert, rsa ]
77
136
  end
78
137
  module_function :create_self_signed_cert
79
138
  end
80
139
 
140
+ ##
141
+ #--
142
+ # Updates WEBrick::GenericServer with SSL functionality
143
+
81
144
  class GenericServer
82
- def ssl_context
83
- @ssl_context ||= nil
145
+
146
+ ##
147
+ # SSL context for the server when run in SSL mode
148
+
149
+ def ssl_context # :nodoc:
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
84
157
  end
85
158
 
86
159
  undef listen
87
- def listen(address, port)
88
- listeners = Utils::create_listeners(address, port, @logger)
160
+
161
+ ##
162
+ # Updates +listen+ to enable SSL when the SSL configuration is active.
163
+
164
+ def listen(address, port) # :nodoc:
165
+ listeners = Utils::create_listeners(address, port)
89
166
  if @config[:SSLEnable]
90
- unless ssl_context
91
- @ssl_context = setup_ssl_context(@config)
92
- @logger.info("\n" + @config[:SSLCertificate].to_text)
93
- end
94
167
  listeners.collect!{|svr|
95
168
  ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context)
96
169
  ssvr.start_immediately = @config[:SSLStartImmediately]
@@ -98,13 +171,17 @@ module WEBrick
98
171
  }
99
172
  end
100
173
  @listeners += listeners
174
+ setup_shutdown_pipe
101
175
  end
102
176
 
103
- def setup_ssl_context(config)
177
+ ##
178
+ # Sets up an SSL context for +config+
179
+
180
+ def setup_ssl_context(config) # :nodoc:
104
181
  unless config[:SSLCertificate]
105
182
  cn = config[:SSLCertName]
106
183
  comment = config[:SSLCertComment]
107
- cert, key = Utils::create_self_signed_cert(1024, cn, comment)
184
+ cert, key = Utils::create_self_signed_cert(2048, cn, comment)
108
185
  config[:SSLCertificate] = cert
109
186
  config[:SSLPrivateKey] = key
110
187
  end
@@ -116,12 +193,23 @@ module WEBrick
116
193
  ctx.ca_file = config[:SSLCACertificateFile]
117
194
  ctx.ca_path = config[:SSLCACertificatePath]
118
195
  ctx.cert_store = config[:SSLCertificateStore]
196
+ ctx.tmp_dh_callback = config[:SSLTmpDhCallback]
119
197
  ctx.verify_mode = config[:SSLVerifyClient]
120
198
  ctx.verify_depth = config[:SSLVerifyDepth]
121
199
  ctx.verify_callback = config[:SSLVerifyCallback]
200
+ ctx.servername_cb = config[:SSLServerNameCallback] || proc { |args| ssl_servername_callback(*args) }
122
201
  ctx.timeout = config[:SSLTimeout]
123
202
  ctx.options = config[:SSLOptions]
203
+ ctx.ciphers = config[:SSLCiphers]
124
204
  ctx
125
205
  end
206
+
207
+ ##
208
+ # ServerNameIndication callback
209
+
210
+ def ssl_servername_callback(sslsocket, hostname = nil)
211
+ # default
212
+ end
213
+
126
214
  end
127
215
  end