unicorn-simon 0.0.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 (158) hide show
  1. checksums.yaml +7 -0
  2. data/.CHANGELOG.old +25 -0
  3. data/.document +28 -0
  4. data/.gitattributes +5 -0
  5. data/.gitignore +25 -0
  6. data/.mailmap +26 -0
  7. data/.manifest +156 -0
  8. data/.olddoc.yml +18 -0
  9. data/Application_Timeouts +77 -0
  10. data/CONTRIBUTORS +35 -0
  11. data/COPYING +674 -0
  12. data/DESIGN +95 -0
  13. data/Documentation/.gitignore +5 -0
  14. data/Documentation/GNUmakefile +30 -0
  15. data/Documentation/unicorn.1.txt +187 -0
  16. data/Documentation/unicorn_rails.1.txt +175 -0
  17. data/FAQ +70 -0
  18. data/GIT-VERSION-FILE +1 -0
  19. data/GIT-VERSION-GEN +39 -0
  20. data/GNUmakefile +253 -0
  21. data/HACKING +120 -0
  22. data/ISSUES +90 -0
  23. data/KNOWN_ISSUES +79 -0
  24. data/LATEST +30 -0
  25. data/LICENSE +67 -0
  26. data/Links +56 -0
  27. data/NEWS +2465 -0
  28. data/PHILOSOPHY +139 -0
  29. data/README +138 -0
  30. data/Rakefile +16 -0
  31. data/SIGNALS +123 -0
  32. data/Sandbox +104 -0
  33. data/TODO +3 -0
  34. data/TUNING +119 -0
  35. data/archive/.gitignore +3 -0
  36. data/archive/slrnpull.conf +4 -0
  37. data/bin/unicorn +126 -0
  38. data/bin/unicorn_rails +209 -0
  39. data/examples/big_app_gc.rb +2 -0
  40. data/examples/echo.ru +27 -0
  41. data/examples/init.sh +102 -0
  42. data/examples/logger_mp_safe.rb +25 -0
  43. data/examples/logrotate.conf +44 -0
  44. data/examples/nginx.conf +155 -0
  45. data/examples/unicorn.conf.minimal.rb +13 -0
  46. data/examples/unicorn.conf.rb +110 -0
  47. data/examples/unicorn.socket +11 -0
  48. data/examples/unicorn@.service +33 -0
  49. data/ext/unicorn_http/CFLAGS +13 -0
  50. data/ext/unicorn_http/c_util.h +124 -0
  51. data/ext/unicorn_http/common_field_optimization.h +111 -0
  52. data/ext/unicorn_http/ext_help.h +62 -0
  53. data/ext/unicorn_http/extconf.rb +11 -0
  54. data/ext/unicorn_http/global_variables.h +97 -0
  55. data/ext/unicorn_http/httpdate.c +78 -0
  56. data/ext/unicorn_http/unicorn_http.c +4274 -0
  57. data/ext/unicorn_http/unicorn_http.rl +980 -0
  58. data/ext/unicorn_http/unicorn_http_common.rl +76 -0
  59. data/lib/unicorn/app/old_rails/static.rb +59 -0
  60. data/lib/unicorn/app/old_rails.rb +35 -0
  61. data/lib/unicorn/cgi_wrapper.rb +147 -0
  62. data/lib/unicorn/configurator.rb +664 -0
  63. data/lib/unicorn/const.rb +21 -0
  64. data/lib/unicorn/http_request.rb +122 -0
  65. data/lib/unicorn/http_response.rb +60 -0
  66. data/lib/unicorn/http_server.rb +824 -0
  67. data/lib/unicorn/launcher.rb +62 -0
  68. data/lib/unicorn/oob_gc.rb +82 -0
  69. data/lib/unicorn/preread_input.rb +33 -0
  70. data/lib/unicorn/socket_helper.rb +195 -0
  71. data/lib/unicorn/stream_input.rb +146 -0
  72. data/lib/unicorn/tee_input.rb +133 -0
  73. data/lib/unicorn/tmpio.rb +27 -0
  74. data/lib/unicorn/util.rb +90 -0
  75. data/lib/unicorn/version.rb +1 -0
  76. data/lib/unicorn/worker.rb +140 -0
  77. data/lib/unicorn.rb +123 -0
  78. data/man/man1/unicorn.1 +221 -0
  79. data/man/man1/unicorn_rails.1 +212 -0
  80. data/setup.rb +1586 -0
  81. data/t/.gitignore +4 -0
  82. data/t/GNUmakefile +74 -0
  83. data/t/README +42 -0
  84. data/t/bin/content-md5-put +36 -0
  85. data/t/bin/sha1sum.rb +17 -0
  86. data/t/bin/unused_listen +40 -0
  87. data/t/broken-app.ru +12 -0
  88. data/t/detach.ru +11 -0
  89. data/t/env.ru +3 -0
  90. data/t/fails-rack-lint.ru +5 -0
  91. data/t/heartbeat-timeout.ru +12 -0
  92. data/t/hijack.ru +43 -0
  93. data/t/listener_names.ru +4 -0
  94. data/t/my-tap-lib.sh +201 -0
  95. data/t/oob_gc.ru +20 -0
  96. data/t/oob_gc_path.ru +20 -0
  97. data/t/pid.ru +3 -0
  98. data/t/preread_input.ru +17 -0
  99. data/t/rack-input-tests.ru +21 -0
  100. data/t/t0000-http-basic.sh +50 -0
  101. data/t/t0001-reload-bad-config.sh +53 -0
  102. data/t/t0002-config-conflict.sh +49 -0
  103. data/t/t0002-parser-error.sh +94 -0
  104. data/t/t0003-working_directory.sh +51 -0
  105. data/t/t0004-heartbeat-timeout.sh +69 -0
  106. data/t/t0004-working_directory_broken.sh +24 -0
  107. data/t/t0005-working_directory_app.rb.sh +40 -0
  108. data/t/t0006-reopen-logs.sh +83 -0
  109. data/t/t0006.ru +13 -0
  110. data/t/t0007-working_directory_no_embed_cli.sh +44 -0
  111. data/t/t0008-back_out_of_upgrade.sh +110 -0
  112. data/t/t0009-broken-app.sh +56 -0
  113. data/t/t0009-winch_ttin.sh +59 -0
  114. data/t/t0010-reap-logging.sh +55 -0
  115. data/t/t0011-active-unix-socket.sh +79 -0
  116. data/t/t0012-reload-empty-config.sh +85 -0
  117. data/t/t0013-rewindable-input-false.sh +24 -0
  118. data/t/t0013.ru +12 -0
  119. data/t/t0014-rewindable-input-true.sh +24 -0
  120. data/t/t0014.ru +12 -0
  121. data/t/t0015-configurator-internals.sh +25 -0
  122. data/t/t0018-write-on-close.sh +23 -0
  123. data/t/t0019-max_header_len.sh +49 -0
  124. data/t/t0020-at_exit-handler.sh +49 -0
  125. data/t/t0021-process_detach.sh +29 -0
  126. data/t/t0022-listener_names-preload_app.sh +32 -0
  127. data/t/t0100-rack-input-tests.sh +124 -0
  128. data/t/t0116-client_body_buffer_size.sh +80 -0
  129. data/t/t0116.ru +16 -0
  130. data/t/t0200-rack-hijack.sh +30 -0
  131. data/t/t0300-no-default-middleware.sh +20 -0
  132. data/t/t9000-preread-input.sh +48 -0
  133. data/t/t9001-oob_gc.sh +47 -0
  134. data/t/t9002-oob_gc-path.sh +75 -0
  135. data/t/test-lib.sh +128 -0
  136. data/t/write-on-close.ru +11 -0
  137. data/test/aggregate.rb +15 -0
  138. data/test/benchmark/README +50 -0
  139. data/test/benchmark/dd.ru +18 -0
  140. data/test/benchmark/stack.ru +8 -0
  141. data/test/exec/README +5 -0
  142. data/test/exec/test_exec.rb +1099 -0
  143. data/test/test_helper.rb +298 -0
  144. data/test/unit/test_configurator.rb +175 -0
  145. data/test/unit/test_droplet.rb +28 -0
  146. data/test/unit/test_http_parser.rb +886 -0
  147. data/test/unit/test_http_parser_ng.rb +633 -0
  148. data/test/unit/test_request.rb +182 -0
  149. data/test/unit/test_response.rb +111 -0
  150. data/test/unit/test_server.rb +268 -0
  151. data/test/unit/test_signals.rb +188 -0
  152. data/test/unit/test_socket_helper.rb +197 -0
  153. data/test/unit/test_stream_input.rb +203 -0
  154. data/test/unit/test_tee_input.rb +304 -0
  155. data/test/unit/test_upload.rb +306 -0
  156. data/test/unit/test_util.rb +105 -0
  157. data/unicorn.gemspec +50 -0
  158. metadata +310 -0
