puma 3.12.1 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +47 -5
- data/README.md +29 -9
- data/docs/architecture.md +1 -0
- data/docs/deployment.md +24 -4
- data/docs/restart.md +4 -2
- data/docs/systemd.md +27 -9
- data/ext/puma_http11/PumaHttp11Service.java +2 -0
- data/ext/puma_http11/extconf.rb +8 -0
- data/ext/puma_http11/mini_ssl.c +26 -4
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +11 -4
- data/lib/puma/app/status.rb +3 -2
- data/lib/puma/binder.rb +10 -1
- data/lib/puma/client.rb +43 -25
- data/lib/puma/cluster.rb +38 -14
- data/lib/puma/configuration.rb +2 -1
- data/lib/puma/const.rb +6 -2
- data/lib/puma/control_cli.rb +10 -0
- data/lib/puma/dsl.rb +45 -3
- data/lib/puma/io_buffer.rb +1 -6
- data/lib/puma/launcher.rb +12 -13
- data/lib/puma/minissl.rb +13 -1
- data/lib/puma/reactor.rb +104 -53
- data/lib/puma/runner.rb +1 -1
- data/lib/puma/server.rb +25 -24
- data/lib/puma/single.rb +2 -2
- data/lib/puma/thread_pool.rb +5 -1
- data/lib/puma/util.rb +1 -6
- data/tools/jungle/init.d/puma +5 -5
- metadata +22 -11
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/java_io_buffer.rb +0 -47
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
data/lib/puma/runner.rb
CHANGED
@@ -55,7 +55,7 @@ module Puma
|
|
55
55
|
app = Puma::App::Status.new @launcher
|
56
56
|
|
57
57
|
if token = @options[:control_auth_token]
|
58
|
-
app.auth_token = token unless token.empty?
|
58
|
+
app.auth_token = token unless token.empty? || token == 'none'
|
59
59
|
end
|
60
60
|
|
61
61
|
control = Puma::Server.new app, @launcher.events
|
data/lib/puma/server.rb
CHANGED
@@ -6,7 +6,6 @@ require 'puma/thread_pool'
|
|
6
6
|
require 'puma/const'
|
7
7
|
require 'puma/events'
|
8
8
|
require 'puma/null_io'
|
9
|
-
require 'puma/compat'
|
10
9
|
require 'puma/reactor'
|
11
10
|
require 'puma/client'
|
12
11
|
require 'puma/binder'
|
@@ -16,10 +15,6 @@ require 'puma/util'
|
|
16
15
|
|
17
16
|
require 'puma/puma_http11'
|
18
17
|
|
19
|
-
unless Puma.const_defined? "IOBuffer"
|
20
|
-
require 'puma/io_buffer'
|
21
|
-
end
|
22
|
-
|
23
18
|
require 'socket'
|
24
19
|
|
25
20
|
module Puma
|
@@ -28,7 +23,7 @@ module Puma
|
|
28
23
|
#
|
29
24
|
# This class is used by the `Puma::Single` and `Puma::Cluster` classes
|
30
25
|
# to generate one or more `Puma::Server` instances capable of handling requests.
|
31
|
-
# Each Puma process will contain one `Puma::Server`
|
26
|
+
# Each Puma process will contain one `Puma::Server` instance.
|
32
27
|
#
|
33
28
|
# The `Puma::Server` instance pulls requests from the socket, adds them to a
|
34
29
|
# `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`.
|
@@ -79,7 +74,6 @@ module Puma
|
|
79
74
|
@first_data_timeout = options.fetch(:first_data_timeout, FIRST_DATA_TIMEOUT)
|
80
75
|
|
81
76
|
@binder = Binder.new(events)
|
82
|
-
@own_binder = true
|
83
77
|
|
84
78
|
@leak_stack_on_error = true
|
85
79
|
|
@@ -102,7 +96,6 @@ module Puma
|
|
102
96
|
|
103
97
|
def inherit_binder(bind)
|
104
98
|
@binder = bind
|
105
|
-
@own_binder = false
|
106
99
|
end
|
107
100
|
|
108
101
|
def tcp_mode!
|
@@ -270,10 +263,11 @@ module Puma
|
|
270
263
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
271
264
|
end
|
272
265
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
266
|
+
# Prevent can't modify frozen IOError (RuntimeError)
|
267
|
+
begin
|
268
|
+
@notify.close
|
269
|
+
rescue IOError
|
270
|
+
# no biggy
|
277
271
|
end
|
278
272
|
end
|
279
273
|
|
@@ -398,7 +392,10 @@ module Puma
|
|
398
392
|
end
|
399
393
|
|
400
394
|
pool << client
|
401
|
-
pool.wait_until_not_full
|
395
|
+
busy_threads = pool.wait_until_not_full
|
396
|
+
if busy_threads == 0
|
397
|
+
@options[:out_of_band].each(&:call) if @options[:out_of_band]
|
398
|
+
end
|
402
399
|
end
|
403
400
|
rescue SystemCallError
|
404
401
|
# nothing
|
@@ -430,10 +427,6 @@ module Puma
|
|
430
427
|
ensure
|
431
428
|
@check.close
|
432
429
|
@notify.close
|
433
|
-
|
434
|
-
if @status != :restart and @own_binder
|
435
|
-
@binder.close
|
436
|
-
end
|
437
430
|
end
|
438
431
|
|
439
432
|
@events.fire :state, :done
|
@@ -599,15 +592,19 @@ module Puma
|
|
599
592
|
env['HTTP_X_FORWARDED_PROTO'] == 'https' ? PORT_443 : PORT_80
|
600
593
|
end
|
601
594
|
|
602
|
-
#
|
603
|
-
#
|
604
|
-
#
|
605
|
-
# +
|
595
|
+
# Takes the request +req+, invokes the Rack application to construct
|
596
|
+
# the response and writes it back to +req.io+.
|
597
|
+
#
|
598
|
+
# The second parameter +lines+ is a IO-like object unique to this thread.
|
599
|
+
# This is normally an instance of Puma::IOBuffer.
|
606
600
|
#
|
607
|
-
# +
|
608
|
-
#
|
609
|
-
# it up again.
|
601
|
+
# It'll return +false+ when the connection is closed, this doesn't mean
|
602
|
+
# that the response wasn't successful.
|
610
603
|
#
|
604
|
+
# It'll return +:async+ if the connection remains open but will be handled
|
605
|
+
# elsewhere, i.e. the connection has been hijacked by the Rack application.
|
606
|
+
#
|
607
|
+
# Finally, it'll return +true+ on keep-alive connections.
|
611
608
|
def handle_request(req, lines)
|
612
609
|
env = req.env
|
613
610
|
client = req.io
|
@@ -942,6 +939,10 @@ module Puma
|
|
942
939
|
@events.debug "Drained #{count} additional connections."
|
943
940
|
end
|
944
941
|
|
942
|
+
if @status != :restart
|
943
|
+
@binder.close
|
944
|
+
end
|
945
|
+
|
945
946
|
if @thread_pool
|
946
947
|
if timeout = @options[:force_shutdown_after]
|
947
948
|
@thread_pool.shutdown timeout.to_i
|
data/lib/puma/single.rb
CHANGED
@@ -26,7 +26,7 @@ module Puma
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def stop
|
29
|
-
@server.stop
|
29
|
+
@server.stop(false) if @server
|
30
30
|
end
|
31
31
|
|
32
32
|
def halt
|
@@ -36,7 +36,7 @@ module Puma
|
|
36
36
|
def stop_blocked
|
37
37
|
log "- Gracefully stopping, waiting for requests to finish"
|
38
38
|
@control.stop(true) if @control
|
39
|
-
@server.stop(true)
|
39
|
+
@server.stop(true) if @server
|
40
40
|
end
|
41
41
|
|
42
42
|
def jruby_daemon?
|
data/lib/puma/thread_pool.rb
CHANGED
@@ -194,6 +194,9 @@ module Puma
|
|
194
194
|
# method would not block and another request would be added into the reactor
|
195
195
|
# by the server. This would continue until a fully bufferend request
|
196
196
|
# makes it through the reactor and can then be processed by the thread pool.
|
197
|
+
#
|
198
|
+
# Returns the current number of busy threads, or +nil+ if shutting down.
|
199
|
+
#
|
197
200
|
def wait_until_not_full
|
198
201
|
@mutex.synchronize do
|
199
202
|
while true
|
@@ -203,7 +206,8 @@ module Puma
|
|
203
206
|
# is work queued that cannot be handled by waiting
|
204
207
|
# threads, then accept more work until we would
|
205
208
|
# spin up the max number of threads.
|
206
|
-
|
209
|
+
busy_threads = @spawned - @waiting + @todo.size
|
210
|
+
return busy_threads if @max > busy_threads
|
207
211
|
|
208
212
|
@not_full.wait @mutex
|
209
213
|
end
|
data/lib/puma/util.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
major, minor, patch = RUBY_VERSION.split('.').map { |v| v.to_i }
|
3
2
|
|
4
|
-
|
5
|
-
require 'puma/rack/backports/uri/common_193'
|
6
|
-
else
|
7
|
-
require 'uri/common'
|
8
|
-
end
|
3
|
+
require 'uri/common'
|
9
4
|
|
10
5
|
module Puma
|
11
6
|
module Util
|
data/tools/jungle/init.d/puma
CHANGED
@@ -47,11 +47,11 @@ do_start_one() {
|
|
47
47
|
PIDFILE=$1/tmp/puma/pid
|
48
48
|
if [ -e $PIDFILE ]; then
|
49
49
|
PID=`cat $PIDFILE`
|
50
|
-
# If the puma
|
50
|
+
# If the puma is running, restart it, otherwise run it.
|
51
51
|
if ps -p $PID > /dev/null; then
|
52
|
-
do_start_one_do $1
|
53
|
-
else
|
54
52
|
do_restart_one $1
|
53
|
+
else
|
54
|
+
do_start_one_do $1
|
55
55
|
fi
|
56
56
|
else
|
57
57
|
do_start_one_do $1
|
@@ -106,8 +106,6 @@ do_stop_one() {
|
|
106
106
|
if [ -e $PIDFILE ]; then
|
107
107
|
PID=`cat $PIDFILE`
|
108
108
|
if ps -p $PID > /dev/null; then
|
109
|
-
log_daemon_msg "---> Puma $1 isn't running."
|
110
|
-
else
|
111
109
|
log_daemon_msg "---> About to kill PID `cat $PIDFILE`"
|
112
110
|
if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
|
113
111
|
cd $1 && bundle exec pumactl --state $STATEFILE stop
|
@@ -116,6 +114,8 @@ do_stop_one() {
|
|
116
114
|
fi
|
117
115
|
# Many daemons don't delete their pidfiles when they exit.
|
118
116
|
rm -f $PIDFILE $STATEFILE
|
117
|
+
else
|
118
|
+
log_daemon_msg "---> Puma $1 isn't running."
|
119
119
|
fi
|
120
120
|
else
|
121
121
|
log_daemon_msg "---> No puma here..."
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.1
|
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: 2019-
|
12
|
-
dependencies:
|
11
|
+
date: 2019-07-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nio4r
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
13
27
|
description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
|
14
28
|
for Ruby/Rack applications. Puma is intended for use in both development and production
|
15
29
|
environments. It's great for highly concurrent Ruby implementations such as Rubinius
|
@@ -51,6 +65,7 @@ files:
|
|
51
65
|
- ext/puma_http11/mini_ssl.c
|
52
66
|
- ext/puma_http11/org/jruby/puma/Http11.java
|
53
67
|
- ext/puma_http11/org/jruby/puma/Http11Parser.java
|
68
|
+
- ext/puma_http11/org/jruby/puma/IOBuffer.java
|
54
69
|
- ext/puma_http11/org/jruby/puma/MiniSSL.java
|
55
70
|
- ext/puma_http11/puma_http11.c
|
56
71
|
- lib/puma.rb
|
@@ -61,7 +76,6 @@ files:
|
|
61
76
|
- lib/puma/client.rb
|
62
77
|
- lib/puma/cluster.rb
|
63
78
|
- lib/puma/commonlogger.rb
|
64
|
-
- lib/puma/compat.rb
|
65
79
|
- lib/puma/configuration.rb
|
66
80
|
- lib/puma/const.rb
|
67
81
|
- lib/puma/control_cli.rb
|
@@ -72,14 +86,12 @@ files:
|
|
72
86
|
- lib/puma/dsl.rb
|
73
87
|
- lib/puma/events.rb
|
74
88
|
- lib/puma/io_buffer.rb
|
75
|
-
- lib/puma/java_io_buffer.rb
|
76
89
|
- lib/puma/jruby_restart.rb
|
77
90
|
- lib/puma/launcher.rb
|
78
91
|
- lib/puma/minissl.rb
|
79
92
|
- lib/puma/null_io.rb
|
80
93
|
- lib/puma/plugin.rb
|
81
94
|
- lib/puma/plugin/tmp_restart.rb
|
82
|
-
- lib/puma/rack/backports/uri/common_193.rb
|
83
95
|
- lib/puma/rack/builder.rb
|
84
96
|
- lib/puma/rack/urlmap.rb
|
85
97
|
- lib/puma/rack_default.rb
|
@@ -108,7 +120,7 @@ licenses:
|
|
108
120
|
- BSD-3-Clause
|
109
121
|
metadata:
|
110
122
|
msys2_mingw_dependencies: openssl
|
111
|
-
post_install_message:
|
123
|
+
post_install_message:
|
112
124
|
rdoc_options: []
|
113
125
|
require_paths:
|
114
126
|
- lib
|
@@ -123,9 +135,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
135
|
- !ruby/object:Gem::Version
|
124
136
|
version: '0'
|
125
137
|
requirements: []
|
126
|
-
|
127
|
-
|
128
|
-
signing_key:
|
138
|
+
rubygems_version: 3.0.3
|
139
|
+
signing_key:
|
129
140
|
specification_version: 4
|
130
141
|
summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
|
131
142
|
Ruby/Rack applications
|
data/lib/puma/compat.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# Provides code to work properly on 1.8 and 1.9
|
2
|
-
|
3
|
-
class String
|
4
|
-
unless method_defined? :bytesize
|
5
|
-
alias_method :bytesize, :size
|
6
|
-
end
|
7
|
-
|
8
|
-
unless method_defined? :byteslice
|
9
|
-
def byteslice(*arg)
|
10
|
-
enc = self.encoding
|
11
|
-
self.dup.force_encoding(Encoding::ASCII_8BIT).slice(*arg).force_encoding(enc)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
data/lib/puma/java_io_buffer.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'java'
|
4
|
-
|
5
|
-
# Conservative native JRuby/Java implementation of IOBuffer
|
6
|
-
# backed by a ByteArrayOutputStream and conversion between
|
7
|
-
# Ruby String and Java bytes
|
8
|
-
module Puma
|
9
|
-
class JavaIOBuffer < java.io.ByteArrayOutputStream
|
10
|
-
field_reader :buf
|
11
|
-
end
|
12
|
-
|
13
|
-
class IOBuffer
|
14
|
-
BUF_DEFAULT_SIZE = 4096
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@buf = JavaIOBuffer.new(BUF_DEFAULT_SIZE)
|
18
|
-
end
|
19
|
-
|
20
|
-
def reset
|
21
|
-
@buf.reset
|
22
|
-
end
|
23
|
-
|
24
|
-
def <<(str)
|
25
|
-
bytes = str.to_java_bytes
|
26
|
-
@buf.write(bytes, 0, bytes.length)
|
27
|
-
end
|
28
|
-
|
29
|
-
def append(*strs)
|
30
|
-
strs.each { |s| self << s; }
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_s
|
34
|
-
String.from_java_bytes @buf.to_byte_array
|
35
|
-
end
|
36
|
-
|
37
|
-
alias_method :to_str, :to_s
|
38
|
-
|
39
|
-
def used
|
40
|
-
@buf.size
|
41
|
-
end
|
42
|
-
|
43
|
-
def capacity
|
44
|
-
@buf.buf.length
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# :stopdoc:
|
2
|
-
|
3
|
-
require 'uri/common'
|
4
|
-
|
5
|
-
# Issue:
|
6
|
-
# http://bugs.ruby-lang.org/issues/5925
|
7
|
-
#
|
8
|
-
# Relevant commit:
|
9
|
-
# https://github.com/ruby/ruby/commit/edb7cdf1eabaff78dfa5ffedfbc2e91b29fa9ca1
|
10
|
-
|
11
|
-
|
12
|
-
module URI
|
13
|
-
begin
|
14
|
-
256.times do |i|
|
15
|
-
TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
|
16
|
-
end
|
17
|
-
TBLENCWWWCOMP_[' '] = '+'
|
18
|
-
TBLENCWWWCOMP_.freeze
|
19
|
-
|
20
|
-
256.times do |i|
|
21
|
-
h, l = i>>4, i&15
|
22
|
-
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
|
23
|
-
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
|
24
|
-
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
|
25
|
-
TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
|
26
|
-
end
|
27
|
-
TBLDECWWWCOMP_['+'] = ' '
|
28
|
-
TBLDECWWWCOMP_.freeze
|
29
|
-
rescue Exception
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# :startdoc:
|