puma 5.3.2-java → 5.5.2-java
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 +81 -8
- data/README.md +42 -6
- data/docs/architecture.md +49 -16
- data/docs/compile_options.md +4 -2
- data/docs/deployment.md +53 -67
- data/docs/plugins.md +15 -15
- data/docs/rails_dev_mode.md +2 -3
- data/docs/restart.md +6 -6
- data/docs/signals.md +10 -10
- data/docs/stats.md +8 -8
- data/docs/systemd.md +64 -67
- data/ext/puma_http11/extconf.rb +18 -1
- data/ext/puma_http11/http11_parser.c +23 -10
- data/ext/puma_http11/http11_parser_common.rl +1 -1
- data/ext/puma_http11/mini_ssl.c +16 -1
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +49 -47
- data/lib/puma/app/status.rb +4 -4
- data/lib/puma/binder.rb +33 -2
- data/lib/puma/cli.rb +5 -0
- data/lib/puma/client.rb +49 -8
- data/lib/puma/cluster/worker.rb +3 -13
- data/lib/puma/cluster.rb +1 -13
- data/lib/puma/configuration.rb +1 -1
- data/lib/puma/const.rb +4 -2
- data/lib/puma/control_cli.rb +1 -1
- data/lib/puma/dsl.rb +20 -3
- data/lib/puma/{json.rb → json_serialization.rb} +1 -1
- data/lib/puma/launcher.rb +2 -0
- data/lib/puma/minissl.rb +6 -21
- data/lib/puma/plugin.rb +1 -1
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/rack/builder.rb +1 -1
- data/lib/puma/request.rb +4 -4
- data/lib/puma/runner.rb +19 -6
- data/lib/puma/server.rb +17 -8
- data/lib/puma/thread_pool.rb +6 -4
- data/lib/puma/util.rb +8 -1
- data/lib/puma.rb +2 -2
- metadata +6 -6
@@ -34,9 +34,9 @@ private static short[] init__puma_parser_key_offsets_0()
|
|
34
34
|
{
|
35
35
|
return new short [] {
|
36
36
|
0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
|
37
|
-
39, 41, 44, 45, 61, 62, 78,
|
38
|
-
|
39
|
-
|
37
|
+
39, 41, 44, 45, 61, 62, 78, 85, 91, 99, 107, 117,
|
38
|
+
125, 134, 142, 150, 159, 168, 177, 186, 195, 204, 213, 222,
|
39
|
+
231, 240, 249, 258, 267, 276, 285, 294, 303, 312, 313
|
40
40
|
};
|
41
41
|
}
|
42
42
|
|
@@ -52,26 +52,27 @@ private static char[] init__puma_parser_trans_keys_0()
|
|
52
52
|
46, 48, 57, 48, 57, 13, 48, 57, 10, 13, 33, 124,
|
53
53
|
126, 35, 39, 42, 43, 45, 46, 48, 57, 65, 90, 94,
|
54
54
|
122, 10, 33, 58, 124, 126, 35, 39, 42, 43, 45, 46,
|
55
|
-
48, 57, 65, 90, 94, 122, 13, 32,
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
63
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
64
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
65
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
66
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
67
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
68
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
69
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
70
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
71
|
-
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
72
|
-
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
73
|
-
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
74
|
-
65, 90, 32,
|
55
|
+
48, 57, 65, 90, 94, 122, 13, 32, 127, 0, 8, 10,
|
56
|
+
31, 13, 127, 0, 8, 10, 31, 32, 60, 62, 127, 0,
|
57
|
+
31, 34, 35, 32, 60, 62, 127, 0, 31, 34, 35, 43,
|
58
|
+
58, 45, 46, 48, 57, 65, 90, 97, 122, 32, 34, 35,
|
59
|
+
60, 62, 127, 0, 31, 32, 34, 35, 60, 62, 63, 127,
|
60
|
+
0, 31, 32, 34, 35, 60, 62, 127, 0, 31, 32, 34,
|
61
|
+
35, 60, 62, 127, 0, 31, 32, 36, 95, 45, 46, 48,
|
62
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
63
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
64
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
65
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
66
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
67
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
68
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
69
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
70
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
71
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
72
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
73
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
74
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
75
|
+
32, 0
|
75
76
|
};
|
76
77
|
}
|
77
78
|
|
@@ -82,7 +83,7 @@ private static byte[] init__puma_parser_single_lengths_0()
|
|
82
83
|
{
|
83
84
|
return new byte [] {
|
84
85
|
0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
|
85
|
-
0, 1, 1, 4, 1, 4,
|
86
|
+
0, 1, 1, 4, 1, 4, 3, 2, 4, 4, 2, 6,
|
86
87
|
7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
87
88
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
|
88
89
|
};
|
@@ -95,7 +96,7 @@ private static byte[] init__puma_parser_range_lengths_0()
|
|
95
96
|
{
|
96
97
|
return new byte [] {
|
97
98
|
0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
|
98
|
-
1, 1, 0, 6, 0, 6,
|
99
|
+
1, 1, 0, 6, 0, 6, 2, 2, 2, 2, 4, 1,
|
99
100
|
1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
100
101
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
|
101
102
|
};
|
@@ -108,9 +109,9 @@ private static short[] init__puma_parser_index_offsets_0()
|
|
108
109
|
{
|
109
110
|
return new short [] {
|
110
111
|
0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
|
111
|
-
39, 41, 44, 46, 57, 59, 70,
|
112
|
-
|
113
|
-
|
112
|
+
39, 41, 44, 46, 57, 59, 70, 76, 81, 88, 95, 102,
|
113
|
+
110, 119, 127, 135, 142, 149, 156, 163, 170, 177, 184, 191,
|
114
|
+
198, 205, 212, 219, 226, 233, 240, 247, 254, 261, 263
|
114
115
|
};
|
115
116
|
}
|
116
117
|
|
@@ -126,22 +127,23 @@ private static byte[] init__puma_parser_indicies_0()
|
|
126
127
|
16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21,
|
127
128
|
21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23,
|
128
129
|
24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
|
129
|
-
|
130
|
-
1, 1, 1, 1,
|
131
|
-
|
132
|
-
1,
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
63, 63, 1, 2, 1, 1,
|
130
|
+
1, 1, 1, 25, 29, 1, 1, 1, 28, 30, 1, 1,
|
131
|
+
1, 1, 1, 31, 32, 1, 1, 1, 1, 1, 33, 34,
|
132
|
+
35, 34, 34, 34, 34, 1, 8, 1, 9, 1, 1, 1,
|
133
|
+
1, 35, 36, 1, 38, 1, 1, 39, 1, 1, 37, 40,
|
134
|
+
1, 42, 1, 1, 1, 1, 41, 43, 1, 45, 1, 1,
|
135
|
+
1, 1, 44, 2, 46, 46, 46, 46, 46, 1, 2, 47,
|
136
|
+
47, 47, 47, 47, 1, 2, 48, 48, 48, 48, 48, 1,
|
137
|
+
2, 49, 49, 49, 49, 49, 1, 2, 50, 50, 50, 50,
|
138
|
+
50, 1, 2, 51, 51, 51, 51, 51, 1, 2, 52, 52,
|
139
|
+
52, 52, 52, 1, 2, 53, 53, 53, 53, 53, 1, 2,
|
140
|
+
54, 54, 54, 54, 54, 1, 2, 55, 55, 55, 55, 55,
|
141
|
+
1, 2, 56, 56, 56, 56, 56, 1, 2, 57, 57, 57,
|
142
|
+
57, 57, 1, 2, 58, 58, 58, 58, 58, 1, 2, 59,
|
143
|
+
59, 59, 59, 59, 1, 2, 60, 60, 60, 60, 60, 1,
|
144
|
+
2, 61, 61, 61, 61, 61, 1, 2, 62, 62, 62, 62,
|
145
|
+
62, 1, 2, 63, 63, 63, 63, 63, 1, 2, 1, 1,
|
146
|
+
0
|
145
147
|
};
|
146
148
|
}
|
147
149
|
|
@@ -210,7 +212,7 @@ static final int puma_parser_error = 0;
|
|
210
212
|
cs = 0;
|
211
213
|
|
212
214
|
|
213
|
-
// line
|
215
|
+
// line 216 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
214
216
|
{
|
215
217
|
cs = puma_parser_start;
|
216
218
|
}
|
@@ -242,7 +244,7 @@ static final int puma_parser_error = 0;
|
|
242
244
|
parser.buffer = buffer;
|
243
245
|
|
244
246
|
|
245
|
-
// line
|
247
|
+
// line 248 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
246
248
|
{
|
247
249
|
int _klen;
|
248
250
|
int _trans = 0;
|
@@ -398,7 +400,7 @@ case 1:
|
|
398
400
|
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
|
399
401
|
}
|
400
402
|
break;
|
401
|
-
// line
|
403
|
+
// line 404 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
402
404
|
}
|
403
405
|
}
|
404
406
|
}
|
data/lib/puma/app/status.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'puma/
|
2
|
+
require 'puma/json_serialization'
|
3
3
|
|
4
4
|
module Puma
|
5
5
|
module App
|
@@ -46,17 +46,17 @@ module Puma
|
|
46
46
|
GC.start ; 200
|
47
47
|
|
48
48
|
when 'gc-stats'
|
49
|
-
Puma::
|
49
|
+
Puma::JSONSerialization.generate GC.stat
|
50
50
|
|
51
51
|
when 'stats'
|
52
|
-
Puma::
|
52
|
+
Puma::JSONSerialization.generate @launcher.stats
|
53
53
|
|
54
54
|
when 'thread-backtraces'
|
55
55
|
backtraces = []
|
56
56
|
@launcher.thread_status do |name, backtrace|
|
57
57
|
backtraces << { name: name, backtrace: backtrace }
|
58
58
|
end
|
59
|
-
Puma::
|
59
|
+
Puma::JSONSerialization.generate backtraces
|
60
60
|
|
61
61
|
else
|
62
62
|
return rack_response(404, "Unsupported action", 'text/plain')
|
data/lib/puma/binder.rb
CHANGED
@@ -41,6 +41,7 @@ module Puma
|
|
41
41
|
"rack.multithread".freeze => conf.options[:max_threads] > 1,
|
42
42
|
"rack.multiprocess".freeze => conf.options[:workers] >= 1,
|
43
43
|
"rack.run_once".freeze => false,
|
44
|
+
RACK_URL_SCHEME => conf.options[:rack_url_scheme],
|
44
45
|
"SCRIPT_NAME".freeze => ENV['SCRIPT_NAME'] || "",
|
45
46
|
|
46
47
|
# I'd like to set a default CONTENT_TYPE here but some things
|
@@ -56,6 +57,7 @@ module Puma
|
|
56
57
|
|
57
58
|
@envs = {}
|
58
59
|
@ios = []
|
60
|
+
localhost_authority
|
59
61
|
end
|
60
62
|
|
61
63
|
attr_reader :ios
|
@@ -95,6 +97,7 @@ module Puma
|
|
95
97
|
# @version 5.0.0
|
96
98
|
#
|
97
99
|
def create_activated_fds(env_hash)
|
100
|
+
@events.debug "ENV['LISTEN_FDS'] #{ENV['LISTEN_FDS'].inspect} env_hash['LISTEN_PID'] #{env_hash['LISTEN_PID'].inspect}"
|
98
101
|
return [] unless env_hash['LISTEN_FDS'] && env_hash['LISTEN_PID'].to_i == $$
|
99
102
|
env_hash['LISTEN_FDS'].to_i.times do |index|
|
100
103
|
sock = TCPServer.for_fd(socket_activation_fd(index))
|
@@ -188,7 +191,8 @@ module Puma
|
|
188
191
|
@unix_paths << path unless abstract
|
189
192
|
io = inherit_unix_listener path, fd
|
190
193
|
logger.log "* Inherited #{str}"
|
191
|
-
elsif sock = @activated_sockets.delete([ :unix, path ])
|
194
|
+
elsif sock = @activated_sockets.delete([ :unix, path ]) ||
|
195
|
+
@activated_sockets.delete([ :unix, File.realdirpath(path) ])
|
192
196
|
@unix_paths << path unless abstract || File.exist?(path)
|
193
197
|
io = inherit_unix_listener path, sock
|
194
198
|
logger.log "* Activated #{str}"
|
@@ -224,7 +228,13 @@ module Puma
|
|
224
228
|
raise "Puma compiled without SSL support" unless HAS_SSL
|
225
229
|
|
226
230
|
params = Util.parse_query uri.query
|
227
|
-
|
231
|
+
|
232
|
+
# If key and certs are not defined and localhost gem is required.
|
233
|
+
# localhost gem will be used for self signed
|
234
|
+
# Load localhost authority if not loaded.
|
235
|
+
ctx = localhost_authority && localhost_authority_context if params.empty?
|
236
|
+
|
237
|
+
ctx ||= MiniSSL::ContextBuilder.new(params, @events).context
|
228
238
|
|
229
239
|
if fd = @inherited_fds.delete(str)
|
230
240
|
logger.log "* Inherited #{str}"
|
@@ -282,6 +292,22 @@ module Puma
|
|
282
292
|
end
|
283
293
|
end
|
284
294
|
|
295
|
+
def localhost_authority
|
296
|
+
@localhost_authority ||= Localhost::Authority.fetch if defined?(Localhost::Authority) && !Puma::IS_JRUBY
|
297
|
+
end
|
298
|
+
|
299
|
+
def localhost_authority_context
|
300
|
+
return unless localhost_authority
|
301
|
+
|
302
|
+
key_path, crt_path = if [:key_path, :certificate_path].all? { |m| localhost_authority.respond_to?(m) }
|
303
|
+
[localhost_authority.key_path, localhost_authority.certificate_path]
|
304
|
+
else
|
305
|
+
local_certificates_path = File.expand_path("~/.localhost")
|
306
|
+
[File.join(local_certificates_path, "localhost.key"), File.join(local_certificates_path, "localhost.crt")]
|
307
|
+
end
|
308
|
+
MiniSSL::ContextBuilder.new({ "key" => key_path, "cert" => crt_path }, @events).context
|
309
|
+
end
|
310
|
+
|
285
311
|
# Tell the server to listen on host +host+, port +port+.
|
286
312
|
# If +optimize_for_latency+ is true (the default) then clients connecting
|
287
313
|
# will be optimized for latency over throughput.
|
@@ -299,6 +325,7 @@ module Puma
|
|
299
325
|
|
300
326
|
host = host[1..-2] if host and host[0..0] == '['
|
301
327
|
tcp_server = TCPServer.new(host, port)
|
328
|
+
|
302
329
|
if optimize_for_latency
|
303
330
|
tcp_server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
304
331
|
end
|
@@ -320,6 +347,8 @@ module Puma
|
|
320
347
|
optimize_for_latency=true, backlog=1024)
|
321
348
|
|
322
349
|
raise "Puma compiled without SSL support" unless HAS_SSL
|
350
|
+
# Puma will try to use local authority context if context is supplied nil
|
351
|
+
ctx ||= localhost_authority_context
|
323
352
|
|
324
353
|
if host == "localhost"
|
325
354
|
loopback_addresses.each do |addr|
|
@@ -347,6 +376,8 @@ module Puma
|
|
347
376
|
|
348
377
|
def inherit_ssl_listener(fd, ctx)
|
349
378
|
raise "Puma compiled without SSL support" unless HAS_SSL
|
379
|
+
# Puma will try to use local authority context if context is supplied nil
|
380
|
+
ctx ||= localhost_authority_context
|
350
381
|
|
351
382
|
s = fd.kind_of?(::TCPServer) ? fd : ::TCPServer.for_fd(fd)
|
352
383
|
|
data/lib/puma/cli.rb
CHANGED
@@ -112,6 +112,11 @@ module Puma
|
|
112
112
|
file_config.load arg
|
113
113
|
end
|
114
114
|
|
115
|
+
# Identical to supplying --config "-", but more semantic
|
116
|
+
o.on "--no-config", "Prevent Puma from searching for a config file" do |arg|
|
117
|
+
file_config.load "-"
|
118
|
+
end
|
119
|
+
|
115
120
|
o.on "--control-url URL", "The bind url to use for the control server. Use 'auto' to use temp unix server" do |arg|
|
116
121
|
configure_control_url(arg)
|
117
122
|
end
|
data/lib/puma/client.rb
CHANGED
@@ -56,6 +56,7 @@ module Puma
|
|
56
56
|
@parser = HttpParser.new
|
57
57
|
@parsed_bytes = 0
|
58
58
|
@read_header = true
|
59
|
+
@read_proxy = false
|
59
60
|
@ready = false
|
60
61
|
|
61
62
|
@body = nil
|
@@ -71,6 +72,7 @@ module Puma
|
|
71
72
|
@peerip = nil
|
72
73
|
@listener = nil
|
73
74
|
@remote_addr_header = nil
|
75
|
+
@expect_proxy_proto = false
|
74
76
|
|
75
77
|
@body_remain = 0
|
76
78
|
|
@@ -106,7 +108,7 @@ module Puma
|
|
106
108
|
|
107
109
|
# @!attribute [r] in_data_phase
|
108
110
|
def in_data_phase
|
109
|
-
|
111
|
+
!(@read_header || @read_proxy)
|
110
112
|
end
|
111
113
|
|
112
114
|
def set_timeout(val)
|
@@ -121,6 +123,7 @@ module Puma
|
|
121
123
|
def reset(fast_check=true)
|
122
124
|
@parser.reset
|
123
125
|
@read_header = true
|
126
|
+
@read_proxy = !!@expect_proxy_proto
|
124
127
|
@env = @proto_env.dup
|
125
128
|
@body = nil
|
126
129
|
@tempfile = nil
|
@@ -131,6 +134,8 @@ module Puma
|
|
131
134
|
@in_last_chunk = false
|
132
135
|
|
133
136
|
if @buffer
|
137
|
+
return false unless try_to_parse_proxy_protocol
|
138
|
+
|
134
139
|
@parsed_bytes = @parser.execute(@env, @buffer, @parsed_bytes)
|
135
140
|
|
136
141
|
if @parser.finished?
|
@@ -143,8 +148,7 @@ module Puma
|
|
143
148
|
return false
|
144
149
|
else
|
145
150
|
begin
|
146
|
-
if fast_check &&
|
147
|
-
IO.select([@to_io], nil, nil, FAST_TRACK_KA_TIMEOUT)
|
151
|
+
if fast_check && @to_io.wait_readable(FAST_TRACK_KA_TIMEOUT)
|
148
152
|
return try_to_finish
|
149
153
|
end
|
150
154
|
rescue IOError
|
@@ -158,12 +162,36 @@ module Puma
|
|
158
162
|
begin
|
159
163
|
@io.close
|
160
164
|
rescue IOError
|
161
|
-
|
165
|
+
Puma::Util.purge_interrupt_queue
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# If necessary, read the PROXY protocol from the buffer. Returns
|
170
|
+
# false if more data is needed.
|
171
|
+
def try_to_parse_proxy_protocol
|
172
|
+
if @read_proxy
|
173
|
+
if @expect_proxy_proto == :v1
|
174
|
+
if @buffer.include? "\r\n"
|
175
|
+
if md = PROXY_PROTOCOL_V1_REGEX.match(@buffer)
|
176
|
+
if md[1]
|
177
|
+
@peerip = md[1].split(" ")[0]
|
178
|
+
end
|
179
|
+
@buffer = md.post_match
|
180
|
+
end
|
181
|
+
# if the buffer has a \r\n but doesn't have a PROXY protocol
|
182
|
+
# request, this is just HTTP from a non-PROXY client; move on
|
183
|
+
@read_proxy = false
|
184
|
+
return @buffer.size > 0
|
185
|
+
else
|
186
|
+
return false
|
187
|
+
end
|
188
|
+
end
|
162
189
|
end
|
190
|
+
true
|
163
191
|
end
|
164
192
|
|
165
193
|
def try_to_finish
|
166
|
-
return read_body
|
194
|
+
return read_body if in_data_phase
|
167
195
|
|
168
196
|
begin
|
169
197
|
data = @io.read_nonblock(CHUNK_SIZE)
|
@@ -188,6 +216,8 @@ module Puma
|
|
188
216
|
@buffer = data
|
189
217
|
end
|
190
218
|
|
219
|
+
return false unless try_to_parse_proxy_protocol
|
220
|
+
|
191
221
|
@parsed_bytes = @parser.execute(@env, @buffer, @parsed_bytes)
|
192
222
|
|
193
223
|
if @parser.finished?
|
@@ -202,13 +232,13 @@ module Puma
|
|
202
232
|
|
203
233
|
def eagerly_finish
|
204
234
|
return true if @ready
|
205
|
-
return false unless
|
235
|
+
return false unless @to_io.wait_readable(0)
|
206
236
|
try_to_finish
|
207
237
|
end
|
208
238
|
|
209
239
|
def finish(timeout)
|
210
240
|
return if @ready
|
211
|
-
|
241
|
+
@to_io.wait_readable(timeout) || timeout! until try_to_finish
|
212
242
|
end
|
213
243
|
|
214
244
|
def timeout!
|
@@ -244,6 +274,17 @@ module Puma
|
|
244
274
|
@parsed_bytes == 0
|
245
275
|
end
|
246
276
|
|
277
|
+
def expect_proxy_proto=(val)
|
278
|
+
if val
|
279
|
+
if @read_header
|
280
|
+
@read_proxy = true
|
281
|
+
end
|
282
|
+
else
|
283
|
+
@read_proxy = false
|
284
|
+
end
|
285
|
+
@expect_proxy_proto = val
|
286
|
+
end
|
287
|
+
|
247
288
|
private
|
248
289
|
|
249
290
|
def setup_body
|
@@ -309,7 +350,7 @@ module Puma
|
|
309
350
|
|
310
351
|
@body_remain = remain
|
311
352
|
|
312
|
-
|
353
|
+
false
|
313
354
|
end
|
314
355
|
|
315
356
|
def read_body
|
data/lib/puma/cluster/worker.rb
CHANGED
@@ -35,7 +35,7 @@ module Puma
|
|
35
35
|
|
36
36
|
Thread.new do
|
37
37
|
Puma.set_thread_name "worker check pipe"
|
38
|
-
|
38
|
+
@check_pipe.wait_readable
|
39
39
|
log "! Detected parent died, dying"
|
40
40
|
exit! 1
|
41
41
|
end
|
@@ -106,7 +106,7 @@ module Puma
|
|
106
106
|
begin
|
107
107
|
@worker_write << "b#{Process.pid}:#{index}\n"
|
108
108
|
rescue SystemCallError, IOError
|
109
|
-
|
109
|
+
Puma::Util.purge_interrupt_queue
|
110
110
|
STDERR.puts "Master seems to have exited, exiting."
|
111
111
|
return
|
112
112
|
end
|
@@ -127,7 +127,7 @@ module Puma
|
|
127
127
|
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads": #{m}, "requests_count": #{rc} }\n!
|
128
128
|
io << payload
|
129
129
|
rescue IOError
|
130
|
-
|
130
|
+
Puma::Util.purge_interrupt_queue
|
131
131
|
break
|
132
132
|
end
|
133
133
|
sleep Const::WORKER_CHECK_INTERVAL
|
@@ -168,16 +168,6 @@ module Puma
|
|
168
168
|
@launcher.config.run_hooks :after_worker_fork, idx, @launcher.events
|
169
169
|
pid
|
170
170
|
end
|
171
|
-
|
172
|
-
def wakeup!
|
173
|
-
return unless @wakeup
|
174
|
-
|
175
|
-
begin
|
176
|
-
@wakeup.write "!" unless @wakeup.closed?
|
177
|
-
rescue SystemCallError, IOError
|
178
|
-
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
179
|
-
end
|
180
|
-
end
|
181
171
|
end
|
182
172
|
end
|
183
173
|
end
|
data/lib/puma/cluster.rb
CHANGED
@@ -164,16 +164,6 @@ module Puma
|
|
164
164
|
].compact.min
|
165
165
|
end
|
166
166
|
|
167
|
-
def wakeup!
|
168
|
-
return unless @wakeup
|
169
|
-
|
170
|
-
begin
|
171
|
-
@wakeup.write "!" unless @wakeup.closed?
|
172
|
-
rescue SystemCallError, IOError
|
173
|
-
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
167
|
def worker(index, master)
|
178
168
|
@workers = []
|
179
169
|
|
@@ -426,9 +416,7 @@ module Puma
|
|
426
416
|
|
427
417
|
check_workers
|
428
418
|
|
429
|
-
|
430
|
-
|
431
|
-
if res
|
419
|
+
if read.wait_readable([0, @next_check - Time.now].max)
|
432
420
|
req = read.read_nonblock(1)
|
433
421
|
|
434
422
|
@next_check = Time.now if req == "!"
|
data/lib/puma/configuration.rb
CHANGED
@@ -200,7 +200,7 @@ module Puma
|
|
200
200
|
:worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
|
201
201
|
:remote_address => :socket,
|
202
202
|
:tag => method(:infer_tag),
|
203
|
-
:environment => -> { ENV['RACK_ENV'] || ENV['RAILS_ENV'] ||
|
203
|
+
:environment => -> { ENV['APP_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development' },
|
204
204
|
:rackup => DefaultRackup,
|
205
205
|
:logger => STDOUT,
|
206
206
|
:persistent_timeout => Const::PERSISTENT_TIMEOUT,
|
data/lib/puma/const.rb
CHANGED
@@ -100,8 +100,8 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "5.
|
104
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "5.5.2".freeze
|
104
|
+
CODE_NAME = "Zawgyi".freeze
|
105
105
|
|
106
106
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
107
107
|
|
@@ -247,5 +247,7 @@ module Puma
|
|
247
247
|
|
248
248
|
# Banned keys of response header
|
249
249
|
BANNED_HEADER_KEY = /\A(rack\.|status\z)/.freeze
|
250
|
+
|
251
|
+
PROXY_PROTOCOL_V1_REGEX = /^PROXY (?:TCP4|TCP6|UNKNOWN) ([^\r]+)\r\n/.freeze
|
250
252
|
end
|
251
253
|
end
|
data/lib/puma/control_cli.rb
CHANGED
data/lib/puma/dsl.rb
CHANGED
@@ -381,6 +381,13 @@ module Puma
|
|
381
381
|
@options[:rackup] ||= path.to_s
|
382
382
|
end
|
383
383
|
|
384
|
+
# Allows setting `env['rack.url_scheme']`.
|
385
|
+
# Only necessary if X-Forwarded-Proto is not being set by your proxy
|
386
|
+
# Normal values are 'http' or 'https'.
|
387
|
+
def rack_url_scheme(scheme=nil)
|
388
|
+
@options[:rack_url_scheme] = scheme
|
389
|
+
end
|
390
|
+
|
384
391
|
def early_hints(answer=true)
|
385
392
|
@options[:early_hints] = answer
|
386
393
|
end
|
@@ -578,7 +585,7 @@ module Puma
|
|
578
585
|
# end
|
579
586
|
def after_worker_fork(&block)
|
580
587
|
@options[:after_worker_fork] ||= []
|
581
|
-
@options[:after_worker_fork]
|
588
|
+
@options[:after_worker_fork] << block
|
582
589
|
end
|
583
590
|
|
584
591
|
alias_method :after_worker_boot, :after_worker_fork
|
@@ -811,7 +818,7 @@ module Puma
|
|
811
818
|
# a kernel syscall is required which for very fast rack handlers
|
812
819
|
# slows down the handling significantly.
|
813
820
|
#
|
814
|
-
# There are
|
821
|
+
# There are 5 possible values:
|
815
822
|
#
|
816
823
|
# 1. **:socket** (the default) - read the peername from the socket using the
|
817
824
|
# syscall. This is the normal behavior.
|
@@ -821,7 +828,10 @@ module Puma
|
|
821
828
|
# `set_remote_address header: "X-Real-IP"`.
|
822
829
|
# Only the first word (as separated by spaces or comma) is used, allowing
|
823
830
|
# headers such as X-Forwarded-For to be used as well.
|
824
|
-
# 4.
|
831
|
+
# 4. **proxy_protocol: :v1**- set the remote address to the value read from the
|
832
|
+
# HAproxy PROXY protocol, version 1. If the request does not have the PROXY
|
833
|
+
# protocol attached to it, will fall back to :socket
|
834
|
+
# 5. **\<Any string\>** - this allows you to hardcode remote address to any value
|
825
835
|
# you wish. Because Puma never uses this field anyway, it's format is
|
826
836
|
# entirely in your hands.
|
827
837
|
#
|
@@ -839,6 +849,13 @@ module Puma
|
|
839
849
|
if hdr = val[:header]
|
840
850
|
@options[:remote_address] = :header
|
841
851
|
@options[:remote_address_header] = "HTTP_" + hdr.upcase.tr("-", "_")
|
852
|
+
elsif protocol_version = val[:proxy_protocol]
|
853
|
+
@options[:remote_address] = :proxy_protocol
|
854
|
+
protocol_version = protocol_version.downcase.to_sym
|
855
|
+
unless [:v1].include?(protocol_version)
|
856
|
+
raise "Invalid value for proxy_protocol - #{protocol_version.inspect}"
|
857
|
+
end
|
858
|
+
@options[:remote_address_proxy_protocol] = protocol_version
|
842
859
|
else
|
843
860
|
raise "Invalid value for set_remote_address - #{val.inspect}"
|
844
861
|
end
|
@@ -17,7 +17,7 @@ module Puma
|
|
17
17
|
# be particularly full-featured or fast. It just has to handle the few places
|
18
18
|
# where Puma relies on JSON serialization internally.
|
19
19
|
|
20
|
-
module
|
20
|
+
module JSONSerialization
|
21
21
|
QUOTE = /"/
|
22
22
|
BACKSLASH = /\\/
|
23
23
|
CONTROL_CHAR_TO_ESCAPE = /[\x00-\x1F]/ # As required by ECMA-404
|
data/lib/puma/launcher.rb
CHANGED
@@ -319,10 +319,12 @@ module Puma
|
|
319
319
|
log '* Pruning Bundler environment'
|
320
320
|
home = ENV['GEM_HOME']
|
321
321
|
bundle_gemfile = Bundler.original_env['BUNDLE_GEMFILE']
|
322
|
+
bundle_app_config = Bundler.original_env['BUNDLE_APP_CONFIG']
|
322
323
|
with_unbundled_env do
|
323
324
|
ENV['GEM_HOME'] = home
|
324
325
|
ENV['BUNDLE_GEMFILE'] = bundle_gemfile
|
325
326
|
ENV['PUMA_BUNDLER_PRUNED'] = '1'
|
327
|
+
ENV["BUNDLE_APP_CONFIG"] = bundle_app_config
|
326
328
|
args = [Gem.ruby, puma_wild_location, '-I', dirs.join(':')] + @original_argv
|
327
329
|
# Ruby 2.0+ defaults to true which breaks socket activation
|
328
330
|
args += [{:close_others => false}]
|