puma 3.3.0 → 3.4.0
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.txt +27 -4
- data/README.md +9 -3
- data/docs/nginx.md +2 -2
- data/docs/systemd.md +95 -3
- data/lib/puma/binder.rb +2 -2
- data/lib/puma/cluster.rb +6 -0
- data/lib/puma/const.rb +8 -2
- data/lib/puma/dsl.rb +35 -13
- data/lib/puma/launcher.rb +1 -1
- data/lib/puma/rack/backports/uri/common_18.rb +18 -15
- data/lib/puma/rack/backports/uri/common_192.rb +13 -10
- data/lib/puma/rack/backports/uri/common_193.rb +17 -13
- data/lib/puma/reactor.rb +6 -0
- data/lib/puma/server.rb +24 -2
- data/lib/puma/single.rb +1 -1
- data/lib/puma/thread_pool.rb +36 -2
- data/tools/jungle/init.d/puma +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59d465d75e9f9cbc7ebb6ae7f26dfc531e995b2e
|
4
|
+
data.tar.gz: 93ba7123b7902f390ada3d933b645b969db2afb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ade21758b2cf93fefcfd443b0b19dcbd752ab4d3eff57ccfd86c3e08edb4330157a4f6259736007f73bc1770dc2a4ddc3c1ac696109f1ec944a30bdb6852d05c
|
7
|
+
data.tar.gz: 3143e6dc4f02b4e2a0afbfe32434040211d0eb07623adceeb37c3d4774ded1a50863e31030606e3dd7d351fece77d948ee2f0ccdbab132cd426f133f94777d1f
|
data/History.txt
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
=== 3.4.0 / 2016-04-07
|
2
|
+
|
3
|
+
* 2 minor features:
|
4
|
+
* Add ability to force threads to stop on shutdown. Fixes #938
|
5
|
+
* Detect and commit seppuku when fork(2) fails. Fixes #529
|
6
|
+
|
7
|
+
* 3 unknowns:
|
8
|
+
* Ignore errors trying to update the backport tables. Fixes #788
|
9
|
+
* Invoke the lowlevel_error in more places to allow for exception tracking. Fixes #894
|
10
|
+
* Update the query string when an absolute URI is used. Fixes #937
|
11
|
+
|
12
|
+
* 5 doc fixes:
|
13
|
+
* Add Process Monitors section to top-level README
|
14
|
+
* Better document the hooks. Fixes #840
|
15
|
+
* docs/system.md sample config refinements and elaborations
|
16
|
+
* Fix typos at couple of places.
|
17
|
+
* Cleanup warnings
|
18
|
+
|
19
|
+
* 3 PRs merged:
|
20
|
+
* Merge pull request #945 from dekellum/systemd-docs-refined
|
21
|
+
* Merge pull request #946 from vipulnsward/rm-pid
|
22
|
+
* Merge pull request #947 from vipulnsward/housekeeping-typos
|
23
|
+
|
1
24
|
=== 3.3.0 / 2016-04-05
|
2
25
|
|
3
26
|
* 2 minor features:
|
@@ -980,7 +1003,7 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
980
1003
|
|
981
1004
|
=== 1.5.0 / 2012-07-19
|
982
1005
|
|
983
|
-
* 7
|
1006
|
+
* 7 contributors to this release:
|
984
1007
|
* Christian Mayer
|
985
1008
|
* Darío Javier Cravero
|
986
1009
|
* Dirkjan Bussink
|
@@ -1028,7 +1051,7 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
1028
1051
|
* Only stop the status server if it's started. Fixes #84
|
1029
1052
|
* Set RACK_ENV early in cli also. Fixes #78
|
1030
1053
|
|
1031
|
-
* 1 new
|
1054
|
+
* 1 new contributor:
|
1032
1055
|
* Jesse Cooke
|
1033
1056
|
|
1034
1057
|
=== 1.2.2 / 2012-04-28
|
@@ -1064,9 +1087,9 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
1064
1087
|
* Fix reporting https only on a true SSL connection
|
1065
1088
|
* Set the default content type to 'text/plain'. Fixes #63
|
1066
1089
|
* Use REUSEADDR. Fixes #60
|
1067
|
-
* Shutdown
|
1090
|
+
* Shutdown gracefully on SIGTERM. Fixes #53
|
1068
1091
|
|
1069
|
-
2 new
|
1092
|
+
2 new contributors:
|
1070
1093
|
|
1071
1094
|
* Seamus Abshere
|
1072
1095
|
* Steve Richert
|
data/README.md
CHANGED
@@ -238,7 +238,7 @@ To perform a restart, there are 2 builtin mechanisms:
|
|
238
238
|
|
239
239
|
No code is shared between the current and restarted process, so it should be safe to issue a restart any place where you would manually stop Puma and start it again.
|
240
240
|
|
241
|
-
If the new process is unable to load, it will simply exit. You should therefore run Puma under a
|
241
|
+
If the new process is unable to load, it will simply exit. You should therefore run Puma under a process monitor (see below) when using it in production.
|
242
242
|
|
243
243
|
### Normal vs Hot vs Phased Restart
|
244
244
|
|
@@ -295,9 +295,15 @@ Because of various platforms not being able to implement certain things, the fol
|
|
295
295
|
|
296
296
|
`pumactl` is a simple CLI frontend to the control/status app described above. Please refer to `pumactl --help` for available commands.
|
297
297
|
|
298
|
-
##
|
298
|
+
## Process Monitors
|
299
299
|
|
300
|
-
|
300
|
+
Process monitors or supervisors will at minimum provide start of Puma
|
301
|
+
on system boot. Modern process monitors like systemd or upstart
|
302
|
+
further provide continuous monitoring and restarts for increased
|
303
|
+
reliability in production environments:
|
304
|
+
|
305
|
+
* [tools/jungle](https://github.com/puma/puma/tree/master/tools/jungle) for sysvinit (init.d) and upstart
|
306
|
+
* [docs/systemd](https://github.com/puma/puma/blob/master/docs/systemd.md)
|
301
307
|
|
302
308
|
## Capistrano deployment
|
303
309
|
|
data/docs/nginx.md
CHANGED
@@ -34,7 +34,7 @@ server {
|
|
34
34
|
proxy_set_header Host $http_host;
|
35
35
|
|
36
36
|
# If the file exists as a static file serve it directly without
|
37
|
-
# running all the other
|
37
|
+
# running all the other rewrite tests on it
|
38
38
|
if (-f $request_filename) {
|
39
39
|
break;
|
40
40
|
}
|
@@ -50,7 +50,7 @@ server {
|
|
50
50
|
# this is the meat of the rack page caching config
|
51
51
|
# it adds .html to the end of the url and then checks
|
52
52
|
# the filesystem for that file. If it exists, then we
|
53
|
-
#
|
53
|
+
# rewrite the url to have explicit .html on the end
|
54
54
|
# and then send it on its way to the next config rule.
|
55
55
|
# if there is no file on the fs then it sets all the
|
56
56
|
# necessary headers and proxies to our upstream pumas
|
data/docs/systemd.md
CHANGED
@@ -11,6 +11,9 @@ puma.service configuration file for systemd:
|
|
11
11
|
Description=Puma HTTP Server
|
12
12
|
After=network.target
|
13
13
|
|
14
|
+
# Uncomment for socket activation (see below)
|
15
|
+
# Requires=puma.socket
|
16
|
+
|
14
17
|
[Service]
|
15
18
|
# Foreground process (do not use --daemon in ExecStart or config.rb)
|
16
19
|
Type=simple
|
@@ -33,7 +36,7 @@ Type=simple
|
|
33
36
|
|
34
37
|
# Alternatively with a config file (in WorkingDirectory) and
|
35
38
|
# comparable `bind` directives
|
36
|
-
# ExecStart=<
|
39
|
+
# ExecStart=<WD>/sbin/puma -C config.rb
|
37
40
|
|
38
41
|
Restart=always
|
39
42
|
|
@@ -66,13 +69,102 @@ ListenStream=0.0.0.0:9293
|
|
66
69
|
# SocketUser, SocketGroup, etc. may be needed for Unix domain sockets
|
67
70
|
# ListenStream=/run/puma.sock
|
68
71
|
|
69
|
-
# Socket options matching
|
72
|
+
# Socket options matching Puma defaults
|
70
73
|
NoDelay=true
|
71
74
|
ReusePort=true
|
75
|
+
Backlog=1024
|
72
76
|
|
73
77
|
[Install]
|
74
78
|
WantedBy=sockets.target
|
75
79
|
~~~~
|
76
80
|
|
77
81
|
See [systemd.socket](https://www.freedesktop.org/software/systemd/man/systemd.socket.html)
|
78
|
-
for additional details.
|
82
|
+
for additional configuration details.
|
83
|
+
|
84
|
+
Note that the above configurations will work with Puma in either
|
85
|
+
single process or cluster mode.
|
86
|
+
|
87
|
+
## Usage
|
88
|
+
|
89
|
+
Without socket activation, use `systemctl` as root (e.g. via `sudo`) as
|
90
|
+
with other system services:
|
91
|
+
|
92
|
+
~~~~ sh
|
93
|
+
# After installing or making changes to puma.service
|
94
|
+
systemctl daemon-reload
|
95
|
+
|
96
|
+
# Enable so it starts on boot
|
97
|
+
systemctl enable puma.service
|
98
|
+
|
99
|
+
# Initial start up.
|
100
|
+
systemctl start puma.service
|
101
|
+
|
102
|
+
# Check status
|
103
|
+
systemctl status puma.service
|
104
|
+
|
105
|
+
# A normal restart. Warning: listeners sockets will be closed
|
106
|
+
# while a new puma process initializes.
|
107
|
+
systemctl restart puma.service
|
108
|
+
~~~~
|
109
|
+
|
110
|
+
With socket activation, several but not all of these commands should
|
111
|
+
be run for both socket and service:
|
112
|
+
|
113
|
+
~~~~ sh
|
114
|
+
# After installing or making changes to either puma.socket or
|
115
|
+
# puma.service.
|
116
|
+
systemctl daemon-reload
|
117
|
+
|
118
|
+
# Enable both socket and service so they start on boot. Alternatively
|
119
|
+
# you could leave puma.service disabled and systemd will start it on
|
120
|
+
# first use (with startup lag on first request)
|
121
|
+
systemctl enable puma.socket puma.service
|
122
|
+
|
123
|
+
# Initial start up. The Requires directive (see above) ensures the
|
124
|
+
# socket is started before the service.
|
125
|
+
systemctl start puma.socket puma.service
|
126
|
+
|
127
|
+
# Check status of both socket and service.
|
128
|
+
systemctl status puma.socket puma.service
|
129
|
+
|
130
|
+
# A "hot" restart, with systemd keeping puma.socket listening and
|
131
|
+
# providing to the new puma (master) instance.
|
132
|
+
systemctl restart puma.service
|
133
|
+
|
134
|
+
# A normal restart, needed to handle changes to
|
135
|
+
# puma.socket, such as changing the ListenStream ports. Note
|
136
|
+
# daemon-reload (above) should be run first.
|
137
|
+
systemctl restart puma.socket puma.service
|
138
|
+
~~~~
|
139
|
+
|
140
|
+
Here is sample output from `systemctl status` with both service and
|
141
|
+
socket running:
|
142
|
+
|
143
|
+
~~~~
|
144
|
+
● puma.socket - Puma HTTP Server Accept Sockets
|
145
|
+
Loaded: loaded (/etc/systemd/system/puma.socket; enabled; vendor preset: enabled)
|
146
|
+
Active: active (running) since Thu 2016-04-07 08:40:19 PDT; 1h 2min ago
|
147
|
+
Listen: 0.0.0.0:9233 (Stream)
|
148
|
+
0.0.0.0:9234 (Stream)
|
149
|
+
|
150
|
+
Apr 07 08:40:19 hx systemd[874]: Listening on Puma HTTP Server Accept Sockets.
|
151
|
+
|
152
|
+
● puma.service - Puma HTTP Server
|
153
|
+
Loaded: loaded (/etc/systemd/system/puma.service; enabled; vendor preset: enabled)
|
154
|
+
Active: active (running) since Thu 2016-04-07 08:40:19 PDT; 1h 2min ago
|
155
|
+
Main PID: 28320 (ruby)
|
156
|
+
CGroup: /system.slice/puma.service
|
157
|
+
├─28320 puma 3.3.0 (tcp://0.0.0.0:9233,ssl://0.0.0.0:9234?key=key.pem&cert=cert.pem) [app]
|
158
|
+
├─28323 puma: cluster worker 0: 28320 [app]
|
159
|
+
└─28327 puma: cluster worker 1: 28320 [app]
|
160
|
+
|
161
|
+
Apr 07 08:40:19 hx puma[28320]: Puma starting in cluster mode...
|
162
|
+
Apr 07 08:40:19 hx puma[28320]: * Version 3.3.0 (ruby 2.2.4-p230), codename: Jovial Platypus
|
163
|
+
Apr 07 08:40:19 hx puma[28320]: * Min threads: 0, max threads: 16
|
164
|
+
Apr 07 08:40:19 hx puma[28320]: * Environment: production
|
165
|
+
Apr 07 08:40:19 hx puma[28320]: * Process workers: 2
|
166
|
+
Apr 07 08:40:19 hx puma[28320]: * Phased restart available
|
167
|
+
Apr 07 08:40:19 hx puma[28320]: * Activated tcp://0.0.0.0:9233
|
168
|
+
Apr 07 08:40:19 hx puma[28320]: * Activated ssl://0.0.0.0:9234?key=key.pem&cert=cert.pem
|
169
|
+
Apr 07 08:40:19 hx puma[28320]: Use Ctrl-C to stop
|
170
|
+
~~~~
|
data/lib/puma/binder.rb
CHANGED
@@ -23,7 +23,7 @@ module Puma
|
|
23
23
|
"SCRIPT_NAME".freeze => ENV['SCRIPT_NAME'] || "",
|
24
24
|
|
25
25
|
# I'd like to set a default CONTENT_TYPE here but some things
|
26
|
-
# depend on their not being a default set and
|
26
|
+
# depend on their not being a default set and inferring
|
27
27
|
# it from the content. And so if i set it here, it won't
|
28
28
|
# infer properly.
|
29
29
|
|
@@ -230,7 +230,7 @@ module Puma
|
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
233
|
-
# Also close any
|
233
|
+
# Also close any unused activated sockets
|
234
234
|
@activated_sockets.each do |key, sock|
|
235
235
|
logger.log "* Closing unused activated socket: #{key.join ':'}"
|
236
236
|
begin
|
data/lib/puma/cluster.rb
CHANGED
@@ -118,6 +118,12 @@ module Puma
|
|
118
118
|
@launcher.config.run_hooks :before_worker_fork, idx
|
119
119
|
|
120
120
|
pid = fork { worker(idx, master) }
|
121
|
+
if !pid
|
122
|
+
log "! Complete inability to spawn new workers detected"
|
123
|
+
log "! Seppuku is the only choice."
|
124
|
+
exit! 1
|
125
|
+
end
|
126
|
+
|
121
127
|
debug "Spawned worker: #{pid}"
|
122
128
|
@workers << Worker.new(idx, pid, @phase, @options)
|
123
129
|
|
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 = "3.
|
104
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "3.4.0".freeze
|
104
|
+
CODE_NAME = "Owl Bowl Brawl".freeze
|
105
105
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
106
106
|
|
107
107
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
@@ -118,6 +118,11 @@ module Puma
|
|
118
118
|
# sending data back
|
119
119
|
WRITE_TIMEOUT = 10
|
120
120
|
|
121
|
+
# How long, after raising the ForceShutdown of a thread during
|
122
|
+
# forced shutdown mode, to wait for the thread to try and finish
|
123
|
+
# up it's work before leaving the thread to die on the vine.
|
124
|
+
SHUTDOWN_GRACE_TIME = 5 # seconds
|
125
|
+
|
121
126
|
DATE = "Date".freeze
|
122
127
|
|
123
128
|
SCRIPT_NAME = "SCRIPT_NAME".freeze
|
@@ -125,6 +130,7 @@ module Puma
|
|
125
130
|
# The original URI requested by the client.
|
126
131
|
REQUEST_URI= 'REQUEST_URI'.freeze
|
127
132
|
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
133
|
+
QUERY_STRING = 'QUERY_STRING'.freeze
|
128
134
|
|
129
135
|
PATH_INFO = 'PATH_INFO'.freeze
|
130
136
|
|
data/lib/puma/dsl.rb
CHANGED
@@ -159,6 +159,26 @@ module Puma
|
|
159
159
|
@options[:environment] = environment
|
160
160
|
end
|
161
161
|
|
162
|
+
# How long to wait for threads to stop when shutting them
|
163
|
+
# down. Defaults to :forever. Specifying :immediately will cause
|
164
|
+
# Puma to kill the threads immediately. Otherwise the value
|
165
|
+
# is the number of seconds to wait.
|
166
|
+
#
|
167
|
+
# Puma always waits a few seconds after killing a thread for it to try
|
168
|
+
# to finish up it's work, even in :immediately mode.
|
169
|
+
def force_shutdown_after(val=:forever)
|
170
|
+
i = case val
|
171
|
+
when :forever
|
172
|
+
-1
|
173
|
+
when :immediately
|
174
|
+
0
|
175
|
+
else
|
176
|
+
Integer(val)
|
177
|
+
end
|
178
|
+
|
179
|
+
@options[:force_shutdown_after] = i
|
180
|
+
end
|
181
|
+
|
162
182
|
# Code to run before doing a restart. This code should
|
163
183
|
# close logfiles, database connections, etc.
|
164
184
|
#
|
@@ -271,6 +291,15 @@ module Puma
|
|
271
291
|
_ary(:before_fork) << block
|
272
292
|
end
|
273
293
|
|
294
|
+
# *Cluster mode only* Code to run in a worker when it boots to setup
|
295
|
+
# the process before booting the app.
|
296
|
+
#
|
297
|
+
# This can be called multiple times to add hooks.
|
298
|
+
#
|
299
|
+
def on_worker_boot(&block)
|
300
|
+
_ary(:before_worker_boot) << block
|
301
|
+
end
|
302
|
+
|
274
303
|
# *Cluster mode only* Code to run immediately before a worker shuts
|
275
304
|
# down (after it has finished processing HTTP requests). These hooks
|
276
305
|
# can block if necessary to wait for background operations unknown
|
@@ -282,16 +311,7 @@ module Puma
|
|
282
311
|
_ary(:before_worker_shutdown) << block
|
283
312
|
end
|
284
313
|
|
285
|
-
# *Cluster mode only* Code to run
|
286
|
-
# the process before booting the app.
|
287
|
-
#
|
288
|
-
# This can be called multiple times to add hooks.
|
289
|
-
#
|
290
|
-
def on_worker_boot(&block)
|
291
|
-
_ary(:before_worker_boot) << block
|
292
|
-
end
|
293
|
-
|
294
|
-
# *Cluster mode only* Code to run when a master process is
|
314
|
+
# *Cluster mode only* Code to run in the master when it is
|
295
315
|
# about to create the worker by forking itself.
|
296
316
|
#
|
297
317
|
# This can be called multiple times to add hooks.
|
@@ -300,15 +320,17 @@ module Puma
|
|
300
320
|
_ary(:before_worker_fork) << block
|
301
321
|
end
|
302
322
|
|
303
|
-
# *Cluster mode only* Code to run
|
304
|
-
#
|
323
|
+
# *Cluster mode only* Code to run in the master after it starts
|
324
|
+
# a worker.
|
305
325
|
#
|
306
326
|
# This can be called multiple times to add hooks.
|
307
327
|
#
|
308
|
-
def
|
328
|
+
def after_worker_fork(&block)
|
309
329
|
_ary(:after_worker_fork) << block
|
310
330
|
end
|
311
331
|
|
332
|
+
alias_method :after_worker_boot, :after_worker_fork
|
333
|
+
|
312
334
|
# The directory to operate out of.
|
313
335
|
def directory(dir)
|
314
336
|
@options[:directory] = dir.to_s
|
data/lib/puma/launcher.rb
CHANGED
@@ -12,7 +12,7 @@ require 'puma/state_file'
|
|
12
12
|
require 'puma/commonlogger'
|
13
13
|
|
14
14
|
module Puma
|
15
|
-
#
|
15
|
+
# Puma::Launcher is the single entry point for starting a Puma server based on user
|
16
16
|
# configuration. It is responsible for taking user supplied arguments and resolving them
|
17
17
|
# with configuration in `config/puma.rb` or `config/puma/<env>.rb`.
|
18
18
|
#
|
@@ -7,22 +7,25 @@
|
|
7
7
|
#
|
8
8
|
|
9
9
|
module URI
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
10
|
+
begin
|
11
|
+
TBLENCWWWCOMP_ = {} # :nodoc:
|
12
|
+
256.times do |i|
|
13
|
+
TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
|
14
|
+
end
|
15
|
+
TBLENCWWWCOMP_[' '] = '+'
|
16
|
+
TBLENCWWWCOMP_.freeze
|
17
|
+
TBLDECWWWCOMP_ = {} # :nodoc:
|
18
|
+
256.times do |i|
|
19
|
+
h, l = i>>4, i&15
|
20
|
+
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
|
21
|
+
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
|
22
|
+
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
|
23
|
+
TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
|
24
|
+
end
|
25
|
+
TBLDECWWWCOMP_['+'] = ' '
|
26
|
+
TBLDECWWWCOMP_.freeze
|
27
|
+
rescue Exception
|
23
28
|
end
|
24
|
-
TBLDECWWWCOMP_['+'] = ' '
|
25
|
-
TBLDECWWWCOMP_.freeze
|
26
29
|
|
27
30
|
# Encode given +s+ to URL-encoded form data.
|
28
31
|
#
|
@@ -17,17 +17,20 @@
|
|
17
17
|
require 'uri/common'
|
18
18
|
|
19
19
|
module URI
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
begin
|
21
|
+
TBLDECWWWCOMP_ = {} unless const_defined?(:TBLDECWWWCOMP_) #:nodoc:
|
22
|
+
if TBLDECWWWCOMP_.empty?
|
23
|
+
256.times do |i|
|
24
|
+
h, l = i>>4, i&15
|
25
|
+
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
|
26
|
+
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
|
27
|
+
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
|
28
|
+
TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
|
29
|
+
end
|
30
|
+
TBLDECWWWCOMP_['+'] = ' '
|
31
|
+
TBLDECWWWCOMP_.freeze
|
28
32
|
end
|
29
|
-
|
30
|
-
TBLDECWWWCOMP_.freeze
|
33
|
+
rescue Exception
|
31
34
|
end
|
32
35
|
|
33
36
|
def self.decode_www_form(str, enc=Encoding::UTF_8)
|
@@ -8,22 +8,26 @@ require 'uri/common'
|
|
8
8
|
# Relevant commit:
|
9
9
|
# https://github.com/ruby/ruby/commit/edb7cdf1eabaff78dfa5ffedfbc2e91b29fa9ca1
|
10
10
|
|
11
|
+
|
11
12
|
module URI
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
begin
|
14
|
+
256.times do |i|
|
15
|
+
TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
|
16
|
+
end
|
17
|
+
TBLENCWWWCOMP_[' '] = '+'
|
18
|
+
TBLENCWWWCOMP_.freeze
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
24
30
|
end
|
25
|
-
TBLDECWWWCOMP_['+'] = ' '
|
26
|
-
TBLDECWWWCOMP_.freeze
|
27
31
|
end
|
28
32
|
|
29
33
|
# :startdoc:
|
data/lib/puma/reactor.rb
CHANGED
@@ -77,6 +77,8 @@ module Puma
|
|
77
77
|
|
78
78
|
# SSL handshake failure
|
79
79
|
rescue MiniSSL::SSLError => e
|
80
|
+
@server.lowlevel_error(e, c.env)
|
81
|
+
|
80
82
|
ssl_socket = c.io
|
81
83
|
addr = ssl_socket.peeraddr.last
|
82
84
|
cert = ssl_socket.peercert
|
@@ -88,6 +90,8 @@ module Puma
|
|
88
90
|
|
89
91
|
# The client doesn't know HTTP well
|
90
92
|
rescue HttpParserError => e
|
93
|
+
@server.lowlevel_error(e, c.env)
|
94
|
+
|
91
95
|
c.write_400
|
92
96
|
c.close
|
93
97
|
|
@@ -95,6 +99,8 @@ module Puma
|
|
95
99
|
|
96
100
|
@events.parse_error @server, c.env, e
|
97
101
|
rescue StandardError => e
|
102
|
+
@server.lowlevel_error(e, c.env)
|
103
|
+
|
98
104
|
c.write_500
|
99
105
|
c.close
|
100
106
|
|
data/lib/puma/server.rb
CHANGED
@@ -430,6 +430,8 @@ module Puma
|
|
430
430
|
|
431
431
|
# SSL handshake error
|
432
432
|
rescue MiniSSL::SSLError => e
|
433
|
+
lowlevel_error(e, client.env)
|
434
|
+
|
433
435
|
ssl_socket = client.io
|
434
436
|
addr = ssl_socket.peeraddr.last
|
435
437
|
cert = ssl_socket.peercert
|
@@ -440,12 +442,16 @@ module Puma
|
|
440
442
|
|
441
443
|
# The client doesn't know HTTP well
|
442
444
|
rescue HttpParserError => e
|
445
|
+
lowlevel_error(e, client.env)
|
446
|
+
|
443
447
|
client.write_400
|
444
448
|
|
445
449
|
@events.parse_error self, client.env, e
|
446
450
|
|
447
451
|
# Server error
|
448
452
|
rescue StandardError => e
|
453
|
+
lowlevel_error(e, client.env)
|
454
|
+
|
449
455
|
client.write_500
|
450
456
|
|
451
457
|
@events.unknown_error self, e, "Read"
|
@@ -486,6 +492,8 @@ module Puma
|
|
486
492
|
env[REQUEST_PATH] = uri.path
|
487
493
|
|
488
494
|
raise "No REQUEST PATH" unless env[REQUEST_PATH]
|
495
|
+
|
496
|
+
env[QUERY_STRING] = uri.query
|
489
497
|
end
|
490
498
|
|
491
499
|
env[PATH_INFO] = env[REQUEST_PATH]
|
@@ -571,6 +579,14 @@ module Puma
|
|
571
579
|
|
572
580
|
return :async
|
573
581
|
end
|
582
|
+
rescue ThreadPool::ForceShutdown => e
|
583
|
+
@events.log "Detected force shutdown of a thread, returning 503"
|
584
|
+
@events.unknown_error self, e, "Rack app"
|
585
|
+
|
586
|
+
status = 503
|
587
|
+
headers = {}
|
588
|
+
res_body = ["Request was internally terminated early\n"]
|
589
|
+
|
574
590
|
rescue StandardError => e
|
575
591
|
@events.unknown_error self, e, "Rack app"
|
576
592
|
|
@@ -723,7 +739,7 @@ module Puma
|
|
723
739
|
end
|
724
740
|
private :fetch_status_code
|
725
741
|
|
726
|
-
# Given the
|
742
|
+
# Given the request +env+ from +client+ and the partial body +body+
|
727
743
|
# plus a potential Content-Length value +cl+, finish reading
|
728
744
|
# the body and return it.
|
729
745
|
#
|
@@ -835,7 +851,13 @@ module Puma
|
|
835
851
|
@events.debug "Drained #{count} additional connections."
|
836
852
|
end
|
837
853
|
|
838
|
-
|
854
|
+
if @thread_pool
|
855
|
+
if timeout = @options[:force_shutdown_after]
|
856
|
+
@thread_pool.shutdown timeout.to_i
|
857
|
+
else
|
858
|
+
@thread_pool.shutdown
|
859
|
+
end
|
860
|
+
end
|
839
861
|
end
|
840
862
|
|
841
863
|
# Stops the acceptor thread and then causes the worker threads to finish
|
data/lib/puma/single.rb
CHANGED
data/lib/puma/thread_pool.rb
CHANGED
@@ -5,6 +5,9 @@ module Puma
|
|
5
5
|
#
|
6
6
|
class ThreadPool
|
7
7
|
|
8
|
+
class ForceShutdown < RuntimeError
|
9
|
+
end
|
10
|
+
|
8
11
|
# Maintain a minimum of +min+ and maximum of +max+ threads
|
9
12
|
# in the pool.
|
10
13
|
#
|
@@ -239,7 +242,7 @@ module Puma
|
|
239
242
|
|
240
243
|
# Tell all threads in the pool to exit and wait for them to finish.
|
241
244
|
#
|
242
|
-
def shutdown
|
245
|
+
def shutdown(timeout=-1)
|
243
246
|
threads = @mutex.synchronize do
|
244
247
|
@shutdown = true
|
245
248
|
@not_empty.broadcast
|
@@ -251,7 +254,38 @@ module Puma
|
|
251
254
|
@workers.dup
|
252
255
|
end
|
253
256
|
|
254
|
-
|
257
|
+
case timeout
|
258
|
+
when -1
|
259
|
+
threads.each(&:join)
|
260
|
+
when 0
|
261
|
+
threads.each do |t|
|
262
|
+
t.raise ForceShutdown
|
263
|
+
end
|
264
|
+
|
265
|
+
threads.each do |t|
|
266
|
+
t.join Const::SHUTDOWN_GRACE_TIME
|
267
|
+
end
|
268
|
+
else
|
269
|
+
timeout.times do
|
270
|
+
threads.delete_if do |t|
|
271
|
+
t.join 1
|
272
|
+
end
|
273
|
+
|
274
|
+
if threads.empty?
|
275
|
+
break
|
276
|
+
else
|
277
|
+
sleep 1
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
threads.each do |t|
|
282
|
+
t.raise ForceShutdown
|
283
|
+
end
|
284
|
+
|
285
|
+
threads.each do |t|
|
286
|
+
t.join Const::SHUTDOWN_GRACE_TIME
|
287
|
+
end
|
288
|
+
end
|
255
289
|
|
256
290
|
@spawned = 0
|
257
291
|
@workers = []
|
data/tools/jungle/init.d/puma
CHANGED
@@ -357,7 +357,7 @@ case "$1" in
|
|
357
357
|
;;
|
358
358
|
add)
|
359
359
|
if [ "$#" -lt 3 ]; then
|
360
|
-
echo "Please,
|
360
|
+
echo "Please, specify the app's directory and the user that will run it at least."
|
361
361
|
echo " Usage: $SCRIPTNAME add /path/to/app user /path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
|
362
362
|
echo " config and log are optionals."
|
363
363
|
exit 1
|
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: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|