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.
- checksums.yaml +4 -4
- data/History.md +23 -1
- data/README.md +3 -3
- data/docs/architecture.md +3 -3
- data/docs/deployment.md +6 -2
- data/docs/signals.md +4 -4
- data/ext/puma_http11/http11_parser.c +3 -1
- data/ext/puma_http11/http11_parser.rl +3 -1
- data/ext/puma_http11/mini_ssl.c +12 -2
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +37 -6
- data/ext/puma_http11/puma_http11.c +1 -1
- data/lib/puma.rb +1 -0
- data/lib/puma/app/status.rb +4 -2
- data/lib/puma/binder.rb +5 -4
- data/lib/puma/client.rb +36 -9
- data/lib/puma/cluster.rb +8 -4
- data/lib/puma/commonlogger.rb +2 -2
- data/lib/puma/const.rb +1 -1
- data/lib/puma/dsl.rb +3 -3
- data/lib/puma/error_logger.rb +96 -0
- data/lib/puma/events.rb +33 -31
- data/lib/puma/launcher.rb +5 -2
- data/lib/puma/minissl.rb +34 -2
- data/lib/puma/reactor.rb +2 -2
- data/lib/puma/runner.rb +1 -1
- data/lib/puma/server.rb +84 -44
- data/lib/puma/state_file.rb +1 -1
- data/lib/puma/thread_pool.rb +5 -2
- metadata +8 -7
data/lib/puma/server.rb
CHANGED
@@ -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
|
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(
|
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(
|
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
|
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
|
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
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
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
|
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
|
-
|
326
|
-
STDERR.puts e.backtrace
|
330
|
+
@events.unknown_error e, nil, "Exception handling servers"
|
327
331
|
ensure
|
328
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
data/lib/puma/state_file.rb
CHANGED
data/lib/puma/thread_pool.rb
CHANGED
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.
|
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
|
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:
|
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:
|
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
|