puma 5.0.0.beta1 → 5.0.0.beta2

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.

Potentially problematic release.


This version of puma might be problematic. Click here for more details.

@@ -98,10 +98,22 @@ module Puma
98
98
  @binder = bind
99
99
  end
100
100
 
101
+ class << self
102
+ # :nodoc:
103
+ def tcp_cork_supported?
104
+ RbConfig::CONFIG['host_os'] =~ /linux/ &&
105
+ Socket.const_defined?(:IPPROTO_TCP) &&
106
+ Socket.const_defined?(:TCP_CORK) &&
107
+ Socket.const_defined?(:SOL_TCP) &&
108
+ Socket.const_defined?(:TCP_INFO)
109
+ end
110
+ private :tcp_cork_supported?
111
+ end
112
+
101
113
  # On Linux, use TCP_CORK to better control how the TCP stack
102
114
  # packetizes our stream. This improves both latency and throughput.
103
115
  #
104
- if RUBY_PLATFORM =~ /linux/
116
+ if tcp_cork_supported?
105
117
  UNPACK_TCP_STATE_FROM_TCP_INFO = "C".freeze
106
118
 
107
119
  # 6 == Socket::IPPROTO_TCP
@@ -109,7 +121,7 @@ module Puma
109
121
  # 1/0 == turn on/off
110
122
  def cork_socket(socket)
111
123
  begin
112
- socket.setsockopt(6, 3, 1) if socket.kind_of? TCPSocket
124
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if socket.kind_of? TCPSocket
113
125
  rescue IOError, SystemCallError
114
126
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
115
127
  end
@@ -117,7 +129,7 @@ module Puma
117
129
 
118
130
  def uncork_socket(socket)
119
131
  begin
120
- socket.setsockopt(6, 3, 0) if socket.kind_of? TCPSocket
132
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if socket.kind_of? TCPSocket
121
133
  rescue IOError, SystemCallError
122
134
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
123
135
  end
@@ -207,14 +219,16 @@ module Puma
207
219
 
208
220
  client.close
209
221
 
210
- @events.ssl_error self, addr, cert, e
222
+ @events.ssl_error e, addr, cert
211
223
  rescue HttpParserError => e
212
224
  client.write_error(400)
213
225
  client.close
214
226
 
215
- @events.parse_error self, client.env, e
216
- rescue ConnectionError, EOFError
227
+ @events.parse_error e, client
228
+ rescue ConnectionError, EOFError => e
217
229
  client.close
230
+
231
+ @events.connection_error e, client
218
232
  else
219
233
  if process_now
220
234
  process_client client, buffer
@@ -281,35 +295,26 @@ module Puma
281
295
  if sock == check
282
296
  break if handle_check
283
297
  else
284
- begin
285
- pool.wait_until_not_full
286
- pool.wait_for_less_busy_worker(
287
- @options[:wait_for_less_busy_worker].to_f)
288
-
289
- if io = sock.accept_nonblock
290
- client = Client.new io, @binder.env(sock)
291
- if remote_addr_value
292
- client.peerip = remote_addr_value
293
- elsif remote_addr_header
294
- client.remote_addr_header = remote_addr_header
295
- end
296
-
297
- pool << client
298
- end
299
- rescue SystemCallError
300
- # nothing
301
- rescue Errno::ECONNABORTED
302
- # client closed the socket even before accept
303
- begin
304
- io.close
305
- rescue
306
- Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
307
- end
298
+ pool.wait_until_not_full
299
+ pool.wait_for_less_busy_worker(
300
+ @options[:wait_for_less_busy_worker].to_f)
301
+
302
+ io = begin
303
+ sock.accept_nonblock
304
+ rescue IO::WaitReadable
305
+ next
306
+ end
307
+ client = Client.new io, @binder.env(sock)
308
+ if remote_addr_value
309
+ client.peerip = remote_addr_value
310
+ elsif remote_addr_header
311
+ client.remote_addr_header = remote_addr_header
308
312
  end
313
+ pool << client
309
314
  end
310
315
  end
311
316
  rescue Object => e
312
- @events.unknown_error self, e, "Listen loop"
317
+ @events.unknown_error e, nil, "Listen loop"
313
318
  end
314
319
  end
315
320
 
@@ -322,10 +327,14 @@ module Puma
322
327
  end
323
328
  graceful_shutdown if @status == :stop || @status == :restart
324
329
  rescue Exception => e
325
- STDERR.puts "Exception handling servers: #{e.message} (#{e.class})"
326
- STDERR.puts e.backtrace
330
+ @events.unknown_error e, nil, "Exception handling servers"
327
331
  ensure
328
- @check.close unless @check.closed? # Ruby 2.2 issue
332
+ begin
333
+ @check.close unless @check.closed?
334
+ rescue Errno::EBADF, RuntimeError
335
+ # RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
336
+ # Errno::EBADF is infrequently raised
337
+ end
329
338
  @notify.close
330
339
  @notify = nil
331
340
  @check = nil
@@ -415,7 +424,7 @@ module Puma
415
424
 
416
425
  close_socket = true
417
426
 
418
- @events.ssl_error self, addr, cert, e
427
+ @events.ssl_error e, addr, cert
419
428
 
420
429
  # The client doesn't know HTTP well
421
430
  rescue HttpParserError => e
@@ -423,7 +432,7 @@ module Puma
423
432
 
424
433
  client.write_error(400)
425
434
 
426
- @events.parse_error self, client.env, e
435
+ @events.parse_error e, client
427
436
 
428
437
  # Server error
429
438
  rescue StandardError => e
@@ -431,8 +440,7 @@ module Puma
431
440
 
432
441
  client.write_error(500)
433
442
 
434
- @events.unknown_error self, e, "Read"
435
-
443
+ @events.unknown_error e, nil, "Read"
436
444
  ensure
