puma 3.7.1 → 3.8.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.md +12 -0
- data/Manifest.txt +1 -0
- data/Release.md +9 -0
- data/lib/puma/cli.rb +26 -26
- data/lib/puma/client.rb +7 -0
- data/lib/puma/configuration.rb +115 -125
- data/lib/puma/const.rb +2 -2
- data/lib/puma/convenient.rb +3 -3
- data/lib/puma/dsl.rb +42 -49
- data/lib/puma/launcher.rb +4 -3
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/server.rb +16 -4
- data/lib/rack/handler/puma.rb +46 -20
- metadata +18 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 031dbe9ca0f1197eaf50d15b873064ef8e6a6e17
|
4
|
+
data.tar.gz: dc24ff6e9d693c62a860a649dfed4c201bd6458e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c671408260c12b1f24a93ac0f114d03574381936e5221b8c787f4180db672d453ef6058621a8c3104728f46b094b5cbb68021965f27196d1087d33b868675ee4
|
7
|
+
data.tar.gz: c4f36e2dbe262f02aee3477203c3a39ef7529a81cdf88d62d0e73710d42daa9f292a7c2868f0a54db91aa5f27fca21a59d8f38047d6983c0af5dfa6a41f64ac4
|
data/History.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## 3.8.0 / 2017-03-09
|
2
|
+
|
3
|
+
* bugfixes:
|
4
|
+
* Port from rack handler does not take precedence over config file in Rails 5.1.0.beta2+ and 5.0.1.rc3+ (#1234)
|
5
|
+
* The `tmp/restart.txt` plugin no longer restricts the user from running more than one server from the same folder at a time (#1226)
|
6
|
+
|
7
|
+
* features:
|
8
|
+
* Closed clients are aborted to save capacity (#1227)
|
9
|
+
|
10
|
+
* Refactors
|
11
|
+
* Bundler is no longer a dependency from tests (#1213)
|
12
|
+
|
1
13
|
## 3.7.1 / 2017-02-20
|
2
14
|
|
3
15
|
* 2 bugfixes:
|
data/Manifest.txt
CHANGED
data/Release.md
ADDED
data/lib/puma/cli.rb
CHANGED
@@ -47,21 +47,21 @@ module Puma
|
|
47
47
|
@parser.parse! @argv
|
48
48
|
|
49
49
|
if file = @argv.shift
|
50
|
-
@conf.configure do |
|
51
|
-
|
50
|
+
@conf.configure do |user_config, file_config|
|
51
|
+
file_config.rackup file
|
52
52
|
end
|
53
53
|
end
|
54
54
|
rescue UnsupportedOption
|
55
55
|
exit 1
|
56
56
|
end
|
57
57
|
|
58
|
-
@conf.configure do |
|
58
|
+
@conf.configure do |user_config, file_config|
|
59
59
|
if @stdout || @stderr
|
60
|
-
|
60
|
+
user_config.stdout_redirect @stdout, @stderr, @append
|
61
61
|
end
|
62
62
|
|
63
63
|
if @control_url
|
64
|
-
|
64
|
+
user_config.activate_control_app @control_url, @control_options
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -87,14 +87,14 @@ module Puma
|
|
87
87
|
#
|
88
88
|
|
89
89
|
def setup_options
|
90
|
-
@conf = Configuration.new do |
|
90
|
+
@conf = Configuration.new do |user_config, file_config|
|
91
91
|
@parser = OptionParser.new do |o|
|
92
92
|
o.on "-b", "--bind URI", "URI to bind to (tcp://, unix://, ssl://)" do |arg|
|
93
|
-
|
93
|
+
user_config.bind arg
|
94
94
|
end
|
95
95
|
|
96
96
|
o.on "-C", "--config PATH", "Load PATH as a config file" do |arg|
|
97
|
-
|
97
|
+
file_config.load arg
|
98
98
|
end
|
99
99
|
|
100
100
|
o.on "--control URL", "The bind url to use for the control server",
|
@@ -112,21 +112,21 @@ module Puma
|
|
112
112
|
end
|
113
113
|
|
114
114
|
o.on "-d", "--daemon", "Daemonize the server into the background" do
|
115
|
-
|
116
|
-
|
115
|
+
user_config.daemonize
|
116
|
+
user_config.quiet
|
117
117
|
end
|
118
118
|
|
119
119
|
o.on "--debug", "Log lowlevel debugging information" do
|
120
|
-
|
120
|
+
user_config.debug
|
121
121
|
end
|
122
122
|
|
123
123
|
o.on "--dir DIR", "Change to DIR before starting" do |d|
|
124
|
-
|
124
|
+
user_config.directory d
|
125
125
|
end
|
126
126
|
|
127
127
|
o.on "-e", "--environment ENVIRONMENT",
|
128
128
|
"The environment to run the Rack app on (default development)" do |arg|
|
129
|
-
|
129
|
+
user_config.environment arg
|
130
130
|
end
|
131
131
|
|
132
132
|
o.on "-I", "--include PATH", "Specify $LOAD_PATH directories" do |arg|
|
@@ -135,50 +135,50 @@ module Puma
|
|
135
135
|
|
136
136
|
o.on "-p", "--port PORT", "Define the TCP port to bind to",
|
137
137
|
"Use -b for more advanced options" do |arg|
|
138
|
-
|
138
|
+
user_config.bind "tcp://#{Configuration::DefaultTCPHost}:#{arg}"
|
139
139
|
end
|
140
140
|
|
141
141
|
o.on "--pidfile PATH", "Use PATH as a pidfile" do |arg|
|
142
|
-
|
142
|
+
user_config.pidfile arg
|
143
143
|
end
|
144
144
|
|
145
145
|
o.on "--preload", "Preload the app. Cluster mode only" do
|
146
|
-
|
146
|
+
user_config.preload_app!
|
147
147
|
end
|
148
148
|
|
149
149
|
o.on "--prune-bundler", "Prune out the bundler env if possible" do
|
150
|
-
|
150
|
+
user_config.prune_bundler
|
151
151
|
end
|
152
152
|
|
153
153
|
o.on "-q", "--quiet", "Do not log requests internally (default true)" do
|
154
|
-
|
154
|
+
user_config.quiet
|
155
155
|
end
|
156
156
|
|
157
157
|
o.on "-v", "--log-requests", "Log requests as they occur" do
|
158
|
-
|
158
|
+
user_config.log_requests
|
159
159
|
end
|
160
160
|
|
161
161
|
o.on "-R", "--restart-cmd CMD",
|
162
162
|
"The puma command to run during a hot restart",
|
163
163
|
"Default: inferred" do |cmd|
|
164
|
-
|
164
|
+
user_config.restart_command cmd
|
165
165
|
end
|
166
166
|
|
167
167
|
o.on "-S", "--state PATH", "Where to store the state details" do |arg|
|
168
|
-
|
168
|
+
user_config.state_path arg
|
169
169
|
end
|
170
170
|
|
171
171
|
o.on '-t', '--threads INT', "min:max threads to use (default 0:16)" do |arg|
|
172
172
|
min, max = arg.split(":")
|
173
173
|
if max
|
174
|
-
|
174
|
+
user_config.threads min, max
|
175
175
|
else
|
176
|
-
|
176
|
+
user_config.threads min, min
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
180
|
o.on "--tcp-mode", "Run the app in raw TCP mode instead of HTTP mode" do
|
181
|
-
|
181
|
+
user_config.tcp_mode!
|
182
182
|
end
|
183
183
|
|
184
184
|
o.on "-V", "--version", "Print the version information" do
|
@@ -188,11 +188,11 @@ module Puma
|
|
188
188
|
|
189
189
|
o.on "-w", "--workers COUNT",
|
190
190
|
"Activate cluster mode: How many worker processes to create" do |arg|
|
191
|
-
|
191
|
+
user_config.workers arg
|
192
192
|
end
|
193
193
|
|
194
194
|
o.on "--tag NAME", "Additional text to display in process listing" do |arg|
|
195
|
-
|
195
|
+
user_config.tag arg
|
196
196
|
end
|
197
197
|
|
198
198
|
o.on "--redirect-stdout FILE", "Redirect STDOUT to a specific file" do |arg|
|
data/lib/puma/client.rb
CHANGED
@@ -216,6 +216,13 @@ module Puma
|
|
216
216
|
end
|
217
217
|
|
218
218
|
def setup_body
|
219
|
+
if @env[HTTP_EXPECT] == CONTINUE
|
220
|
+
# TODO allow a hook here to check the headers before
|
221
|
+
# going forward
|
222
|
+
@io << HTTP_11_100
|
223
|
+
@io.flush
|
224
|
+
end
|
225
|
+
|
219
226
|
@read_header = false
|
220
227
|
|
221
228
|
body = @parser.body
|
data/lib/puma/configuration.rb
CHANGED
@@ -13,152 +13,147 @@ module Puma
|
|
13
13
|
DefaultWorkerShutdownTimeout = 30
|
14
14
|
end
|
15
15
|
|
16
|
-
class
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
16
|
+
# A class used for storing "leveled" configuration options.
|
17
|
+
#
|
18
|
+
# In this class any "user" specified options take precedence over any
|
19
|
+
# "file" specified options, take precedence over any "default" options.
|
20
|
+
#
|
21
|
+
# User input is prefered over "defaults":
|
22
|
+
# user_options = { foo: "bar" }
|
23
|
+
# default_options = { foo: "zoo" }
|
24
|
+
# options = UserFileDefaultOptions.new(user_options, default_options)
|
25
|
+
# puts options[:foo]
|
26
|
+
# # => "bar"
|
27
|
+
#
|
28
|
+
# All values can be accessed via `all_of`
|
29
|
+
#
|
30
|
+
# puts options.all_of(:foo)
|
31
|
+
# # => ["bar", "zoo"]
|
32
|
+
#
|
33
|
+
# A "file" option can be set. This config will be prefered over "default" options
|
34
|
+
# but will defer to any available "user" specified options.
|
35
|
+
#
|
36
|
+
# user_options = { foo: "bar" }
|
37
|
+
# default_options = { rackup: "zoo.rb" }
|
38
|
+
# options = UserFileDefaultOptions.new(user_options, default_options)
|
39
|
+
# options.file_options[:rackup] = "sup.rb"
|
40
|
+
# puts options[:rackup]
|
41
|
+
# # => "sup.rb"
|
42
|
+
#
|
43
|
+
# The "default" options can be set via procs. These are resolved during runtime
|
44
|
+
# via calls to `finalize_values`
|
45
|
+
class UserFileDefaultOptions
|
46
|
+
def initialize(user_options, default_options)
|
47
|
+
@user_options = user_options
|
48
|
+
@file_options = {}
|
49
|
+
@default_options = default_options
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_reader :user_options, :file_options, :default_options
|
37
53
|
|
38
54
|
def [](key)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
v = @defaults[key]
|
46
|
-
if v.respond_to? :call
|
47
|
-
v.call
|
48
|
-
else
|
49
|
-
v
|
50
|
-
end
|
55
|
+
return user_options[key] if user_options.key?(key)
|
56
|
+
return file_options[key] if file_options.key?(key)
|
57
|
+
return default_options[key] if default_options.key?(key)
|
51
58
|
end
|
52
59
|
|
53
|
-
def
|
54
|
-
|
55
|
-
return val if val
|
56
|
-
default
|
60
|
+
def []=(key, value)
|
61
|
+
user_options[key] = value
|
57
62
|
end
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
def all_of(key)
|
62
|
-
all = []
|
63
|
-
|
64
|
-
@set.each do |o|
|
65
|
-
if v = o[key]
|
66
|
-
if v.kind_of? Array
|
67
|
-
all += v
|
68
|
-
else
|
69
|
-
all << v
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
all
|
75
|
-
end
|
76
|
-
|
77
|
-
def []=(key, val)
|
78
|
-
@cur[key] = val
|
64
|
+
def fetch(key, default_value = nil)
|
65
|
+
self[key] || default_value
|
79
66
|
end
|
80
67
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
@default.key? key
|
89
|
-
end
|
90
|
-
|
91
|
-
def merge!(o)
|
92
|
-
o.each do |k,v|
|
93
|
-
@cur[k]= v
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def flatten
|
98
|
-
options = {}
|
99
|
-
|
100
|
-
@set.each do |o|
|
101
|
-
o.each do |k,v|
|
102
|
-
options[k] ||= v
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
options
|
107
|
-
end
|
68
|
+
def all_of(key)
|
69
|
+
user = user_options[key]
|
70
|
+
file = file_options[key]
|
71
|
+
default = default_options[key]
|
108
72
|
|
109
|
-
|
110
|
-
|
73
|
+
user = [user] unless user.is_a?(Array)
|
74
|
+
file = [file] unless file.is_a?(Array)
|
75
|
+
default = [default] unless default.is_a?(Array)
|
111
76
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
77
|
+
user.compact!
|
78
|
+
file.compact!
|
79
|
+
default.compact!
|
116
80
|
|
117
|
-
|
118
|
-
end
|
81
|
+
user + file + default
|
119
82
|
end
|
120
83
|
|
121
|
-
def
|
122
|
-
@
|
84
|
+
def finalize_values
|
85
|
+
@default_options.each do |k,v|
|
123
86
|
if v.respond_to? :call
|
124
|
-
@
|
87
|
+
@default_options[k] = v.call
|
125
88
|
end
|
126
89
|
end
|
127
90
|
end
|
128
91
|
end
|
129
92
|
|
93
|
+
# The main configuration class of Puma.
|
94
|
+
#
|
95
|
+
# It can be initialized with a set of "user" options and "default" options.
|
96
|
+
# Defaults will be merged with `Configuration.puma_default_options`.
|
97
|
+
#
|
98
|
+
# This class works together with 2 main other classes the `UserFileDefaultOptions`
|
99
|
+
# which stores configuration options in order so the precedence is that user
|
100
|
+
# set configuration wins over "file" based configuration wins over "default"
|
101
|
+
# configuration. These configurations are set via the `DSL` class. This
|
102
|
+
# class powers the Puma config file syntax and does double duty as a configuration
|
103
|
+
# DSL used by the `Puma::CLI` and Puma rack handler.
|
104
|
+
#
|
105
|
+
# It also handles loading plugins.
|
106
|
+
#
|
107
|
+
# > Note: `:port` and `:host` are not valid keys. By they time they make it to the
|
108
|
+
# configuration options they are expected to be incorporated into a `:binds` key.
|
109
|
+
# Under the hood the DSL maps `port` and `host` calls to `:binds`
|
110
|
+
#
|
111
|
+
# config = Configuration.new({}) do |user_config, file_config, default_config|
|
112
|
+
# user_config.port 3003
|
113
|
+
# end
|
114
|
+
# config.load
|
115
|
+
# puts config.options[:port]
|
116
|
+
# # => 3003
|
117
|
+
#
|
118
|
+
# It is expected that `load` is called on the configuration instance after setting
|
119
|
+
# config. This method expands any values in `config_file` and puts them into the
|
120
|
+
# correct configuration option hash.
|
121
|
+
#
|
122
|
+
# Once all configuration is complete it is expected that `clamp` will be called
|
123
|
+
# on the instance. This will expand any procs stored under "default" values. This
|
124
|
+
# is done because an environment variable may have been modified while loading
|
125
|
+
# configuration files.
|
130
126
|
class Configuration
|
131
127
|
include ConfigDefault
|
132
128
|
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
DSL.new(cfg.options, cfg)._load_from path
|
129
|
+
def initialize(user_options={}, default_options = {}, &block)
|
130
|
+
default_options = self.puma_default_options.merge(default_options)
|
137
131
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
@
|
143
|
-
|
144
|
-
@plugins = PluginLoader.new
|
132
|
+
@options = UserFileDefaultOptions.new(user_options, default_options)
|
133
|
+
@plugins = PluginLoader.new
|
134
|
+
@user_dsl = DSL.new(@options.user_options, self)
|
135
|
+
@file_dsl = DSL.new(@options.file_options, self)
|
136
|
+
@default_dsl = DSL.new(@options.default_options, self)
|
145
137
|
|
146
|
-
if
|
147
|
-
configure(&
|
138
|
+
if block
|
139
|
+
configure(&block)
|
148
140
|
end
|
149
141
|
end
|
150
142
|
|
151
143
|
attr_reader :options, :plugins
|
152
144
|
|
153
|
-
def configure
|
154
|
-
@
|
155
|
-
|
145
|
+
def configure
|
146
|
+
yield @user_dsl, @file_dsl, @default_dsl
|
147
|
+
ensure
|
148
|
+
@user_dsl._offer_plugins
|
149
|
+
@file_dsl._offer_plugins
|
150
|
+
@default_dsl._offer_plugins
|
156
151
|
end
|
157
152
|
|
158
153
|
def initialize_copy(other)
|
159
|
-
@conf
|
154
|
+
@conf = nil
|
160
155
|
@cli_options = nil
|
161
|
-
@options
|
156
|
+
@options = @options.dup
|
162
157
|
end
|
163
158
|
|
164
159
|
def flatten
|
@@ -170,7 +165,7 @@ module Puma
|
|
170
165
|
self
|
171
166
|
end
|
172
167
|
|
173
|
-
def
|
168
|
+
def puma_default_options
|
174
169
|
{
|
175
170
|
:min_threads => 0,
|
176
171
|
:max_threads => 16,
|
@@ -185,7 +180,7 @@ module Puma
|
|
185
180
|
:worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
|
186
181
|
:remote_address => :socket,
|
187
182
|
:tag => method(:infer_tag),
|
188
|
-
:environment =>
|
183
|
+
:environment => ->{ ENV['RACK_ENV'] || "development" },
|
189
184
|
:rackup => DefaultRackup,
|
190
185
|
:logger => STDOUT,
|
191
186
|
:persistent_timeout => Const::PERSISTENT_TIMEOUT
|
@@ -206,18 +201,15 @@ module Puma
|
|
206
201
|
end
|
207
202
|
|
208
203
|
files.each do |f|
|
209
|
-
@
|
210
|
-
|
211
|
-
DSL.load @options, self, f
|
204
|
+
@file_dsl._load_from(f)
|
212
205
|
end
|
213
|
-
@options
|
206
|
+
@options
|
214
207
|
end
|
215
208
|
|
216
209
|
# Call once all configuration (included from rackup files)
|
217
210
|
# is loaded to flesh out any defaults
|
218
211
|
def clamp
|
219
|
-
@options.
|
220
|
-
@options.force_defaults
|
212
|
+
@options.finalize_values
|
221
213
|
end
|
222
214
|
|
223
215
|
# Injects the Configuration object into the env
|
@@ -318,17 +310,15 @@ module Puma
|
|
318
310
|
def load_rackup
|
319
311
|
raise "Missing rackup file '#{rackup}'" unless File.exist?(rackup)
|
320
312
|
|
321
|
-
@options.shift
|
322
|
-
|
323
313
|
rack_app, rack_options = rack_builder.parse_file(rackup)
|
324
|
-
@options.merge!(rack_options)
|
314
|
+
@options.file_options.merge!(rack_options)
|
325
315
|
|
326
316
|
config_ru_binds = []
|
327
317
|
rack_options.each do |k, v|
|
328
318
|
config_ru_binds << v if k.to_s.start_with?("bind")
|
329
319
|
end
|
330
320
|
|
331
|
-
@options[:binds] = config_ru_binds unless config_ru_binds.empty?
|
321
|
+
@options.file_options[:binds] = config_ru_binds unless config_ru_binds.empty?
|
332
322
|
|
333
323
|
rack_app
|
334
324
|
end
|
data/lib/puma/const.rb
CHANGED
@@ -95,8 +95,8 @@ module Puma
|
|
95
95
|
# too taxing on performance.
|
96
96
|
module Const
|
97
97
|
|
98
|
-
PUMA_VERSION = VERSION = "3.
|
99
|
-
CODE_NAME = "
|
98
|
+
PUMA_VERSION = VERSION = "3.8.0".freeze
|
99
|
+
CODE_NAME = "Sassy Salamander".freeze
|
100
100
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
101
101
|
|
102
102
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
data/lib/puma/convenient.rb
CHANGED
@@ -3,12 +3,12 @@ require 'puma/configuration'
|
|
3
3
|
|
4
4
|
module Puma
|
5
5
|
def self.run(opts={})
|
6
|
-
cfg = Puma::Configuration.new do |
|
6
|
+
cfg = Puma::Configuration.new do |user_config|
|
7
7
|
if port = opts[:port]
|
8
|
-
|
8
|
+
user_config.port port
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
user_config.quiet
|
12
12
|
|
13
13
|
yield c
|
14
14
|
end
|
data/lib/puma/dsl.rb
CHANGED
@@ -1,20 +1,35 @@
|
|
1
1
|
module Puma
|
2
2
|
# The methods that are available for use inside the config file.
|
3
|
+
# These same methods are used in Puma cli and the rack handler
|
4
|
+
# internally.
|
3
5
|
#
|
6
|
+
# Used manually (via CLI class):
|
7
|
+
#
|
8
|
+
# config = Configuration.new({}) do |user_config|
|
9
|
+
# user_config.port 3001
|
10
|
+
# end
|
11
|
+
# config.load
|
12
|
+
#
|
13
|
+
# puts config.options[:binds]
|
14
|
+
# "tcp://127.0.0.1:3001"
|
15
|
+
#
|
16
|
+
# Used to load file:
|
17
|
+
#
|
18
|
+
# $ cat puma_config.rb
|
19
|
+
# port 3002
|
20
|
+
#
|
21
|
+
# config = Configuration.new(config_file: "puma_config.rb")
|
22
|
+
# config.load
|
23
|
+
#
|
24
|
+
# puts config.options[:binds]
|
25
|
+
# # => "tcp://127.0.0.1:3002"
|
26
|
+
#
|
27
|
+
# Detailed docs can be found in `examples/config.rb`
|
4
28
|
class DSL
|
5
29
|
include ConfigDefault
|
6
30
|
|
7
|
-
def self.load(options, cfg, path)
|
8
|
-
d = new(options, cfg)
|
9
|
-
d._load_from(path)
|
10
|
-
|
11
|
-
options
|
12
|
-
ensure
|
13
|
-
d._offer_plugins
|
14
|
-
end
|
15
|
-
|
16
31
|
def initialize(options, config)
|
17
|
-
@config
|
32
|
+
@config = config
|
18
33
|
@options = options
|
19
34
|
|
20
35
|
@plugins = []
|
@@ -40,36 +55,10 @@ module Puma
|
|
40
55
|
@plugins.clear
|
41
56
|
end
|
42
57
|
|
43
|
-
def _run(&blk)
|
44
|
-
blk.call self
|
45
|
-
ensure
|
46
|
-
_offer_plugins
|
47
|
-
end
|
48
|
-
|
49
58
|
def inject(&blk)
|
50
59
|
instance_eval(&blk)
|
51
60
|
end
|
52
61
|
|
53
|
-
# Load configuration from another named file. If the file name is absolute,
|
54
|
-
# load the file as an absolute path. Otherwise load it relative to the
|
55
|
-
# current config file.
|
56
|
-
#
|
57
|
-
def import(file)
|
58
|
-
if File.extname(file) == ""
|
59
|
-
file += ".rb"
|
60
|
-
end
|
61
|
-
|
62
|
-
if file[0,1] == "/"
|
63
|
-
path = file
|
64
|
-
elsif @path
|
65
|
-
path = File.join File.dirname(@path), file
|
66
|
-
else
|
67
|
-
raise "No original configuration path to import relative to"
|
68
|
-
end
|
69
|
-
|
70
|
-
DSL.new(@options, @config)._load_from(path)
|
71
|
-
end
|
72
|
-
|
73
62
|
def get(key,default=nil)
|
74
63
|
@options[key.to_sym] || default
|
75
64
|
end
|
@@ -115,15 +104,18 @@ module Puma
|
|
115
104
|
end
|
116
105
|
|
117
106
|
# Load additional configuration from a file
|
107
|
+
# Files get loaded later via Configuration#load
|
118
108
|
def load(file)
|
119
|
-
|
109
|
+
@options[:config_files] ||= []
|
110
|
+
@options[:config_files] << file
|
120
111
|
end
|
121
112
|
|
122
113
|
# Bind the server to +url+. tcp:// and unix:// are the only accepted
|
123
114
|
# protocols.
|
124
115
|
#
|
125
116
|
def bind(url)
|
126
|
-
|
117
|
+
@options[:binds] ||= []
|
118
|
+
@options[:binds] << url
|
127
119
|
end
|
128
120
|
|
129
121
|
# Define the TCP port to bind to. Use +bind+ for more advanced options.
|
@@ -192,7 +184,8 @@ module Puma
|
|
192
184
|
# This can be called multiple times to add code each time.
|
193
185
|
#
|
194
186
|
def on_restart(&block)
|
195
|
-
|
187
|
+
@options[:on_restart] ||= []
|
188
|
+
@options[:on_restart] << block
|
196
189
|
end
|
197
190
|
|
198
191
|
# Command to use to restart puma. This should be just how to
|
@@ -297,7 +290,8 @@ module Puma
|
|
297
290
|
# This can be called multiple times to add hooks.
|
298
291
|
#
|
299
292
|
def before_fork(&block)
|
300
|
-
|
293
|
+
@options[:before_fork] ||= []
|
294
|
+
@options[:before_fork] << block
|
301
295
|
end
|
302
296
|
|
303
297
|
# *Cluster mode only* Code to run in a worker when it boots to setup
|
@@ -306,7 +300,8 @@ module Puma
|
|
306
300
|
# This can be called multiple times to add hooks.
|
307
301
|
#
|
308
302
|
def on_worker_boot(&block)
|
309
|
-
|
303
|
+
@options[:before_worker_boot] ||= []
|
304
|
+
@options[:before_worker_boot] << block
|
310
305
|
end
|
311
306
|
|
312
307
|
# *Cluster mode only* Code to run immediately before a worker shuts
|
@@ -317,7 +312,8 @@ module Puma
|
|
317
312
|
# This can be called multiple times to add hooks.
|
318
313
|
#
|
319
314
|
def on_worker_shutdown(&block)
|
320
|
-
|
315
|
+
@options[:before_worker_shutdown] ||= []
|
316
|
+
@options[:before_worker_shutdown] << block
|
321
317
|
end
|
322
318
|
|
323
319
|
# *Cluster mode only* Code to run in the master when it is
|
@@ -326,7 +322,8 @@ module Puma
|
|
326
322
|
# This can be called multiple times to add hooks.
|
327
323
|
#
|
328
324
|
def on_worker_fork(&block)
|
329
|
-
|
325
|
+
@options[:before_worker_fork] ||= []
|
326
|
+
@options[:before_worker_fork] << block
|
330
327
|
end
|
331
328
|
|
332
329
|
# *Cluster mode only* Code to run in the master after it starts
|
@@ -335,7 +332,8 @@ module Puma
|
|
335
332
|
# This can be called multiple times to add hooks.
|
336
333
|
#
|
337
334
|
def after_worker_fork(&block)
|
338
|
-
|
335
|
+
@options[:after_worker_fork] ||= []
|
336
|
+
@options[:after_worker_fork] = block
|
339
337
|
end
|
340
338
|
|
341
339
|
alias_method :after_worker_boot, :after_worker_fork
|
@@ -477,10 +475,5 @@ module Puma
|
|
477
475
|
end
|
478
476
|
end
|
479
477
|
|
480
|
-
private
|
481
|
-
|
482
|
-
def _ary(key)
|
483
|
-
(@options.cur[key] ||= [])
|
484
|
-
end
|
485
478
|
end
|
486
479
|
end
|
data/lib/puma/launcher.rb
CHANGED
@@ -34,9 +34,9 @@ module Puma
|
|
34
34
|
#
|
35
35
|
# Examples:
|
36
36
|
#
|
37
|
-
# conf = Puma::Configuration.new do |
|
38
|
-
#
|
39
|
-
#
|
37
|
+
# conf = Puma::Configuration.new do |user_config|
|
38
|
+
# user_config.threads 1, 10
|
39
|
+
# user_config.app do |env|
|
40
40
|
# [200, {}, ["hello world"]]
|
41
41
|
# end
|
42
42
|
# end
|
@@ -59,6 +59,7 @@ module Puma
|
|
59
59
|
@config.load
|
60
60
|
|
61
61
|
@options = @config.options
|
62
|
+
@config.clamp
|
62
63
|
|
63
64
|
generate_restart_data
|
64
65
|
|
data/lib/puma/server.rb
CHANGED
@@ -100,6 +100,8 @@ module Puma
|
|
100
100
|
# packetizes our stream. This improves both latency and throughput.
|
101
101
|
#
|
102
102
|
if RUBY_PLATFORM =~ /linux/
|
103
|
+
UNPACK_TCP_STATE_FROM_TCP_INFO = "C".freeze
|
104
|
+
|
103
105
|
# 6 == Socket::IPPROTO_TCP
|
104
106
|
# 3 == TCP_CORK
|
105
107
|
# 1/0 == turn on/off
|
@@ -116,12 +118,24 @@ module Puma
|
|
116
118
|
rescue IOError, SystemCallError
|
117
119
|
end
|
118
120
|
end
|
121
|
+
|
122
|
+
def closed_socket?(socket)
|
123
|
+
return false unless socket.kind_of? TCPSocket
|
124
|
+
tcp_info = socket.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO)
|
125
|
+
state = tcp_info.unpack(UNPACK_TCP_STATE_FROM_TCP_INFO)[0]
|
126
|
+
# TIME_WAIT: 6, CLOSE: 7, CLOSE_WAIT: 8, LAST_ACK: 9, CLOSING: 11
|
127
|
+
(state >= 6 && state <= 9) || state == 11
|
128
|
+
end
|
119
129
|
else
|
120
130
|
def cork_socket(socket)
|
121
131
|
end
|
122
132
|
|
123
133
|
def uncork_socket(socket)
|
124
134
|
end
|
135
|
+
|
136
|
+
def closed_socket?(socket)
|
137
|
+
false
|
138
|
+
end
|
125
139
|
end
|
126
140
|
|
127
141
|
def backlog
|
@@ -404,10 +418,6 @@ module Puma
|
|
404
418
|
def process_client(client, buffer)
|
405
419
|
begin
|
406
420
|
|
407
|
-
if client.env[HTTP_EXPECT] == CONTINUE
|
408
|
-
client.io << HTTP_11_100
|
409
|
-
end
|
410
|
-
|
411
421
|
clean_thread_locals = @options[:clean_thread_locals]
|
412
422
|
close_socket = true
|
413
423
|
|
@@ -550,6 +560,8 @@ module Puma
|
|
550
560
|
env = req.env
|
551
561
|
client = req.io
|
552
562
|
|
563
|
+
return false if closed_socket?(client)
|
564
|
+
|
553
565
|
normalize_env env, req
|
554
566
|
|
555
567
|
env[PUMA_SOCKET] = client
|
data/lib/rack/handler/puma.rb
CHANGED
@@ -8,46 +8,52 @@ module Rack
|
|
8
8
|
:Silent => false
|
9
9
|
}
|
10
10
|
|
11
|
-
def self.
|
11
|
+
def self.config(app, options = {})
|
12
12
|
require 'puma/configuration'
|
13
13
|
require 'puma/events'
|
14
14
|
require 'puma/launcher'
|
15
15
|
|
16
|
-
|
16
|
+
default_options = DEFAULT_OPTIONS.dup
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
# Libraries pass in values such as :Port and there is no way to determine
|
19
|
+
# if it is a default provided by the library or a special value provided
|
20
|
+
# by the user. A special key `user_supplied_options` can be passed. This
|
21
|
+
# contains an array of all explicitly defined user options. We then
|
22
|
+
# know that all other values are defaults
|
23
|
+
if user_supplied_options = options.delete(:user_supplied_options)
|
24
|
+
(options.keys - user_supplied_options).each do |k, v|
|
25
|
+
default_options[k] = options.delete(k)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
|
30
|
+
user_config.quiet
|
20
31
|
|
21
32
|
if options.delete(:Verbose)
|
22
33
|
app = Rack::CommonLogger.new(app, STDOUT)
|
23
34
|
end
|
24
35
|
|
25
36
|
if options[:environment]
|
26
|
-
|
37
|
+
user_config.environment options[:environment]
|
27
38
|
end
|
28
39
|
|
29
40
|
if options[:Threads]
|
30
41
|
min, max = options.delete(:Threads).split(':', 2)
|
31
|
-
|
42
|
+
user_config.threads min, max
|
32
43
|
end
|
33
44
|
|
34
|
-
|
45
|
+
self.set_host_port_to_config(options[:Host], options[:Port], user_config)
|
46
|
+
self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
|
35
47
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
uri.port ||= options[:Port] || ::Puma::Configuration::DefaultTCPPort
|
41
|
-
c.bind uri.to_s
|
42
|
-
else
|
43
|
-
host ||= ::Puma::Configuration::DefaultTCPHost
|
44
|
-
port = options[:Port] || ::Puma::Configuration::DefaultTCPPort
|
48
|
+
user_config.app app
|
49
|
+
end
|
50
|
+
conf
|
51
|
+
end
|
45
52
|
|
46
|
-
c.port port, host
|
47
|
-
end
|
48
53
|
|
49
|
-
|
50
|
-
|
54
|
+
|
55
|
+
def self.run(app, options = {})
|
56
|
+
conf = self.config(app, options)
|
51
57
|
|
52
58
|
events = options.delete(:Silent) ? ::Puma::Events.strings : ::Puma::Events.stdio
|
53
59
|
|
@@ -71,6 +77,26 @@ module Rack
|
|
71
77
|
"Verbose" => "Don't report each request (default: false)"
|
72
78
|
}
|
73
79
|
end
|
80
|
+
private
|
81
|
+
def self.set_host_port_to_config(host, port, config)
|
82
|
+
if host && (host[0,1] == '.' || host[0,1] == '/')
|
83
|
+
config.bind "unix://#{host}"
|
84
|
+
elsif host && host =~ /^ssl:\/\//
|
85
|
+
uri = URI.parse(host)
|
86
|
+
uri.port ||= port || ::Puma::Configuration::DefaultTCPPort
|
87
|
+
config.bind uri.to_s
|
88
|
+
else
|
89
|
+
|
90
|
+
if host
|
91
|
+
port ||= ::Puma::Configuration::DefaultTCPPort
|
92
|
+
end
|
93
|
+
|
94
|
+
if port
|
95
|
+
host ||= ::Puma::Configuration::DefaultTCPHost
|
96
|
+
config.port port, host
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
74
100
|
end
|
75
101
|
|
76
102
|
register :puma, Puma
|
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: 3.
|
4
|
+
version: 3.8.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: 2017-
|
11
|
+
date: 2017-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rdoc
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rack
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,20 +58,6 @@ dependencies:
|
|
44
58
|
- - "~>"
|
45
59
|
- !ruby/object:Gem::Version
|
46
60
|
version: '0.8'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: rdoc
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - "~>"
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '4.0'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - "~>"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '4.0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: hoe
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -89,6 +89,7 @@ extra_rdoc_files:
|
|
89
89
|
- History.md
|
90
90
|
- Manifest.txt
|
91
91
|
- README.md
|
92
|
+
- Release.md
|
92
93
|
- docs/nginx.md
|
93
94
|
- docs/signals.md
|
94
95
|
- docs/systemd.md
|
@@ -104,6 +105,7 @@ files:
|
|
104
105
|
- Manifest.txt
|
105
106
|
- README.md
|
106
107
|
- Rakefile
|
108
|
+
- Release.md
|
107
109
|
- bin/puma
|
108
110
|
- bin/puma-wild
|
109
111
|
- bin/pumactl
|