puma 3.12.1 → 5.6.4
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 +1553 -447
- data/LICENSE +23 -20
- data/README.md +175 -63
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +59 -21
- data/docs/compile_options.md +21 -0
- data/docs/deployment.md +69 -58
- data/docs/fork_worker.md +33 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/jungle/README.md +9 -0
- data/{tools → docs}/jungle/rc.d/README.md +1 -1
- data/{tools → docs}/jungle/rc.d/puma +2 -2
- data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +22 -12
- data/docs/rails_dev_mode.md +28 -0
- data/docs/restart.md +47 -22
- data/docs/signals.md +13 -11
- data/docs/stats.md +142 -0
- data/docs/systemd.md +95 -120
- data/ext/puma_http11/PumaHttp11Service.java +2 -2
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +51 -1
- data/ext/puma_http11/http11_parser.c +105 -117
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +22 -38
- data/ext/puma_http11/http11_parser.rl +4 -2
- data/ext/puma_http11/http11_parser_common.rl +4 -4
- data/ext/puma_http11/mini_ssl.c +319 -96
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +108 -116
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +84 -99
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +120 -65
- data/ext/puma_http11/puma_http11.c +35 -51
- data/lib/puma/app/status.rb +68 -49
- data/lib/puma/binder.rb +234 -137
- data/lib/puma/cli.rb +28 -18
- data/lib/puma/client.rb +343 -230
- data/lib/puma/cluster/worker.rb +173 -0
- data/lib/puma/cluster/worker_handle.rb +94 -0
- data/lib/puma/cluster.rb +247 -232
- data/lib/puma/commonlogger.rb +2 -2
- data/lib/puma/configuration.rb +61 -51
- data/lib/puma/const.rb +42 -21
- data/lib/puma/control_cli.rb +109 -67
- data/lib/puma/detect.rb +29 -2
- data/lib/puma/dsl.rb +615 -123
- data/lib/puma/error_logger.rb +104 -0
- data/lib/puma/events.rb +55 -31
- data/lib/puma/io_buffer.rb +7 -5
- data/lib/puma/jruby_restart.rb +0 -58
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher.rb +182 -69
- data/lib/puma/minissl/context_builder.rb +81 -0
- data/lib/puma/minissl.rb +161 -61
- data/lib/puma/null_io.rb +13 -1
- data/lib/puma/plugin/tmp_restart.rb +2 -0
- data/lib/puma/plugin.rb +7 -13
- data/lib/puma/queue_close.rb +26 -0
- data/lib/puma/rack/builder.rb +3 -5
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +2 -0
- data/lib/puma/reactor.rb +85 -316
- data/lib/puma/request.rb +472 -0
- data/lib/puma/runner.rb +48 -55
- data/lib/puma/server.rb +303 -695
- data/lib/puma/single.rb +11 -67
- data/lib/puma/state_file.rb +47 -8
- data/lib/puma/systemd.rb +46 -0
- data/lib/puma/thread_pool.rb +132 -82
- data/lib/puma/util.rb +21 -7
- data/lib/puma.rb +54 -0
- data/lib/rack/handler/puma.rb +5 -6
- data/tools/Dockerfile +16 -0
- data/tools/trickletest.rb +0 -1
- metadata +45 -29
- data/ext/puma_http11/io_buffer.c +0 -155
- data/lib/puma/accept_nonblock.rb +0 -23
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/convenient.rb +0 -25
- data/lib/puma/daemon_ext.rb +0 -33
- data/lib/puma/delegation.rb +0 -13
- data/lib/puma/java_io_buffer.rb +0 -47
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
- data/lib/puma/tcp_logger.rb +0 -41
- data/tools/jungle/README.md +0 -19
- data/tools/jungle/init.d/README.md +0 -61
- data/tools/jungle/init.d/puma +0 -421
- data/tools/jungle/init.d/run-puma +0 -18
- data/tools/jungle/upstart/README.md +0 -61
- data/tools/jungle/upstart/puma-manager.conf +0 -31
- data/tools/jungle/upstart/puma.conf +0 -69
data/lib/puma/minissl.rb
CHANGED
@@ -2,11 +2,21 @@
|
|
2
2
|
|
3
3
|
begin
|
4
4
|
require 'io/wait'
|
5
|
-
|
5
|
+
rescue LoadError
|
6
6
|
end
|
7
7
|
|
8
|
+
# need for Puma::MiniSSL::OPENSSL constants used in `HAS_TLS1_3`
|
9
|
+
require 'puma/puma_http11'
|
10
|
+
|
8
11
|
module Puma
|
9
12
|
module MiniSSL
|
13
|
+
# Define constant at runtime, as it's easy to determine at built time,
|
14
|
+
# but Puma could (it shouldn't) be loaded with an older OpenSSL version
|
15
|
+
# @version 5.0.0
|
16
|
+
HAS_TLS1_3 = !IS_JRUBY &&
|
17
|
+
(OPENSSL_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) != -1 &&
|
18
|
+
(OPENSSL_LIBRARY_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) !=-1
|
19
|
+
|
10
20
|
class Socket
|
11
21
|
def initialize(socket, engine)
|
12
22
|
@socket = socket
|
@@ -14,6 +24,7 @@ module Puma
|
|
14
24
|
@peercert = nil
|
15
25
|
end
|
16
26
|
|
27
|
+
# @!attribute [r] to_io
|
17
28
|
def to_io
|
18
29
|
@socket
|
19
30
|
end
|
@@ -22,6 +33,27 @@ module Puma
|
|
22
33
|
@socket.closed?
|
23
34
|
end
|
24
35
|
|
36
|
+
# Returns a two element array,
|
37
|
+
# first is protocol version (SSL_get_version),
|
38
|
+
# second is 'handshake' state (SSL_state_string)
|
39
|
+
#
|
40
|
+
# Used for dropping tcp connections to ssl.
|
41
|
+
# See OpenSSL ssl/ssl_stat.c SSL_state_string for info
|
42
|
+
# @!attribute [r] ssl_version_state
|
43
|
+
# @version 5.0.0
|
44
|
+
#
|
45
|
+
def ssl_version_state
|
46
|
+
IS_JRUBY ? [nil, nil] : @engine.ssl_vers_st
|
47
|
+
end
|
48
|
+
|
49
|
+
# Used to check the handshake status, in particular when a TCP connection
|
50
|
+
# is made with TLSv1.3 as an available protocol
|
51
|
+
# @version 5.0.0
|
52
|
+
def bad_tlsv1_3?
|
53
|
+
HAS_TLS1_3 && @engine.ssl_vers_st == ['TLSv1.3', 'SSLERR']
|
54
|
+
end
|
55
|
+
private :bad_tlsv1_3?
|
56
|
+
|
25
57
|
def readpartial(size)
|
26
58
|
while true
|
27
59
|
output = @engine.read
|
@@ -54,22 +86,22 @@ module Puma
|
|
54
86
|
output = engine_read_all
|
55
87
|
return output if output
|
56
88
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
89
|
+
data = @socket.read_nonblock(size, exception: false)
|
90
|
+
if data == :wait_readable || data == :wait_writable
|
91
|
+
# It would make more sense to let @socket.read_nonblock raise
|
92
|
+
# EAGAIN if necessary but it seems like it'll misbehave on Windows.
|
93
|
+
# I don't have a Windows machine to debug this so I can't explain
|
94
|
+
# exactly whats happening in that OS. Please let me know if you
|
95
|
+
# find out!
|
96
|
+
#
|
97
|
+
# In the meantime, we can emulate the correct behavior by
|
98
|
+
# capturing :wait_readable & :wait_writable and raising EAGAIN
|
99
|
+
# ourselves.
|
100
|
+
raise IO::EAGAINWaitReadable
|
101
|
+
elsif data.nil?
|
102
|
+
raise SSLError.exception "HTTP connection?" if bad_tlsv1_3?
|
103
|
+
return nil
|
104
|
+
end
|
73
105
|
|
74
106
|
@engine.inject(data)
|
75
107
|
output = engine_read_all
|
@@ -85,22 +117,23 @@ module Puma
|
|
85
117
|
def write(data)
|
86
118
|
return 0 if data.empty?
|
87
119
|
|
88
|
-
|
120
|
+
data_size = data.bytesize
|
121
|
+
need = data_size
|
89
122
|
|
90
123
|
while true
|
91
124
|
wrote = @engine.write data
|
92
|
-
enc = @engine.extract
|
93
125
|
|
94
|
-
|
95
|
-
|
96
|
-
|
126
|
+
enc_wr = ''.dup
|
127
|
+
while (enc = @engine.extract)
|
128
|
+
enc_wr << enc
|
97
129
|
end
|
130
|
+
@socket.write enc_wr unless enc_wr.empty?
|
98
131
|
|
99
132
|
need -= wrote
|
100
133
|
|
101
|
-
return
|
134
|
+
return data_size if need == 0
|
102
135
|
|
103
|
-
data = data
|
136
|
+
data = data.byteslice(wrote..-1)
|
104
137
|
end
|
105
138
|
end
|
106
139
|
|
@@ -108,14 +141,18 @@ module Puma
|
|
108
141
|
alias_method :<<, :write
|
109
142
|
|
110
143
|
# This is a temporary fix to deal with websockets code using
|
111
|
-
# write_nonblock.
|
144
|
+
# write_nonblock.
|
145
|
+
|
146
|
+
# The problem with implementing it properly
|
112
147
|
# is that it means we'd have to have the ability to rewind
|
113
148
|
# an engine because after we write+extract, the socket
|
114
149
|
# write_nonblock call might raise an exception and later
|
115
150
|
# code would pass the same data in, but the engine would think
|
116
|
-
# it had already written the data in.
|
117
|
-
#
|
118
|
-
#
|
151
|
+
# it had already written the data in.
|
152
|
+
#
|
153
|
+
# So for the time being (and since write blocking is quite rare),
|
154
|
+
# go ahead and actually block in write_nonblock.
|
155
|
+
#
|
119
156
|
def write_nonblock(data, *_)
|
120
157
|
write data
|
121
158
|
end
|
@@ -124,39 +161,27 @@ module Puma
|
|
124
161
|
@socket.flush
|
125
162
|
end
|
126
163
|
|
127
|
-
def read_and_drop(timeout = 1)
|
128
|
-
return :timeout unless IO.select([@socket], nil, nil, timeout)
|
129
|
-
return :eof unless read_nonblock(1024)
|
130
|
-
:drop
|
131
|
-
rescue Errno::EAGAIN
|
132
|
-
# do nothing
|
133
|
-
:eagain
|
134
|
-
end
|
135
|
-
|
136
|
-
def should_drop_bytes?
|
137
|
-
@engine.init? || !@engine.shutdown
|
138
|
-
end
|
139
|
-
|
140
164
|
def close
|
141
165
|
begin
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
return if [:timeout, :eof].include?(read_and_drop(1))
|
166
|
+
unless @engine.shutdown
|
167
|
+
while alert_data = @engine.extract
|
168
|
+
@socket.write alert_data
|
169
|
+
end
|
147
170
|
end
|
148
171
|
rescue IOError, SystemCallError
|
149
|
-
|
172
|
+
Puma::Util.purge_interrupt_queue
|
150
173
|
# nothing
|
151
174
|
ensure
|
152
175
|
@socket.close
|
153
176
|
end
|
154
177
|
end
|
155
178
|
|
179
|
+
# @!attribute [r] peeraddr
|
156
180
|
def peeraddr
|
157
181
|
@socket.peeraddr
|
158
182
|
end
|
159
183
|
|
184
|
+
# @!attribute [r] peercert
|
160
185
|
def peercert
|
161
186
|
return @peercert if @peercert
|
162
187
|
|
@@ -167,18 +192,29 @@ module Puma
|
|
167
192
|
end
|
168
193
|
end
|
169
194
|
|
170
|
-
if
|
195
|
+
if IS_JRUBY
|
196
|
+
OPENSSL_NO_SSL3 = false
|
197
|
+
OPENSSL_NO_TLS1 = false
|
198
|
+
|
171
199
|
class SSLError < StandardError
|
172
200
|
# Define this for jruby even though it isn't used.
|
173
201
|
end
|
174
|
-
|
175
|
-
def self.check; end
|
176
202
|
end
|
177
203
|
|
178
204
|
class Context
|
179
205
|
attr_accessor :verify_mode
|
206
|
+
attr_reader :no_tlsv1, :no_tlsv1_1
|
207
|
+
|
208
|
+
def initialize
|
209
|
+
@no_tlsv1 = false
|
210
|
+
@no_tlsv1_1 = false
|
211
|
+
@key = nil
|
212
|
+
@cert = nil
|
213
|
+
@key_pem = nil
|
214
|
+
@cert_pem = nil
|
215
|
+
end
|
180
216
|
|
181
|
-
if
|
217
|
+
if IS_JRUBY
|
182
218
|
# jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair
|
183
219
|
attr_reader :keystore
|
184
220
|
attr_accessor :keystore_pass
|
@@ -198,7 +234,10 @@ module Puma
|
|
198
234
|
attr_reader :key
|
199
235
|
attr_reader :cert
|
200
236
|
attr_reader :ca
|
237
|
+
attr_reader :cert_pem
|
238
|
+
attr_reader :key_pem
|
201
239
|
attr_accessor :ssl_cipher_filter
|
240
|
+
attr_accessor :verification_flags
|
202
241
|
|
203
242
|
def key=(key)
|
204
243
|
raise ArgumentError, "No such key file '#{key}'" unless File.exist? key
|
@@ -215,46 +254,107 @@ module Puma
|
|
215
254
|
@ca = ca
|
216
255
|
end
|
217
256
|
|
257
|
+
def cert_pem=(cert_pem)
|
258
|
+
raise ArgumentError, "'cert_pem' is not a String" unless cert_pem.is_a? String
|
259
|
+
@cert_pem = cert_pem
|
260
|
+
end
|
261
|
+
|
262
|
+
def key_pem=(key_pem)
|
263
|
+
raise ArgumentError, "'key_pem' is not a String" unless key_pem.is_a? String
|
264
|
+
@key_pem = key_pem
|
265
|
+
end
|
266
|
+
|
218
267
|
def check
|
219
|
-
raise "Key not configured"
|
220
|
-
raise "Cert not configured"
|
268
|
+
raise "Key not configured" if @key.nil? && @key_pem.nil?
|
269
|
+
raise "Cert not configured" if @cert.nil? && @cert_pem.nil?
|
221
270
|
end
|
222
271
|
end
|
272
|
+
|
273
|
+
# disables TLSv1
|
274
|
+
# @!attribute [w] no_tlsv1=
|
275
|
+
def no_tlsv1=(tlsv1)
|
276
|
+
raise ArgumentError, "Invalid value of no_tlsv1=" unless ['true', 'false', true, false].include?(tlsv1)
|
277
|
+
@no_tlsv1 = tlsv1
|
278
|
+
end
|
279
|
+
|
280
|
+
# disables TLSv1 and TLSv1.1. Overrides `#no_tlsv1=`
|
281
|
+
# @!attribute [w] no_tlsv1_1=
|
282
|
+
def no_tlsv1_1=(tlsv1_1)
|
283
|
+
raise ArgumentError, "Invalid value of no_tlsv1_1=" unless ['true', 'false', true, false].include?(tlsv1_1)
|
284
|
+
@no_tlsv1_1 = tlsv1_1
|
285
|
+
end
|
286
|
+
|
223
287
|
end
|
224
288
|
|
225
289
|
VERIFY_NONE = 0
|
226
290
|
VERIFY_PEER = 1
|
227
291
|
VERIFY_FAIL_IF_NO_PEER_CERT = 2
|
228
292
|
|
293
|
+
# https://github.com/openssl/openssl/blob/master/include/openssl/x509_vfy.h.in
|
294
|
+
# /* Certificate verify flags */
|
295
|
+
VERIFICATION_FLAGS = {
|
296
|
+
"USE_CHECK_TIME" => 0x2,
|
297
|
+
"CRL_CHECK" => 0x4,
|
298
|
+
"CRL_CHECK_ALL" => 0x8,
|
299
|
+
"IGNORE_CRITICAL" => 0x10,
|
300
|
+
"X509_STRICT" => 0x20,
|
301
|
+
"ALLOW_PROXY_CERTS" => 0x40,
|
302
|
+
"POLICY_CHECK" => 0x80,
|
303
|
+
"EXPLICIT_POLICY" => 0x100,
|
304
|
+
"INHIBIT_ANY" => 0x200,
|
305
|
+
"INHIBIT_MAP" => 0x400,
|
306
|
+
"NOTIFY_POLICY" => 0x800,
|
307
|
+
"EXTENDED_CRL_SUPPORT" => 0x1000,
|
308
|
+
"USE_DELTAS" => 0x2000,
|
309
|
+
"CHECK_SS_SIGNATURE" => 0x4000,
|
310
|
+
"TRUSTED_FIRST" => 0x8000,
|
311
|
+
"SUITEB_128_LOS_ONLY" => 0x10000,
|
312
|
+
"SUITEB_192_LOS" => 0x20000,
|
313
|
+
"SUITEB_128_LOS" => 0x30000,
|
314
|
+
"PARTIAL_CHAIN" => 0x80000,
|
315
|
+
"NO_ALT_CHAINS" => 0x100000,
|
316
|
+
"NO_CHECK_TIME" => 0x200000
|
317
|
+
}.freeze
|
318
|
+
|
229
319
|
class Server
|
230
320
|
def initialize(socket, ctx)
|
231
321
|
@socket = socket
|
232
322
|
@ctx = ctx
|
233
|
-
|
234
|
-
|
235
|
-
def to_io
|
236
|
-
@socket
|
323
|
+
@eng_ctx = IS_JRUBY ? @ctx : SSLContext.new(ctx)
|
237
324
|
end
|
238
325
|
|
239
326
|
def accept
|
240
327
|
@ctx.check
|
241
328
|
io = @socket.accept
|
242
|
-
engine = Engine.server @
|
243
|
-
|
329
|
+
engine = Engine.server @eng_ctx
|
244
330
|
Socket.new io, engine
|
245
331
|
end
|
246
332
|
|
247
333
|
def accept_nonblock
|
248
334
|
@ctx.check
|
249
335
|
io = @socket.accept_nonblock
|
250
|
-
engine = Engine.server @
|
251
|
-
|
336
|
+
engine = Engine.server @eng_ctx
|
252
337
|
Socket.new io, engine
|
253
338
|
end
|
254
339
|
|
340
|
+
# @!attribute [r] to_io
|
341
|
+
def to_io
|
342
|
+
@socket
|
343
|
+
end
|
344
|
+
|
345
|
+
# @!attribute [r] addr
|
346
|
+
# @version 5.0.0
|
347
|
+
def addr
|
348
|
+
@socket.addr
|
349
|
+
end
|
350
|
+
|
255
351
|
def close
|
256
352
|
@socket.close unless @socket.closed? # closed? call is for Windows
|
257
353
|
end
|
354
|
+
|
355
|
+
def closed?
|
356
|
+
@socket.closed?
|
357
|
+
end
|
258
358
|
end
|
259
359
|
end
|
260
360
|
end
|
data/lib/puma/null_io.rb
CHANGED
@@ -9,13 +9,17 @@ module Puma
|
|
9
9
|
nil
|
10
10
|
end
|
11
11
|
|
12
|
+
def string
|
13
|
+
""
|
14
|
+
end
|
15
|
+
|
12
16
|
def each
|
13
17
|
end
|
14
18
|
|
15
19
|
# Mimics IO#read with no data.
|
16
20
|
#
|
17
21
|
def read(count = nil, _buffer = nil)
|
18
|
-
|
22
|
+
count && count > 0 ? nil : ""
|
19
23
|
end
|
20
24
|
|
21
25
|
def rewind
|
@@ -32,6 +36,10 @@ module Puma
|
|
32
36
|
true
|
33
37
|
end
|
34
38
|
|
39
|
+
def sync
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
35
43
|
def sync=(v)
|
36
44
|
end
|
37
45
|
|
@@ -40,5 +48,9 @@ module Puma
|
|
40
48
|
|
41
49
|
def write(*ary)
|
42
50
|
end
|
51
|
+
|
52
|
+
def flush
|
53
|
+
self
|
54
|
+
end
|
43
55
|
end
|
44
56
|
end
|
data/lib/puma/plugin.rb
CHANGED
@@ -10,7 +10,7 @@ module Puma
|
|
10
10
|
|
11
11
|
def create(name)
|
12
12
|
if cls = Plugins.find(name)
|
13
|
-
plugin = cls.new
|
13
|
+
plugin = cls.new
|
14
14
|
@instances << plugin
|
15
15
|
return plugin
|
16
16
|
end
|
@@ -62,8 +62,11 @@ module Puma
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def fire_background
|
65
|
-
@background.
|
66
|
-
Thread.new
|
65
|
+
@background.each_with_index do |b, i|
|
66
|
+
Thread.new do
|
67
|
+
Puma.set_thread_name "plgn bg #{i}"
|
68
|
+
b.call
|
69
|
+
end
|
67
70
|
end
|
68
71
|
end
|
69
72
|
end
|
@@ -88,7 +91,7 @@ module Puma
|
|
88
91
|
path = ary.first[CALLER_FILE]
|
89
92
|
|
90
93
|
m = %r!puma/plugin/([^/]*)\.rb$!.match(path)
|
91
|
-
|
94
|
+
m[1]
|
92
95
|
end
|
93
96
|
|
94
97
|
def self.create(&blk)
|
@@ -101,17 +104,8 @@ module Puma
|
|
101
104
|
Plugins.register name, cls
|
102
105
|
end
|
103
106
|
|
104
|
-
def initialize(loader)
|
105
|
-
@loader = loader
|
106
|
-
end
|
107
|
-
|
108
107
|
def in_background(&blk)
|
109
108
|
Plugins.add_background blk
|
110
109
|
end
|
111
|
-
|
112
|
-
def workers_supported?
|
113
|
-
return false if Puma.jruby? || Puma.windows?
|
114
|
-
true
|
115
|
-
end
|
116
110
|
end
|
117
111
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class ClosedQueueError < StandardError; end
|
2
|
+
module Puma
|
3
|
+
|
4
|
+
# Queue#close was added in Ruby 2.3.
|
5
|
+
# Add a simple implementation for earlier Ruby versions.
|
6
|
+
#
|
7
|
+
module QueueClose
|
8
|
+
def close
|
9
|
+
num_waiting.times {push nil}
|
10
|
+
@closed = true
|
11
|
+
end
|
12
|
+
def closed?
|
13
|
+
@closed ||= false
|
14
|
+
end
|
15
|
+
def push(object)
|
16
|
+
raise ClosedQueueError if closed?
|
17
|
+
super
|
18
|
+
end
|
19
|
+
alias << push
|
20
|
+
def pop(non_block=false)
|
21
|
+
return nil if !non_block && closed? && empty?
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
::Queue.prepend QueueClose
|
26
|
+
end
|
data/lib/puma/rack/builder.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Puma
|
2
4
|
end
|
3
5
|
|
@@ -65,10 +67,6 @@ module Puma::Rack
|
|
65
67
|
options[:environment] = e
|
66
68
|
}
|
67
69
|
|
68
|
-
opts.on("-D", "--daemonize", "run daemonized in the background") { |d|
|
69
|
-
options[:daemonize] = d ? true : false
|
70
|
-
}
|
71
|
-
|
72
70
|
opts.on("-P", "--pid FILE", "file to store PID") { |f|
|
73
71
|
options[:pid] = ::File.expand_path(f)
|
74
72
|
}
|
@@ -167,7 +165,7 @@ module Puma::Rack
|
|
167
165
|
require config
|
168
166
|
app = Object.const_get(::File.basename(config, '.rb').capitalize)
|
169
167
|
end
|
170
|
-
|
168
|
+
[app, options]
|
171
169
|
end
|
172
170
|
|
173
171
|
def self.new_from_string(builder_script, file="(rackup)")
|
data/lib/puma/rack/urlmap.rb
CHANGED