@@ -0,0 +1,664 @@
1
+ # -*- encoding: binary -*-
2
+ require 'logger'
3
+
4
+ # Implements a simple DSL for configuring a unicorn server.
5
+ #
6
+ # See https://bogomips.org/unicorn/examples/unicorn.conf.rb and
7
+ # https://bogomips.org/unicorn/examples/unicorn.conf.minimal.rb
8
+ # example configuration files. An example config file for use with
9
+ # nginx is also available at
10
+ # https://bogomips.org/unicorn/examples/nginx.conf
11
+ #
12
+ # See the link:/TUNING.html document for more information on tuning unicorn.
13
+ class Unicorn::Configurator
14
+ include Unicorn
15
+
16
+ # :stopdoc:
17
+ attr_accessor :set, :config_file, :after_reload
18
+
19
+ # used to stash stuff for deferred processing of cli options in
20
+ # config.ru after "working_directory" is bound. Do not rely on
21
+ # this being around later on...
22
+ RACKUP = {
23
+ :daemonize => false,
24
+ :host => Unicorn::Const::DEFAULT_HOST,
25
+ :port => Unicorn::Const::DEFAULT_PORT,
26
+ :set_listener => false,
27
+ :options => { :listeners => [] }
28
+ }
29
+
30
+ # Default settings for Unicorn
31
+ DEFAULTS = {
32
+ :timeout => 60,
33
+ :logger => Logger.new($stderr),
34
+ :worker_processes => 1,
35
+ :after_fork => lambda { |server, worker|
36
+ server.logger.info("worker=#{worker.nr} spawned pid=#{$$}")
37
+ },
38
+ :before_fork => lambda { |server, worker|
39
+ server.logger.info("worker=#{worker.nr} spawning...")
40
+ },
41
+ :before_exec => lambda { |server|
42
+ server.logger.info("forked child re-executing...")
43
+ },
44
+ :pid => nil,
45
+ :preload_app => false,
46
+ :check_client_connection => false,
47
+ :rewindable_input => true, # for Rack 2.x: (Rack::VERSION[0] <= 1),
48
+ :client_body_buffer_size => Unicorn::Const::MAX_BODY,
49
+ }
50
+ #:startdoc:
51
+
52
+ def initialize(defaults = {}) #:nodoc:
53
+ self.set = Hash.new(:unset)
54
+ @use_defaults = defaults.delete(:use_defaults)
55
+ self.config_file = defaults.delete(:config_file)
56
+
57
+ # after_reload is only used by unicorn_rails, unsupported otherwise
58
+ self.after_reload = defaults.delete(:after_reload)
59
+
60
+ set.merge!(DEFAULTS) if @use_defaults
61
+ defaults.each { |key, value| self.__send__(key, value) }
62
+ Hash === set[:listener_opts] or
63
+ set[:listener_opts] = Hash.new { |hash,key| hash[key] = {} }
64
+ Array === set[:listeners] or set[:listeners] = []
65
+ reload(false)
66
+ end
67
+
68
+ def reload(merge_defaults = true) #:nodoc:
69
+ if merge_defaults && @use_defaults
70
+ set.merge!(DEFAULTS) if @use_defaults
71
+ end
72
+ instance_eval(File.read(config_file), config_file) if config_file
73
+
74
+ parse_rackup_file
75
+
76
+ RACKUP[:set_listener] and
77
+ set[:listeners] << "#{RACKUP[:host]}:#{RACKUP[:port]}"
78
+
79
+ # unicorn_rails creates dirs here after working_directory is bound
80
+ after_reload.call if after_reload
81
+
82
+ # working_directory binds immediately (easier error checking that way),
83
+ # now ensure any paths we changed are correctly set.
84
+ [ :pid, :stderr_path, :stdout_path ].each do |var|
85
+ String === (path = set[var]) or next
86
+ path = File.expand_path(path)
87
+ File.writable?(path) || File.writable?(File.dirname(path)) or \
88
+ raise ArgumentError, "directory for #{var}=#{path} not writable"
89
+ end
90
+ end
91
+
92
+ def commit!(server, options = {}) #:nodoc:
93
+ skip = options[:skip] || []
94
+ if ready_pipe = RACKUP.delete(:ready_pipe)
95
+ server.ready_pipe = ready_pipe
96
+ end
97
+ if set[:check_client_connection]
98
+ set[:listeners].each do |address|
99
+ if set[:listener_opts][address][:tcp_nopush] == true
100
+ raise ArgumentError,
101
+ "check_client_connection is incompatible with tcp_nopush:true"
102
+ end
103
+ end
104
+ end
105
+ set.each do |key, value|
106
+ value == :unset and next
107
+ skip.include?(key) and next
108
+ server.__send__("#{key}=", value)
109
+ end
110
+ end
111
+
112
+ def [](key) # :nodoc:
113
+ set[key]
114
+ end
115
+
116
+ # sets object to the +obj+ Logger-like object. The new Logger-like
117
+ # object must respond to the following methods:
118
+ # * debug
119
+ # * info
120
+ # * warn
121
+ # * error
122
+ # * fatal
123
+ # The default Logger will log its output to the path specified
124
+ # by +stderr_path+. If you're running Unicorn daemonized, then
125
+ # you must specify a path to prevent error messages from going
126
+ # to /dev/null.
127
+ def logger(obj)
128
+ %w(debug info warn error fatal).each do |m|
129
+ obj.respond_to?(m) and next
130
+ raise ArgumentError, "logger=#{obj} does not respond to method=#{m}"
131
+ end
132
+
133
+ set[:logger] = obj
134
+ end
135
+
136
+ # sets after_fork hook to a given block. This block will be called by
137
+ # the worker after forking. The following is an example hook which adds
138
+ # a per-process listener to every worker:
139
+ #
140
+ # after_fork do |server,worker|
141
+ # # per-process listener ports for debugging/admin:
142
+ # addr = "127.0.0.1:#{9293 + worker.nr}"
143
+ #
144
+ # # the negative :tries parameter indicates we will retry forever
145
+ # # waiting on the existing process to exit with a 5 second :delay
146
+ # # Existing options for Unicorn::Configurator#listen such as
147
+ # # :backlog, :rcvbuf, :sndbuf are available here as well.
148
+ # server.listen(addr, :tries => -1, :delay => 5, :backlog => 128)
149
+ # end
150
+ def after_fork(*args, &block)
151
+ set_hook(:after_fork, block_given? ? block : args[0])
152
+ end
153
+
154
+ # sets before_fork got be a given Proc object. This Proc
155
+ # object will be called by the master process before forking
156
+ # each worker.
157
+ def before_fork(*args, &block)
158
+ set_hook(:before_fork, block_given? ? block : args[0])
159
+ end
160
+
161
+ # sets the before_exec hook to a given Proc object. This
162
+ # Proc object will be called by the master process right
163
+ # before exec()-ing the new unicorn binary. This is useful
164
+ # for freeing certain OS resources that you do NOT wish to
165
+ # share with the reexeced child process.
166
+ # There is no corresponding after_exec hook (for obvious reasons).
167
+ def before_exec(*args, &block)
168
+ set_hook(:before_exec, block_given? ? block : args[0], 1)
169
+ end
170
+
171
+ # sets the timeout of worker processes to +seconds+. Workers
172
+ # handling the request/app.call/response cycle taking longer than
173
+ # this time period will be forcibly killed (via SIGKILL). This
174
+ # timeout is enforced by the master process itself and not subject
175
+ # to the scheduling limitations by the worker process. Due the
176
+ # low-complexity, low-overhead implementation, timeouts of less
177
+ # than 3.0 seconds can be considered inaccurate and unsafe.
178
+ #
179
+ # For running Unicorn behind nginx, it is recommended to set
180
+ # "fail_timeout=0" for in your nginx configuration like this
181
+ # to have nginx always retry backends that may have had workers
182
+ # SIGKILL-ed due to timeouts.
183
+ #
184
+ # upstream unicorn_backend {
185
+ # # for UNIX domain socket setups:
186
+ # server unix:/path/to/.unicorn.sock fail_timeout=0;
187
+ #
188
+ # # for TCP setups
189
+ # server 192.168.0.7:8080 fail_timeout=0;
190
+ # server 192.168.0.8:8080 fail_timeout=0;
191
+ # server 192.168.0.9:8080 fail_timeout=0;
192
+ # }
193
+ #
194
+ # See http://nginx.org/en/docs/http/ngx_http_upstream_module.html
195
+ # for more details on nginx upstream configuration.
196
+ def timeout(seconds)
197
+ set_int(:timeout, seconds, 3)
198
+ # POSIX says 31 days is the smallest allowed maximum timeout for select()
199
+ max = 30 * 60 * 60 * 24
200
+ set[:timeout] = seconds > max ? max : seconds
201
+ end
202
+
203
+ # sets the current number of worker_processes to +nr+. Each worker
204
+ # process will serve exactly one client at a time. You can
205
+ # increment or decrement this value at runtime by sending SIGTTIN
206
+ # or SIGTTOU respectively to the master process without reloading
207
+ # the rest of your Unicorn configuration. See the SIGNALS document
208
+ # for more information.
209
+ def worker_processes(nr)
210
+ set_int(:worker_processes, nr, 1)
211
+ end
212
+
213
+ # sets listeners to the given +addresses+, replacing or augmenting the
214
+ # current set. This is for the global listener pool shared by all
215
+ # worker processes. For per-worker listeners, see the after_fork example
216
+ # This is for internal API use only, do not use it in your Unicorn
217
+ # config file. Use listen instead.
218
+ def listeners(addresses) # :nodoc:
219
+ Array === addresses or addresses = Array(addresses)
220
+ addresses.map! { |addr| expand_addr(addr) }
221
+ set[:listeners] = addresses
222
+ end
223
+
224
+ # Adds an +address+ to the existing listener set. May be specified more
225
+ # than once. +address+ may be an Integer port number for a TCP port, an
226
+ # "IP_ADDRESS:PORT" for TCP listeners or a pathname for UNIX domain sockets.
227
+ #
228
+ # listen 3000 # listen to port 3000 on all TCP interfaces
229
+ # listen "127.0.0.1:3000" # listen to port 3000 on the loopback interface
230
+ # listen "/path/to/.unicorn.sock" # listen on the given Unix domain socket
231
+ # listen "[::1]:3000" # listen to port 3000 on the IPv6 loopback interface
232
+ #
233
+ # When using Unix domain sockets, be sure:
234
+ # 1) the path matches the one used by nginx
235
+ # 2) uses the same filesystem namespace as the nginx process
236
+ # For systemd users using PrivateTmp=true (for either nginx or unicorn),
237
+ # this means Unix domain sockets must not be placed in /tmp
238
+ #
239
+ # The following options may be specified (but are generally not needed):
240
+ #
241
+ # [:backlog => number of clients]
242
+ #
243
+ # This is the backlog of the listen() syscall.
244
+ #
245
+ # Some operating systems allow negative values here to specify the
246
+ # maximum allowable value. In most cases, this number is only
247
+ # recommendation and there are other OS-specific tunables and
248
+ # variables that can affect this number. See the listen(2)
249
+ # syscall documentation of your OS for the exact semantics of
250
+ # this.
251
+ #
252
+ # If you are running unicorn on multiple machines, lowering this number
253
+ # can help your load balancer detect when a machine is overloaded
254
+ # and give requests to a different machine.
255
+ #
256
+ # Default: 1024
257
+ #
258
+ # Note: with the Linux kernel, the net.core.somaxconn sysctl defaults
259
+ # to 128, capping this value to 128. Raising the sysctl allows a
260
+ # larger backlog (which may not be desirable with multiple,
261
+ # load-balanced machines).
262
+ #
263
+ # [:rcvbuf => bytes, :sndbuf => bytes]
264
+ #
265
+ # Maximum receive and send buffer sizes (in bytes) of sockets.
266
+ #
267
+ # These correspond to the SO_RCVBUF and SO_SNDBUF settings which
268
+ # can be set via the setsockopt(2) syscall. Some kernels
269
+ # (e.g. Linux 2.4+) have intelligent auto-tuning mechanisms and
270
+ # there is no need (and it is sometimes detrimental) to specify them.
271
+ #
272
+ # See the socket API documentation of your operating system
273
+ # to determine the exact semantics of these settings and
274
+ # other operating system-specific knobs where they can be
275
+ # specified.
276
+ #
277
+ # Defaults: operating system defaults
278
+ #
279
+ # [:tcp_nodelay => true or false]
280
+ #
281
+ # Disables Nagle's algorithm on TCP sockets if +true+.
282
+ #
283
+ # Setting this to +true+ can make streaming responses in Rails 3.1
284
+ # appear more quickly at the cost of slightly higher bandwidth usage.
285
+ # The effect of this option is most visible if nginx is not used,
286
+ # but nginx remains highly recommended with unicorn.
287
+ #
288
+ # This has no effect on UNIX sockets.
289
+ #
290
+ # Default: +true+ (Nagle's algorithm disabled) in unicorn
291
+ # This defaulted to +false+ in unicorn 3.x
292
+ #
293
+ # [:tcp_nopush => true or false]
294
+ #
295
+ # Enables/disables TCP_CORK in Linux or TCP_NOPUSH in FreeBSD
296
+ #
297
+ # This prevents partial TCP frames from being sent out and reduces
298
+ # wakeups in nginx if it is on a different machine. Since unicorn
299
+ # is only designed for applications that send the response body
300
+ # quickly without keepalive, sockets will always be flushed on close
301
+ # to prevent delays.
302
+ #
303
+ # This has no effect on UNIX sockets.
304
+ #
305
+ # Default: +false+
306
+ # This defaulted to +true+ in unicorn 3.4 - 3.7
307
+ #
308
+ # [:ipv6only => true or false]
309
+ #
310
+ # This option makes IPv6-capable TCP listeners IPv6-only and unable
311
+ # to receive IPv4 queries on dual-stack systems. A separate IPv4-only
312
+ # listener is required if this is true.
313
+ #
314
+ # Enabling this option for the IPv6-only listener and having a
315
+ # separate IPv4 listener is recommended if you wish to support IPv6
316
+ # on the same TCP port. Otherwise, the value of \env[\"REMOTE_ADDR\"]
317
+ # will appear as an ugly IPv4-mapped-IPv6 address for IPv4 clients
318
+ # (e.g ":ffff:10.0.0.1" instead of just "10.0.0.1").
319
+ #
320
+ # Default: Operating-system dependent
321
+ #
322
+ # [:reuseport => true or false]
323
+ #
324
+ # This enables multiple, independently-started unicorn instances to
325
+ # bind to the same port (as long as all the processes enable this).
326
+ #
327
+ # This option must be used when unicorn first binds the listen socket.
328
+ # It cannot be enabled when a socket is inherited via SIGUSR2
329
+ # (but it will remain on if inherited), and it cannot be enabled
330
+ # directly via SIGHUP.
331
+ #
332
+ # Note: there is a chance of connections being dropped if
333
+ # one of the unicorn instances is stopped while using this.
334
+ #
335
+ # This is supported on *BSD systems and Linux 3.9 or later.
336
+ #
337
+ # ref: https://lwn.net/Articles/542629/
338
+ #
339
+ # Default: false (unset)
340
+ #
341
+ # [:tries => Integer]
342
+ #
343
+ # Times to retry binding a socket if it is already in use
344
+ #
345
+ # A negative number indicates we will retry indefinitely, this is
346
+ # useful for migrations and upgrades when individual workers
347
+ # are binding to different ports.
348
+ #
349
+ # Default: 5
350
+ #
351
+ # [:delay => seconds]
352
+ #
353
+ # Seconds to wait between successive +tries+
354
+ #
355
+ # Default: 0.5 seconds
356
+ #
357
+ # [:umask => mode]
358
+ #
359
+ # Sets the file mode creation mask for UNIX sockets. If specified,
360
+ # this is usually in octal notation.
361
+ #
362
+ # Typically UNIX domain sockets are created with more liberal
363
+ # file permissions than the rest of the application. By default,
364
+ # we create UNIX domain sockets to be readable and writable by
365
+ # all local users to give them the same accessibility as
366
+ # locally-bound TCP listeners.
367
+ #
368
+ # This has no effect on TCP listeners.
369
+ #
370
+ # Default: 0000 (world-read/writable)
371
+ #
372
+ # [:tcp_defer_accept => Integer]
373
+ #
374
+ # Defer accept() until data is ready (Linux-only)
375
+ #
376
+ # For Linux 2.6.32 and later, this is the number of retransmits to
377
+ # defer an accept() for if no data arrives, but the client will
378
+ # eventually be accepted after the specified number of retransmits
379
+ # regardless of whether data is ready.
380
+ #
381
+ # For Linux before 2.6.32, this is a boolean option, and
382
+ # accepts are _always_ deferred indefinitely if no data arrives.
383
+ # This is similar to <code>:accept_filter => "dataready"</code>
384
+ # under FreeBSD.
385
+ #
386
+ # Specifying +true+ is synonymous for the default value(s) below,
387
+ # and +false+ or +nil+ is synonymous for a value of zero.
388
+ #
389
+ # A value of +1+ is a good optimization for local networks
390
+ # and trusted clients. There is no good reason to ever
391
+ # disable this with a +zero+ value with unicorn.
392
+ #
393
+ # Default: 1
394
+ #
395
+ # [:accept_filter => String]
396
+ #
397
+ # defer accept() until data is ready (FreeBSD-only)
398
+ #
399
+ # This enables either the "dataready" or (default) "httpready"
400
+ # accept() filter under FreeBSD. This is intended as an
401
+ # optimization to reduce context switches with common GET/HEAD
402
+ # requests.
403
+ #
404
+ # There is no good reason to change from the default.
405
+ #
406
+ # Default: "httpready"
407
+ def listen(address, options = {})
408
+ address = expand_addr(address)
409
+ if String === address
410
+ [ :umask, :backlog, :sndbuf, :rcvbuf, :tries ].each do |key|
411
+ value = options[key] or next
412
+ Integer === value or
413
+ raise ArgumentError, "not an integer: #{key}=#{value.inspect}"
414
+ end
415
+ [ :tcp_nodelay, :tcp_nopush, :ipv6only, :reuseport ].each do |key|
416
+ (value = options[key]).nil? and next
417
+ TrueClass === value || FalseClass === value or
418
+ raise ArgumentError, "not boolean: #{key}=#{value.inspect}"
419
+ end
420
+ unless (value = options[:delay]).nil?
421
+ Numeric === value or
422
+ raise ArgumentError, "not numeric: delay=#{value.inspect}"
423
+ end
424
+ set[:listener_opts][address].merge!(options)
425
+ end
426
+
427
+ set[:listeners] << address
428
+ end
429
+
430
+ # sets the +path+ for the PID file of the unicorn master process
431
+ def pid(path); set_path(:pid, path); end
432
+
433
+ # Enabling this preloads an application before forking worker
434
+ # processes. This allows memory savings when using a
435
+ # copy-on-write-friendly GC but can cause bad things to happen when
436
+ # resources like sockets are opened at load time by the master
437
+ # process and shared by multiple children. People enabling this are
438
+ # highly encouraged to look at the before_fork/after_fork hooks to
439
+ # properly close/reopen sockets. Files opened for logging do not
440
+ # have to be reopened as (unbuffered-in-userspace) files opened with
441
+ # the File::APPEND flag are written to atomically on UNIX.
442
+ #
443
+ # In addition to reloading the unicorn-specific config settings,
444
+ # SIGHUP will reload application code in the working
445
+ # directory/symlink when workers are gracefully restarted when
446
+ # preload_app=false (the default). As reloading the application
447
+ # sometimes requires RubyGems updates, +Gem.refresh+ is always
448
+ # called before the application is loaded (for RubyGems users).
449
+ #
450
+ # During deployments, care should _always_ be taken to ensure your
451
+ # applications are properly deployed and running. Using
452
+ # preload_app=false (the default) means you _must_ check if
453
+ # your application is responding properly after a deployment.
454
+ # Improperly deployed applications can go into a spawn loop
455
+ # if the application fails to load. While your children are
456
+ # in a spawn loop, it is is possible to fix an application
457
+ # by properly deploying all required code and dependencies.
458
+ # Using preload_app=true means any application load error will
459
+ # cause the master process to exit with an error.
460
+
461
+ def preload_app(bool)
462
+ set_bool(:preload_app, bool)
463
+ end
464
+
465
+ # Toggles making \env[\"rack.input\"] rewindable.
466
+ # Disabling rewindability can improve performance by lowering
467
+ # I/O and memory usage for applications that accept uploads.
468
+ # Keep in mind that the Rack 1.x spec requires
469
+ # \env[\"rack.input\"] to be rewindable, so this allows
470
+ # intentionally violating the current Rack 1.x spec.
471
+ #
472
+ # +rewindable_input+ defaults to +true+ when used with Rack 1.x for
473
+ # Rack conformance. When Rack 2.x is finalized, this will most
474
+ # likely default to +false+ while still conforming to the newer
475
+ # (less demanding) spec.
476
+ def rewindable_input(bool)
477
+ set_bool(:rewindable_input, bool)
478
+ end
479
+
480
+ # The maximum size (in +bytes+) to buffer in memory before
481
+ # resorting to a temporary file. Default is 112 kilobytes.
482
+ # This option has no effect if "rewindable_input" is set to
483
+ # +false+.
484
+ def client_body_buffer_size(bytes)
485
+ set_int(:client_body_buffer_size, bytes, 0)
486
+ end
487
+
488
+ # When enabled, unicorn will check the client connection by writing
489
+ # the beginning of the HTTP headers before calling the application.
490
+ #
491
+ # This will prevent calling the application for clients who have
492
+ # disconnected while their connection was queued.
493
+ #
494
+ # This only affects clients connecting over Unix domain sockets
495
+ # and TCP via loopback (127.*.*.*). It is unlikely to detect
496
+ # disconnects if the client is on a remote host (even on a fast LAN).
497
+ #
498
+ # This option cannot be used in conjunction with :tcp_nopush.
499
+ def check_client_connection(bool)
500
+ set_bool(:check_client_connection, bool)
501
+ end
502
+
503
+ # Allow redirecting $stderr to a given path. Unlike doing this from
504
+ # the shell, this allows the unicorn process to know the path its
505
+ # writing to and rotate the file if it is used for logging. The
506
+ # file will be opened with the File::APPEND flag and writes
507
+ # synchronized to the kernel (but not necessarily to _disk_) so
508
+ # multiple processes can safely append to it.
509
+ #
510
+ # If you are daemonizing and using the default +logger+, it is important
511
+ # to specify this as errors will otherwise be lost to /dev/null.
512
+ # Some applications/libraries may also triggering warnings that go to
513
+ # stderr, and they will end up here.
514
+ def stderr_path(path)
515
+ set_path(:stderr_path, path)
516
+ end
517
+
518
+ # Same as stderr_path, except for $stdout. Not many Rack applications
519
+ # write to $stdout, but any that do will have their output written here.
520
+ # It is safe to point this to the same location a stderr_path.
521
+ # Like stderr_path, this defaults to /dev/null when daemonized.
522
+ def stdout_path(path)
523
+ set_path(:stdout_path, path)
524
+ end
525
+
526
+ # sets the working directory for Unicorn. This ensures SIGUSR2 will
527
+ # start a new instance of Unicorn in this directory. This may be
528
+ # a symlink, a common scenario for Capistrano users. Unlike
529
+ # all other Unicorn configuration directives, this binds immediately
530
+ # for error checking and cannot be undone by unsetting it in the
531
+ # configuration file and reloading.
532
+ def working_directory(path)
533
+ # just let chdir raise errors
534
+ path = File.expand_path(path)
535
+ if config_file &&
536
+ config_file[0] != ?/ &&
537
+ ! File.readable?("#{path}/#{config_file}")
538
+ raise ArgumentError,
539
+ "config_file=#{config_file} would not be accessible in" \
540
+ " working_directory=#{path}"
541
+ end
542
+ Dir.chdir(path)
543
+ Unicorn::HttpServer::START_CTX[:cwd] = ENV["PWD"] = path
544
+ end
545
+
546
+ # Runs worker processes as the specified +user+ and +group+.
547
+ # The master process always stays running as the user who started it.
548
+ # This switch will occur after calling the after_fork hook, and only
549
+ # if the Worker#user method is not called in the after_fork hook
550
+ # +group+ is optional and will not change if unspecified.
551
+ def user(user, group = nil)
552
+ # raises ArgumentError on invalid user/group
553
+ Etc.getpwnam(user)
554
+ Etc.getgrnam(group) if group
555
+ set[:user] = [ user, group ]
556
+ end
557
+
558
+ # expands "unix:path/to/foo" to a socket relative to the current path
559
+ # expands pathnames of sockets if relative to "~" or "~username"
560
+ # expands "*:port and ":port" to "0.0.0.0:port"
561
+ def expand_addr(address) #:nodoc:
562
+ return "0.0.0.0:#{address}" if Integer === address
563
+ return address unless String === address
564
+
565
+ case address
566
+ when %r{\Aunix:(.*)\z}
567
+ File.expand_path($1)
568
+ when %r{\A~}
569
+ File.expand_path(address)
570
+ when %r{\A(?:\*:)?(\d+)\z}
571
+ "0.0.0.0:#$1"
572
+ when %r{\A\[([a-fA-F0-9:]+)\]\z}, %r/\A((?:\d+\.){3}\d+)\z/
573
+ canonicalize_tcp($1, 80)
574
+ when %r{\A\[([a-fA-F0-9:]+)\]:(\d+)\z}, %r{\A(.*):(\d+)\z}
575
+ canonicalize_tcp($1, $2.to_i)
576
+ else
577
+ address
578
+ end
579
+ end
580
+
581
+ private
582
+ def set_int(var, n, min) #:nodoc:
583
+ Integer === n or raise ArgumentError, "not an integer: #{var}=#{n.inspect}"
584
+ n >= min or raise ArgumentError, "too low (< #{min}): #{var}=#{n.inspect}"
585
+ set[var] = n
586
+ end
587
+
588
+ def canonicalize_tcp(addr, port)
589
+ packed = Socket.pack_sockaddr_in(port, addr)
590
+ port, addr = Socket.unpack_sockaddr_in(packed)
591
+ addr.include?(':') ? "[#{addr}]:#{port}" : "#{addr}:#{port}"
592
+ end
593
+
594
+ def set_path(var, path) #:nodoc:
595
+ case path
596
+ when NilClass, String
597
+ set[var] = path
598
+ else
599
+ raise ArgumentError
600
+ end
601
+ end
602
+
603
+ def check_bool(var, bool) # :nodoc:
604
+ case bool
605
+ when true, false
606
+ return bool
607
+ end
608
+ raise ArgumentError, "#{var}=#{bool.inspect} not a boolean"
609
+ end
610
+
611
+ def set_bool(var, bool) #:nodoc:
612
+ set[var] = check_bool(var, bool)
613
+ end
614
+
615
+ def set_hook(var, my_proc, req_arity = 2) #:nodoc:
616
+ case my_proc
617
+ when Proc
618
+ arity = my_proc.arity
619
+ (arity == req_arity) or \
620
+ raise ArgumentError,
621
+ "#{var}=#{my_proc.inspect} has invalid arity: " \
622
+ "#{arity} (need #{req_arity})"
623
+ when NilClass
624
+ my_proc = DEFAULTS[var]
625
+ else
626
+ raise ArgumentError, "invalid type: #{var}=#{my_proc.inspect}"
627
+ end
628
+ set[var] = my_proc
629
+ end
630
+
631
+ # this is called _after_ working_directory is bound. This only
632
+ # parses the embedded switches in .ru files
633
+ # (for "rackup" compatibility)
634
+ def parse_rackup_file # :nodoc:
635
+ ru = RACKUP[:file] or return # we only return here in unit tests
636
+
637
+ # :rails means use (old) Rails autodetect
638
+ if ru == :rails
639
+ File.readable?('config.ru') or return
640
+ ru = 'config.ru'
641
+ end
642
+
643
+ File.readable?(ru) or
644
+ raise ArgumentError, "rackup file (#{ru}) not readable"
645
+
646
+ # it could be a .rb file, too, we don't parse those manually
647
+ ru.end_with?('.ru') or return
648
+
649
+ /^#\\(.*)/ =~ File.read(ru) or return
650
+ RACKUP[:optparse].parse!($1.split(/\s+/))
651
+
652
+ if RACKUP[:daemonize]
653
+ # unicorn_rails wants a default pid path, (not plain 'unicorn')
654
+ if after_reload
655
+ spid = set[:pid]
656
+ pid('tmp/pids/unicorn.pid') if spid.nil? || spid == :unset
657
+ end
658
+ unless RACKUP[:daemonized]
659
+ Unicorn::Launcher.daemonize!(RACKUP[:options])
660
+ RACKUP[:ready_pipe] = RACKUP[:options].delete(:ready_pipe)
661
+ end
662
+ end
663
+ end
664
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: binary -*-
2
+
3
+ module Unicorn::Const # :nodoc:
4
+ # default TCP listen host address (0.0.0.0, all interfaces)
5
+ DEFAULT_HOST = "0.0.0.0"
6
+
7
+ # default TCP listen port (8080)
8
+ DEFAULT_PORT = 8080
9
+
10
+ # default TCP listen address and port (0.0.0.0:8080)
11
+ DEFAULT_LISTEN = "#{DEFAULT_HOST}:#{DEFAULT_PORT}"
12
+
13
+ # The basic request body size we'll try to read at once (16 kilobytes).
14
+ CHUNK_SIZE = 16 * 1024
15
+
16
+ # Maximum request body size before it is moved out of memory and into a
17
+ # temporary file for reading (112 kilobytes). This is the default
18
+ # value of client_body_buffer_size.
19
+ MAX_BODY = 1024 * 112
20
+ end
21
+ require_relative 'version'