webrick 1.4.0.beta1 → 1.4.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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 24fd7f86aee41c3b6f2d1017f780739cd68103a1
4
- data.tar.gz: a6ce1434723786cd182d31042dbb658dbe8f1cef
2
+ SHA256:
3
+ metadata.gz: 926bf6b339db61209654cf64990452098312e0703b9fbcaad9597676ec5773d0
4
+ data.tar.gz: 42b7e45d151849c7572b52aeb077e2eb8737c70bea869d8726117c88a7711dd0
5
5
  SHA512:
6
- metadata.gz: 1f4874e7a0e49a67c93d35237b7eeaa12778d1a5bdf3201809101b426336ddb2e6663ec9f747c42482937c515085bcb31975fce182e3dfc78bd15b7728f3c55f
7
- data.tar.gz: 5c7f0c2b427a27bc2b6dd7f2b4248e47221207e9909ff4d4ed9a303bed8e8dad83f55fa36b2a2497be8eff84a55ea769abfdc49c100094d27c138a0b3db5de77
6
+ metadata.gz: b9e3a2432b7ca093b734b677432d427e2e8a3774f6d2ca6e8f49d27c7de93ba2a2ade32adadbc1dc4b32444f34687dd021f563bd3af0f0327a799ae552bb157e
7
+ data.tar.gz: f8a0eacb288108fc528ee11487d7b823a4366b9edcc86a4fb97467ca7edf0d5a56a974ee67600f5e6c6fa36a787e827d9e03365505b1c3f027322df40420f8af
@@ -193,13 +193,13 @@ module WEBrick
193
193
  begin
194
194
  while fds = IO::select([ua, os])
195
195
  if fds[0].member?(ua)
196
- buf = ua.sysread(1024);
196
+ buf = ua.readpartial(1024);
197
197
  @logger.debug("CONNECT: #{buf.bytesize} byte from User-Agent")
198
- os.syswrite(buf)
198
+ os.write(buf)
199
199
  elsif fds[0].member?(os)
200
- buf = os.sysread(1024);
200
+ buf = os.readpartial(1024);
201
201
  @logger.debug("CONNECT: #{buf.bytesize} byte from #{host}:#{port}")
202
- ua.syswrite(buf)
202
+ ua.write(buf)
203
203
  end
204
204
  end
205
205
  rescue
@@ -303,6 +303,8 @@ module WEBrick
303
303
  def send_body(socket) # :nodoc:
304
304
  if @body.respond_to? :readpartial then
305
305
  send_body_io(socket)
306
+ elsif @body.respond_to?(:call) then
307
+ send_body_proc(socket)
306
308
  else
307
309
  send_body_string(socket)
308
310
  end
@@ -394,19 +396,18 @@ module WEBrick
394
396
  if @request_method == "HEAD"
395
397
  # do nothing
396
398
  elsif chunked?
399
+ buf = ''
397
400
  begin
398
- buf = ''
399
- data = ''
400
- while true
401
- @body.readpartial( @buffer_size, buf ) # there is no need to clear buf?
402
- data << format("%x", buf.bytesize) << CRLF
403
- data << buf << CRLF
404
- _write_data(socket, data)
405
- data.clear
406
- @sent_size += buf.bytesize
407
- end
408
- rescue EOFError # do nothing
409
- end
401
+ @body.readpartial(@buffer_size, buf)
402
+ size = buf.bytesize
403
+ data = "#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}"
404
+ _write_data(socket, data)
405
+ data.clear
406
+ @sent_size += size
407
+ rescue EOFError
408
+ break
409
+ end while true
410
+ buf.clear
410
411
  _write_data(socket, "0#{CRLF}#{CRLF}")
411
412
  else
412
413
  size = @header['content-length'].to_i
@@ -425,11 +426,11 @@ module WEBrick
425
426
  body ? @body.bytesize : 0
426
427
  while buf = @body[@sent_size, @buffer_size]
427
428
  break if buf.empty?
428
- data = ""
429
- data << format("%x", buf.bytesize) << CRLF
430
- data << buf << CRLF
429
+ size = buf.bytesize
430
+ data = "#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}"
431
+ buf.clear
431
432
  _write_data(socket, data)
432
- @sent_size += buf.bytesize
433
+ @sent_size += size
433
434
  end
434
435
  _write_data(socket, "0#{CRLF}#{CRLF}")
435
436
  else
@@ -440,6 +441,39 @@ module WEBrick
440
441
  end
441
442
  end
442
443
 
444
+ def send_body_proc(socket)
445
+ if @request_method == "HEAD"
446
+ # do nothing
447
+ elsif chunked?
448
+ @body.call(ChunkedWrapper.new(socket, self))
449
+ _write_data(socket, "0#{CRLF}#{CRLF}")
450
+ else
451
+ size = @header['content-length'].to_i
452
+ @body.call(socket)
453
+ @sent_size = size
454
+ end
455
+ end
456
+
457
+ class ChunkedWrapper
458
+ def initialize(socket, resp)
459
+ @socket = socket
460
+ @resp = resp
461
+ end
462
+
463
+ def write(buf)
464
+ return if buf.empty?
465
+ socket = @socket
466
+ @resp.instance_eval {
467
+ size = buf.bytesize
468
+ data = "#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}"
469
+ _write_data(socket, data)
470
+ data.clear
471
+ @sent_size += size
472
+ }
473
+ end
474
+ alias :<< :write
475
+ end
476
+
443
477
  def _send_file(output, input, offset, size)
444
478
  while offset > 0
445
479
  sz = @buffer_size < size ? @buffer_size : size
@@ -10,6 +10,7 @@
10
10
  # $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $
11
11
 
