puma-simon 3.7.1

Sign up to get free protection for your applications and to get access to all the features.
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