puma-simon 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/.github/issue_template.md +20 -0
  3. data/.gitignore +18 -0
  4. data/.hoeignore +12 -0
  5. data/.travis.yml +29 -0
  6. data/DEPLOYMENT.md +91 -0
  7. data/Gemfile +12 -0
  8. data/History.md +1254 -0
  9. data/LICENSE +26 -0
  10. data/Manifest.txt +78 -0
  11. data/README.md +353 -0
  12. data/Rakefile +158 -0
  13. data/Release.md +9 -0
  14. data/bin/puma +10 -0
  15. data/bin/puma-wild +31 -0
  16. data/bin/pumactl +12 -0
  17. data/docs/nginx.md +80 -0
  18. data/docs/signals.md +43 -0
  19. data/docs/systemd.md +197 -0
  20. data/examples/CA/cacert.pem +23 -0
  21. data/examples/CA/newcerts/cert_1.pem +19 -0
  22. data/examples/CA/newcerts/cert_2.pem +19 -0
  23. data/examples/CA/private/cakeypair.pem +30 -0
  24. data/examples/CA/serial +1 -0
  25. data/examples/config.rb +200 -0
  26. data/examples/plugins/redis_stop_puma.rb +46 -0
  27. data/examples/puma/cert_puma.pem +19 -0
  28. data/examples/puma/client-certs/ca.crt +19 -0
  29. data/examples/puma/client-certs/ca.key +27 -0
  30. data/examples/puma/client-certs/client.crt +19 -0
  31. data/examples/puma/client-certs/client.key +27 -0
  32. data/examples/puma/client-certs/client_expired.crt +19 -0
  33. data/examples/puma/client-certs/client_expired.key +27 -0
  34. data/examples/puma/client-certs/client_unknown.crt +19 -0
  35. data/examples/puma/client-certs/client_unknown.key +27 -0
  36. data/examples/puma/client-certs/generate.rb +78 -0
  37. data/examples/puma/client-certs/keystore.jks +0 -0
  38. data/examples/puma/client-certs/server.crt +19 -0
  39. data/examples/puma/client-certs/server.key +27 -0
  40. data/examples/puma/client-certs/server.p12 +0 -0
  41. data/examples/puma/client-certs/unknown_ca.crt +19 -0
  42. data/examples/puma/client-certs/unknown_ca.key +27 -0
  43. data/examples/puma/csr_puma.pem +11 -0
  44. data/examples/puma/keystore.jks +0 -0
  45. data/examples/puma/puma_keypair.pem +15 -0
  46. data/examples/qc_config.rb +13 -0
  47. data/ext/puma_http11/PumaHttp11Service.java +17 -0
  48. data/ext/puma_http11/ext_help.h +15 -0
  49. data/ext/puma_http11/extconf.rb +15 -0
  50. data/ext/puma_http11/http11_parser.c +1069 -0
  51. data/ext/puma_http11/http11_parser.h +65 -0
  52. data/ext/puma_http11/http11_parser.java.rl +161 -0
  53. data/ext/puma_http11/http11_parser.rl +147 -0
  54. data/ext/puma_http11/http11_parser_common.rl +54 -0
  55. data/ext/puma_http11/io_buffer.c +155 -0
  56. data/ext/puma_http11/mini_ssl.c +457 -0
  57. data/ext/puma_http11/org/jruby/puma/Http11.java +234 -0
  58. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +473 -0
  59. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +339 -0
  60. data/ext/puma_http11/puma_http11.c +500 -0
  61. data/gemfiles/2.1-Gemfile +12 -0
  62. data/lib/puma.rb +15 -0
  63. data/lib/puma/accept_nonblock.rb +23 -0
  64. data/lib/puma/app/status.rb +66 -0
  65. data/lib/puma/binder.rb +402 -0
  66. data/lib/puma/cli.rb +220 -0
  67. data/lib/puma/client.rb +434 -0
  68. data/lib/puma/cluster.rb +510 -0
  69. data/lib/puma/commonlogger.rb +106 -0
  70. data/lib/puma/compat.rb +14 -0
  71. data/lib/puma/configuration.rb +364 -0
  72. data/lib/puma/const.rb +224 -0
  73. data/lib/puma/control_cli.rb +259 -0
  74. data/lib/puma/convenient.rb +23 -0
  75. data/lib/puma/daemon_ext.rb +31 -0
  76. data/lib/puma/delegation.rb +11 -0
  77. data/lib/puma/detect.rb +13 -0
  78. data/lib/puma/dsl.rb +486 -0
  79. data/lib/puma/events.rb +152 -0
  80. data/lib/puma/io_buffer.rb +7 -0
  81. data/lib/puma/java_io_buffer.rb +45 -0
  82. data/lib/puma/jruby_restart.rb +83 -0
  83. data/lib/puma/launcher.rb +410 -0
  84. data/lib/puma/minissl.rb +221 -0
  85. data/lib/puma/null_io.rb +42 -0
  86. data/lib/puma/plugin.rb +115 -0
  87. data/lib/puma/plugin/tmp_restart.rb +35 -0
  88. data/lib/puma/rack/backports/uri/common_193.rb +33 -0
  89. data/lib/puma/rack/builder.rb +298 -0
  90. data/lib/puma/rack/urlmap.rb +91 -0
  91. data/lib/puma/rack_default.rb +7 -0
  92. data/lib/puma/reactor.rb +210 -0
  93. data/lib/puma/runner.rb +171 -0
  94. data/lib/puma/server.rb +949 -0
  95. data/lib/puma/single.rb +112 -0
  96. data/lib/puma/state_file.rb +29 -0
  97. data/lib/puma/tcp_logger.rb +39 -0
  98. data/lib/puma/thread_pool.rb +297 -0
  99. data/lib/puma/util.rb +128 -0
  100. data/lib/rack/handler/puma.rb +78 -0
  101. data/puma.gemspec +52 -0
  102. data/test/ab_rs.rb +22 -0
  103. data/test/config.rb +2 -0
  104. data/test/config/app.rb +9 -0
  105. data/test/config/plugin.rb +1 -0
  106. data/test/config/settings.rb +2 -0
  107. data/test/config/state_file_testing_config.rb +14 -0
  108. data/test/hello-bind.ru +2 -0
  109. data/test/hello-delay.ru +3 -0
  110. data/test/hello-map.ru +3 -0
  111. data/test/hello-post.ru +4 -0
  112. data/test/hello-stuck.ru +1 -0
  113. data/test/hello-tcp.ru +5 -0
  114. data/test/hello.ru +1 -0
  115. data/test/hijack.ru +6 -0
  116. data/test/hijack2.ru +5 -0
  117. data/test/lobster.ru +4 -0
  118. data/test/shell/run.sh +24 -0
  119. data/test/shell/t1.rb +19 -0
  120. data/test/shell/t1_conf.rb +3 -0
  121. data/test/shell/t2.rb +17 -0
  122. data/test/shell/t2_conf.rb +6 -0
  123. data/test/shell/t3.rb +25 -0
  124. data/test/shell/t3_conf.rb +5 -0
  125. data/test/slow.ru +4 -0
  126. data/test/ssl_config.rb +4 -0
  127. data/test/test_app_status.rb +93 -0
  128. data/test/test_binder.rb +31 -0
  129. data/test/test_cli.rb +209 -0
  130. data/test/test_config.rb +95 -0
  131. data/test/test_events.rb +161 -0
  132. data/test/test_helper.rb +50 -0
  133. data/test/test_http10.rb +27 -0
  134. data/test/test_http11.rb +186 -0
  135. data/test/test_integration.rb +247 -0
  136. data/test/test_iobuffer.rb +39 -0
  137. data/test/test_minissl.rb +29 -0
  138. data/test/test_null_io.rb +49 -0
  139. data/test/test_persistent.rb +245 -0
  140. data/test/test_puma_server.rb +626 -0
  141. data/test/test_puma_server_ssl.rb +222 -0
  142. data/test/test_rack_handler.rb +57 -0
  143. data/test/test_rack_server.rb +138 -0
  144. data/test/test_tcp_logger.rb +39 -0
  145. data/test/test_tcp_rack.rb +36 -0
  146. data/test/test_thread_pool.rb +250 -0
  147. data/test/test_unix_socket.rb +35 -0
  148. data/test/test_web_server.rb +88 -0
  149. data/tools/jungle/README.md +9 -0
  150. data/tools/jungle/init.d/README.md +59 -0
  151. data/tools/jungle/init.d/puma +421 -0
  152. data/tools/jungle/init.d/run-puma +18 -0
  153. data/tools/jungle/upstart/README.md +61 -0
  154. data/tools/jungle/upstart/puma-manager.conf +31 -0
  155. data/tools/jungle/upstart/puma.conf +69 -0
  156. data/tools/trickletest.rb +45 -0
  157. metadata +297 -0