12
12
  require 'webrick/ssl'
13
+ require 'webrick/httpserver'
13
14
 
14
15
  module WEBrick
15
16
  module Config
@@ -84,4 +85,68 @@ module WEBrick
84
85
 
85
86
  # :startdoc:
86
87
  end
88
+
89
+ ##
90
+ #--
91
+ # Fake WEBrick::HTTPRequest for lookup_server
92
+
93
+ class SNIRequest
94
+
95
+ ##
96
+ # The SNI hostname
97
+
98
+ attr_reader :host
99
+
100
+ ##
101
+ # The socket address of the server
102
+
103
+ attr_reader :addr
104
+
105
+ ##
106
+ # The port this request is for
107
+
108
+ attr_reader :port
109
+
110
+ ##
111
+ # Creates a new SNIRequest.
112
+
113
+ def initialize(sslsocket, hostname)
114
+ @host = hostname
115
+ @addr = sslsocket.addr
116
+ @port = @addr[1]
117
+ end
118
+ end
119
+
120
+
121
+ ##
122
+ #--
123
+ # Adds SSL functionality to WEBrick::HTTPServer
124
+
125
+ class HTTPServer < ::WEBrick::GenericServer
126
+ ##
127
+ # ServerNameIndication callback
128
+
129
+ def ssl_servername_callback(sslsocket, hostname = nil)
130
+ req = SNIRequest.new(sslsocket, hostname)
131
+ server = lookup_server(req)
132
+ server ? server.ssl_context : nil
133
+ end
134
+
135
+ # :stopdoc:
136
+
137
+ ##
138
+ # Check whether +server+ is also SSL server.
139
+ # Also +server+'s SSL context will be created.
140
+
141
+ alias orig_virtual_host virtual_host
142
+
143
+ def virtual_host(server)
144
+ if @config[:SSLEnable] && !server.ssl_context
145
+ raise ArgumentError, "virtual host must set SSLEnable to true"
146
+ end
147
+ orig_virtual_host(server)
148
+ end
149
+
150
+ # :startdoc:
151
+ end
87
152
  end
@@ -267,12 +267,12 @@ module WEBrick
267
267
  k.sort!
268
268
  k.reverse!
269
269
  k.collect!{|path| Regexp.escape(path) }
270
- @scanner = Regexp.new("^(" + k.join("|") +")(?=/|$)")
270
+ @scanner = Regexp.new("\\A(" + k.join("|") +")(?=/|\\z)")
271
271
  end
272
272
 
273
273
  def normalize(dir)
274
274
  ret = dir ? dir.dup : ""
275
- ret.sub!(%r|/+$|, "")
275
+ ret.sub!(%r|/+\z|, "")
276
276
  ret
277
277
  end
278
278
  end
@@ -9,8 +9,6 @@
9
9
  #
10
10
  # $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $
11
11
 
12
- require 'thread'
13
-
14
12
  require 'webrick/htmlutils'
15
13
  require 'webrick/httputils'
16
14
  require 'webrick/httpstatus'
@@ -9,7 +9,6 @@
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
14
  require 'webrick/htmlutils'
@@ -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
@@ -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",
@@ -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
@@ -9,7 +9,6 @@
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
13
  require 'webrick/config'
15
14
  require 'webrick/log'
@@ -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], nil, nil, 2.0)
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 = nil
256
- begin
257
- sock = svr.accept
258
- sock.sync = true
259
- Utils::set_non_blocking(sock)
260
- rescue Errno::ECONNRESET, Errno::ECONNABORTED,
261
- Errno::EPROTO, Errno::EINVAL
262
- rescue StandardError => ex
263
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
264
- @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
265
266
  end
266
- 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
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
@@ -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 ::
@@ -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 ||= nil
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]
@@ -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
@@ -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
 
@@ -14,5 +14,5 @@ module WEBrick
14
14
  ##
15
15
  # The WEBrick version
16
16
 
17
- VERSION = "1.4.0.beta1"
17
+ VERSION = "1.4.0"
18
18
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webrick
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0.beta1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TAKAHASHI Masayoshi
8
8
  - GOTOU YUUZOU
9
+ - Eric Wong
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2017-05-01 00:00:00.000000000 Z
13
+ date: 2017-12-14 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rake
@@ -30,6 +31,7 @@ description: WEBrick is an HTTP server toolkit that can be configured as an HTTP
30
31
  email:
31
32
  -
32
33
  -
34
+ - normal@ruby-lang.org
33
35
  executables: []
34
36
  extensions: []
35
37
  extra_rdoc_files: []
@@ -72,7 +74,10 @@ files:
72
74
  homepage: https://www.ruby-lang.org
73
75
  licenses:
74
76
  - BSD-2-Clause
75
- metadata: {}
77
+ metadata:
78
+ bug_tracker_uri: https://bugs.ruby-lang.org/projects/ruby-trunk/issues
79
+ homepage_uri: https://www.ruby-lang.org
80
+ source_code_uri: https://svn.ruby-lang.org/repos/ruby
76
81
  post_install_message:
77
82
  rdoc_options: []
78
83
  require_paths:
@@ -84,12 +89,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
84
89
  version: 2.5.0dev
85
90
  required_rubygems_version: !ruby/object:Gem::Requirement
86
91
  requirements:
87
- - - ">"
92
+ - - ">="
88
93
  - !ruby/object:Gem::Version
89
- version: 1.3.1
94
+ version: '0'
90
95
  requirements: []
91
96
  rubyforge_project:
92
- rubygems_version: 2.6.11
97
+ rubygems_version: 2.7.3
93
98
  signing_key:
94
99
  specification_version: 4
95
100
  summary: HTTP server toolkit