437
445
  buffer.reset
438
446
 
@@ -442,7 +450,7 @@ module Puma
442
450
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
443
451
  # Already closed
444
452
  rescue StandardError => e
445
- @events.unknown_error self, e, "Client"
453
+ @events.unknown_error e, nil, "Client"
446
454
  end
447
455
  end
448
456
  end
@@ -478,7 +486,7 @@ module Puma
478
486
 
479
487
  env[PATH_INFO] = env[REQUEST_PATH]
480
488
 
481
- # From http://www.ietf.org/rfc/rfc3875 :
489
+ # From https://www.ietf.org/rfc/rfc3875 :
482
490
  # "Script authors should be aware that the REMOTE_ADDR and
483
491
  # REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
484
492
  # may not identify the ultimate source of the request.
@@ -567,12 +575,44 @@ module Puma
567
575
  end
568
576
 
569
577
  fast_write client, "\r\n".freeze
570
- rescue ConnectionError
578
+ rescue ConnectionError => e
579
+ @events.debug_error e
571
580
  # noop, if we lost the socket we just won't send the early hints
572
581
  end
573
582
  }
574
583
  end
575
584
 
585
+ # Fixup any headers with , in the name to have _ now. We emit
586
+ # headers with , in them during the parse phase to avoid ambiguity
587
+ # with the - to _ conversion for critical headers. But here for
588
+ # compatibility, we'll convert them back. This code is written to
589
+ # avoid allocation in the common case (ie there are no headers
590
+ # with , in their names), that's why it has the extra conditionals.
591
+
592
+ to_delete = nil
593
+ to_add = nil
594
+
595
+ env.each do |k,v|
596
+ if k.start_with?("HTTP_") and k.include?(",") and k != "HTTP_TRANSFER,ENCODING"
597
+ if to_delete
598
+ to_delete << k
599
+ else
600
+ to_delete = [k]
601
+ end
602
+
603
+ unless to_add
604
+ to_add = {}
605
+ end
606
+
607
+ to_add[k.tr(",", "_")] = v
608
+ end
609
+ end
610
+
611
+ if to_delete
612
+ to_delete.each { |k| env.delete(k) }
613
+ env.merge! to_add
614
+ end
615
+
576
616
  # A rack extension. If the app writes #call'ables to this
577
617
  # array, we will invoke them when the request is done.
578
618
  #
@@ -594,12 +634,12 @@ module Puma
594
634
  return :async
595
635
  end
596
636
  rescue ThreadPool::ForceShutdown => e
597
- @events.unknown_error self, e, "Rack app", env
637
+ @events.unknown_error e, req, "Rack app"
598
638
  @events.log "Detected force shutdown of a thread"
599
639
 
600
640
  status, headers, res_body = lowlevel_error(e, env, 503)
601
641
  rescue Exception => e
602
- @events.unknown_error self, e, "Rack app", env
642
+ @events.unknown_error e, req, "Rack app"
603
643
 
604
644
  status, headers, res_body = lowlevel_error(e, env, 500)
605
645
  end
@@ -889,7 +929,7 @@ module Puma
889
929
  @check, @notify = Puma::Util.pipe unless @notify
890
930
  begin
891
931
  @notify << message
892
- rescue IOError
932
+ rescue IOError, NoMethodError, Errno::EPIPE
893
933
  # The server, in another thread, is shutting down
894
934
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
895
935
  rescue RuntimeError => e
@@ -19,7 +19,7 @@ module Puma
19
19
  @options = YAML.load File.read(path)
20
20
  end
21
21
 
22
- FIELDS = %w!control_url control_auth_token pid!
22
+ FIELDS = %w!control_url control_auth_token pid running_from!
23
23
 
24
24
  FIELDS.each do |f|
25
25
  define_method f do
@@ -122,8 +122,11 @@ module Puma
122
122
  @out_of_band_pending = false
123
123
  end
124
124
  not_full.signal
125
- not_empty.wait mutex
126
- @waiting -= 1
125
+ begin
126
+ not_empty.wait mutex
127
+ ensure
128
+ @waiting -= 1
129
+ end
127
130
  end
128
131
 
129
132
  work = todo.shift
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.beta1
4
+ version: 5.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-12 00:00:00.000000000 Z
11
+ date: 2020-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nio4r
@@ -87,6 +87,7 @@ files:
87
87
  - lib/puma/control_cli.rb
88
88
  - lib/puma/detect.rb
89
89
  - lib/puma/dsl.rb
90
+ - lib/puma/error_logger.rb
90
91
  - lib/puma/events.rb
91
92
  - lib/puma/io_buffer.rb
92
93
  - lib/puma/jruby_restart.rb
@@ -109,15 +110,15 @@ files:
109
110
  - lib/rack/handler/puma.rb
110
111
  - tools/Dockerfile
111
112
  - tools/trickletest.rb
112
- homepage: http://puma.io
113
+ homepage: https://puma.io
113
114
  licenses:
114
115
  - BSD-3-Clause
115
116
  metadata:
116
117
  bug_tracker_uri: https://github.com/puma/puma/issues
117
118
  changelog_uri: https://github.com/puma/puma/blob/master/History.md
118
- homepage_uri: http://puma.io
119
+ homepage_uri: https://puma.io
119
120
  source_code_uri: https://github.com/puma/puma
120
- post_install_message:
121
+ post_install_message:
121
122
  rdoc_options: []
122
123
  require_paths:
123
124
  - lib
@@ -133,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
134
  version: 1.3.1
134
135
  requirements: []
135
136
  rubygems_version: 3.1.2
136
- signing_key:
137
+ signing_key:
137
138
  specification_version: 4
138
139
  summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
139
140
  Ruby/Rack applications