@@ -0,0 +1,23 @@
1
+ require 'puma/launcher'
2
+ require 'puma/configuration'
3
+
4
+ module Puma
5
+ def self.run(opts={})
6
+ cfg = Puma::Configuration.new do |c|
7
+ if port = opts[:port]
8
+ c.port port
9
+ end
10
+
11
+ c.quiet
12
+
13
+ yield c
14
+ end
15
+
16
+ cfg.clamp
17
+
18
+ events = Puma::Events.null
19
+
20
+ launcher = Puma::Launcher.new cfg, :events => events
21
+ launcher.run
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ module Process
2
+
3
+ # This overrides the default version because it is broken if it
4
+ # exists.
5
+
6
+ if respond_to? :daemon
7
+ class << self
8
+ remove_method :daemon
9
+ end
10
+ end
11
+
12
+ def self.daemon(nochdir=false, noclose=false)
13
+ exit if fork # Parent exits, child continues.
14
+
15
+ Process.setsid # Become session leader.
16
+
17
+ exit if fork # Zap session leader. See [1].
18
+
19
+ Dir.chdir "/" unless nochdir # Release old working directory.
20
+
21
+ if !noclose
22
+ STDIN.reopen File.open("/dev/null", "r")
23
+
24
+ null_out = File.open "/dev/null", "w"
25
+ STDOUT.reopen null_out
26
+ STDERR.reopen null_out
27
+ end
28
+
29
+ 0
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module Puma
2
+ module Delegation
3
+ def forward(what, who)
4
+ module_eval <<-CODE
5
+ def #{what}(*args, &block)
6
+ #{who}.#{what}(*args, &block)
7
+ end
8
+ CODE
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Puma
2
+ IS_JRUBY = defined?(JRUBY_VERSION)
3
+
4
+ def self.jruby?
5
+ IS_JRUBY
6
+ end
7
+
8
+ IS_WINDOWS = RUBY_PLATFORM =~ /mswin|ming|cygwin/
9
+
10
+ def self.windows?
11
+ IS_WINDOWS
12
+ end
13
+ end
@@ -0,0 +1,486 @@
1
+ module Puma
2
+ # The methods that are available for use inside the config file.
3
+ #
4
+ class DSL
5
+ include ConfigDefault
6
+
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
+ def initialize(options, config)
17
+ @config = config
18
+ @options = options
19
+
20
+ @plugins = []
21
+ end
22
+
23
+ def _load_from(path)
24
+ if path
25
+ @path = path
26
+ instance_eval(File.read(path), path, 1)
27
+ end
28
+ ensure
29
+ _offer_plugins
30
+ end
31
+
32
+ def _offer_plugins
33
+ @plugins.each do |o|
34
+ if o.respond_to? :config
35
+ @options.shift
36
+ o.config self
37
+ end
38
+ end
39
+
40
+ @plugins.clear
41
+ end
42
+
43
+ def _run(&blk)
44
+ blk.call self
45
+ ensure
46
+ _offer_plugins
47
+ end
48
+
49
+ def inject(&blk)
50
+ instance_eval(&blk)
51
+ end
52
+
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
+ def get(key,default=nil)
74
+ @options[key.to_sym] || default
75
+ end
76
+
77
+ # Load the named plugin for use by this configuration
78
+ #
79
+ def plugin(name)
80
+ @plugins << @config.load_plugin(name)
81
+ end
82
+
83
+ # Use +obj+ or +block+ as the Rack app. This allows a config file to
84
+ # be the app itself.
85
+ #
86
+ def app(obj=nil, &block)
87
+ obj ||= block
88
+
89
+ raise "Provide either a #call'able or a block" unless obj
90
+
91
+ @options[:app] = obj
92
+ end
93
+
94
+ # Start the Puma control rack app on +url+. This app can be communicated
95
+ # with to control the main server.
96
+ #
97
+ def activate_control_app(url="auto", opts={})
98
+ if url == "auto"
99
+ path = Configuration.temp_path
100
+ @options[:control_url] = "unix://#{path}"
101
+ @options[:control_url_temp] = path
102
+ else
103
+ @options[:control_url] = url
104
+ end
105
+
106
+ if opts[:no_token]
107
+ auth_token = :none
108
+ else
109
+ auth_token = opts[:auth_token]
110
+ auth_token ||= Configuration.random_token
111
+ end
112
+
113
+ @options[:control_auth_token] = auth_token
114
+ @options[:control_url_umask] = opts[:umask] if opts[:umask]
115
+ end
116
+
117
+ # Load additional configuration from a file
118
+ def load(file)
119
+ _ary(:config_files) << file
120
+ end
121
+
122
+ # Bind the server to +url+. tcp:// and unix:// are the only accepted
123
+ # protocols.
124
+ #
125
+ def bind(url)
126
+ _ary(:binds) << url
127
+ end
128
+
129
+ # Define the TCP port to bind to. Use +bind+ for more advanced options.
130
+ #
131
+ def port(port, host=nil)
132
+ host ||= Configuration::DefaultTCPHost
133
+ bind "tcp://#{host}:#{port}"
134
+ end
135
+
136
+ # Define how long persistent connections can be idle before puma closes
137
+ # them
138
+ #
139
+ def persistent_timeout(seconds)
140
+ @options[:persistent_timeout] = seconds
141
+ end
142
+
143
+ # Work around leaky apps that leave garbage in Thread locals
144
+ # across requests
145
+ #
146
+ def clean_thread_locals(which=true)
147
+ @options[:clean_thread_locals] = which
148
+ end
149
+
150
+ # Daemonize the server into the background. Highly suggest that
151
+ # this be combined with +pidfile+ and +stdout_redirect+.
152
+ def daemonize(which=true)
153
+ @options[:daemon] = which
154
+ end
155
+
156
+ # When shutting down, drain the accept socket of pending
157
+ # connections and proces them. This loops over the accept
158
+ # socket until there are no more read events and then stops
159
+ # looking and waits for the requests to finish.
160
+ def drain_on_shutdown(which=true)
161
+ @options[:drain_on_shutdown] = which
162
+ end
163
+
164
+ # Set the environment in which the Rack's app will run.
165
+ def environment(environment)
166
+ @options[:environment] = environment
167
+ end
168
+
169
+ # How long to wait for threads to stop when shutting them
170
+ # down. Defaults to :forever. Specifying :immediately will cause
171
+ # Puma to kill the threads immediately. Otherwise the value
172
+ # is the number of seconds to wait.
173
+ #
174
+ # Puma always waits a few seconds after killing a thread for it to try
175
+ # to finish up it's work, even in :immediately mode.
176
+ def force_shutdown_after(val=:forever)
177
+ i = case val
178
+ when :forever
179
+ -1
180
+ when :immediately
181
+ 0
182
+ else
183
+ Integer(val)
184
+ end
185
+
186
+ @options[:force_shutdown_after] = i
187
+ end
188
+
189
+ # Code to run before doing a restart. This code should
190
+ # close logfiles, database connections, etc.
191
+ #
192
+ # This can be called multiple times to add code each time.
193
+ #
194
+ def on_restart(&block)
195
+ _ary(:on_restart) << block
196
+ end
197
+
198
+ # Command to use to restart puma. This should be just how to
199
+ # load puma itself (ie. 'ruby -Ilib bin/puma'), not the arguments
200
+ # to puma, as those are the same as the original process.
201
+ #
202
+ def restart_command(cmd)
203
+ @options[:restart_cmd] = cmd.to_s
204
+ end
205
+
206
+ # Store the pid of the server in the file at +path+.
207
+ def pidfile(path)
208
+ @options[:pidfile] = path.to_s
209
+ end
210
+
211
+ # Disable request logging.
212
+ #
213
+ def quiet(which=true)
214
+ @options[:log_requests] = !which
215
+ end
216
+
217
+ # Enable request logging
218
+ #
219
+ def log_requests(which=true)
220
+ @options[:log_requests] = which
221
+ end
222
+
223
+ # Show debugging info
224
+ #
225
+ def debug
226
+ @options[:debug] = true
227
+ end
228
+
229
+ # Load +path+ as a rackup file.
230
+ #
231
+ def rackup(path)
232
+ @options[:rackup] = path.to_s
233
+ end
234
+
235
+ # Run Puma in TCP mode
236
+ #
237
+ def tcp_mode!
238
+ @options[:mode] = :tcp
239
+ end
240
+
241
+ # Redirect STDOUT and STDERR to files specified.
242
+ def stdout_redirect(stdout=nil, stderr=nil, append=false)
243
+ @options[:redirect_stdout] = stdout
244
+ @options[:redirect_stderr] = stderr
245
+ @options[:redirect_append] = append
246
+ end
247
+
248
+ # Configure +min+ to be the minimum number of threads to use to answer
249
+ # requests and +max+ the maximum.
250
+ #
251
+ def threads(min, max)
252
+ min = Integer(min)
253
+ max = Integer(max)
254
+ if min > max
255
+ raise "The minimum (#{min}) number of threads must be less than or equal to the max (#{max})"
256
+ end
257
+
258
+ if max < 1
259
+ raise "The maximum number of threads (#{max}) must be greater than 0"
260
+ end
261
+
262
+ @options[:min_threads] = min
263
+ @options[:max_threads] = max
264
+ end
265
+
266
+ def ssl_bind(host, port, opts)
267
+ verify = opts.fetch(:verify_mode, 'none')
268
+
269
+ if defined?(JRUBY_VERSION)
270
+ keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}"
271
+ bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&#{keystore_additions}&verify_mode=#{verify}"
272
+ else
273
+ bind "ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}&verify_mode=#{verify}"
274
+ end
275
+ end
276
+
277
+ # Use +path+ as the file to store the server info state. This is
278
+ # used by pumactl to query and control the server.
279
+ #
280
+ def state_path(path)
281
+ @options[:state] = path.to_s
282
+ end
283
+
284
+ # *Cluster mode only* How many worker processes to run.
285
+ #
286
+ def workers(count)
287
+ @options[:workers] = count.to_i
288
+ end
289
+
290
+ # *Cluster mode only* Code to run immediately before master process
291
+ # forks workers (once on boot). These hooks can block if necessary
292
+ # to wait for background operations unknown to puma to finish before
293
+ # the process terminates.
294
+ # This can be used to close any connections to remote servers (database, redis, ...)
295
+ # that were opened when preloading the code
296
+ #
297
+ # This can be called multiple times to add hooks.
298
+ #
299
+ def before_fork(&block)
300
+ _ary(:before_fork) << block
301
+ end
302
+
303
+ # *Cluster mode only* Code to run in a worker when it boots to setup
304
+ # the process before booting the app.
305
+ #
306
+ # This can be called multiple times to add hooks.
307
+ #
308
+ def on_worker_boot(&block)
309
+ _ary(:before_worker_boot) << block
310
+ end
311
+
312
+ # *Cluster mode only* Code to run immediately before a worker shuts
313
+ # down (after it has finished processing HTTP requests). These hooks
314
+ # can block if necessary to wait for background operations unknown
315
+ # to puma to finish before the process terminates.
316
+ #
317
+ # This can be called multiple times to add hooks.
318
+ #
319
+ def on_worker_shutdown(&block)
320
+ _ary(:before_worker_shutdown) << block
321
+ end
322
+
323
+ # *Cluster mode only* Code to run in the master when it is
324
+ # about to create the worker by forking itself.
325
+ #
326
+ # This can be called multiple times to add hooks.
327
+ #
328
+ def on_worker_fork(&block)
329
+ _ary(:before_worker_fork) << block
330
+ end
331
+
332
+ # *Cluster mode only* Code to run in the master after it starts
333
+ # a worker.
334
+ #
335
+ # This can be called multiple times to add hooks.
336
+ #
337
+ def after_worker_fork(&block)
338
+ _ary(:after_worker_fork) << block
339
+ end
340
+
341
+ alias_method :after_worker_boot, :after_worker_fork
342
+
343
+ # The directory to operate out of.
344
+ def directory(dir)
345
+ @options[:directory] = dir.to_s
346
+ end
347
+
348
+ # DEPRECATED: The directory to operate out of.
349
+ def worker_directory(dir)
350
+ $stderr.puts "worker_directory is deprecated. Please use `directory`"
351
+ directory dir
352
+ end
353
+
354
+ # Run the app as a raw TCP app instead of an HTTP rack app
355
+ def tcp_mode
356
+ @options[:mode] = :tcp
357
+ end
358
+
359
+ # *Cluster mode only* Preload the application before starting
360
+ # the workers and setting up the listen ports. This conflicts
361
+ # with using the phased restart feature, you can't use both.
362
+ #
363
+ def preload_app!(answer=true)
364
+ @options[:preload_app] = answer
365
+ end
366
+
367
+ # Use +obj+ or +block+ as the low level error handler. This allows a config file to
368
+ # change the default error on the server.
369
+ #
370
+ def lowlevel_error_handler(obj=nil, &block)
371
+ obj ||= block
372
+ raise "Provide either a #call'able or a block" unless obj
373
+ @options[:lowlevel_error_handler] = obj
374
+ end
375
+
376
+ # This option is used to allow your app and its gems to be
377
+ # properly reloaded when not using preload.
378
+ #
379
+ # When set, if puma detects that it's been invoked in the
380
+ # context of Bundler, it will cleanup the environment and
381
+ # re-run itself outside the Bundler environment, but directly
382
+ # using the files that Bundler has setup.
383
+ #
384
+ # This means that puma is now decoupled from your Bundler
385
+ # context and when each worker loads, it will be loading a
386
+ # new Bundler context and thus can float around as the release
387
+ # dictates.
388
+ def prune_bundler(answer=true)
389
+ @options[:prune_bundler] = answer
390
+ end
391
+
392
+ # Additional text to display in process listing
393
+ def tag(string)
394
+ @options[:tag] = string.to_s
395
+ end
396
+
397
+ # *Cluster mode only* Set the timeout for workers in seconds
398
+ # When set the master process will terminate any workers
399
+ # that have not checked in within the given +timeout+.
400
+ # This mitigates hung processes. Default value is 60 seconds.
401
+ def worker_timeout(timeout)
402
+ @options[:worker_timeout] = timeout
403
+ end
404
+
405
+ # *Cluster mode only* Set the timeout for workers to boot
406
+ def worker_boot_timeout(timeout)
407
+ @options[:worker_boot_timeout] = timeout
408
+ end
409
+
410
+ # *Cluster mode only* Set the timeout for worker shutdown
411
+ def worker_shutdown_timeout(timeout)
412
+ @options[:worker_shutdown_timeout] = timeout
413
+ end
414
+
415
+ # When set to true (the default), workers accept all requests
416
+ # and queue them before passing them to the handlers.
417
+ # When set to false, each worker process accepts exactly as
418
+ # many requests as it is configured to simultaneously handle.
419
+ #
420
+ # Queueing requests generally improves performance. In some
421
+ # cases, such as a single threaded application, it may be
422
+ # better to ensure requests get balanced across workers.
423
+ #
424
+ # Note that setting this to false disables HTTP keepalive and
425
+ # slow clients will occupy a handler thread while the request
426
+ # is being sent. A reverse proxy, such as nginx, can handle
427
+ # slow clients and queue requests before they reach puma.
428
+ def queue_requests(answer=true)
429
+ @options[:queue_requests] = answer
430
+ end
431
+
432
+ # When a shutdown is requested, the backtraces of all the
433
+ # threads will be written to $stdout. This can help figure
434
+ # out why shutdown is hanging.
435
+ def shutdown_debug(val=true)
436
+ @options[:shutdown_debug] = val
437
+ end
438
+
439
+ # Control how the remote address of the connection is set. This
440
+ # is configurable because to calculate the true socket peer address
441
+ # a kernel syscall is required which for very fast rack handlers
442
+ # slows down the handling significantly.
443
+ #
444
+ # There are 4 possible values:
445
+ #
446
+ # * :socket (the default) - read the peername from the socket using the
447
+ # syscall. This is the normal behavior.
448
+ # * :localhost - set the remote address to "127.0.0.1"
449
+ # * header: http_header - set the remote address to the value of the
450
+ # provided http header. For instance:
451
+ # `set_remote_address header: "X-Real-IP"`.
452
+ # Only the first word (as separated by spaces or comma)
453
+ # is used, allowing headers such as X-Forwarded-For
454
+ # to be used as well.
455
+ # * Any string - this allows you to hardcode remote address to any value
456
+ # you wish. Because puma never uses this field anyway, it's
457
+ # format is entirely in your hands.
458
+ def set_remote_address(val=:socket)
459
+ case val
460
+ when :socket
461
+ @options[:remote_address] = val
462
+ when :localhost
463
+ @options[:remote_address] = :value
464
+ @options[:remote_address_value] = "127.0.0.1".freeze
465
+ when String
466
+ @options[:remote_address] = :value
467
+ @options[:remote_address_value] = val
468
+ when Hash
469
+ if hdr = val[:header]
470
+ @options[:remote_address] = :header
471
+ @options[:remote_address_header] = "HTTP_" + hdr.upcase.gsub("-", "_")
472
+ else
473
+ raise "Invalid value for set_remote_address - #{val.inspect}"
474
+ end
475
+ else
476
+ raise "Invalid value for set_remote_address - #{val}"
477
+ end
478
+ end
479
+
480
+ private
481
+
482
+ def _ary(key)
483
+ (@options.cur[key] ||= [])
484
+ end
485
+ end
486
+ end