unicorn 3.5.0 → 3.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +0 -1
- data/DESIGN +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +4 -4
- data/KNOWN_ISSUES +8 -1
- data/README +1 -1
- data/bin/unicorn +2 -2
- data/bin/unicorn_rails +6 -6
- data/examples/logrotate.conf +29 -0
- data/examples/unicorn.conf.rb +7 -0
- data/lib/unicorn.rb +19 -7
- data/lib/unicorn/app/exec_cgi.rb +1 -1
- data/lib/unicorn/app/inetd.rb +1 -2
- data/lib/unicorn/app/old_rails.rb +1 -0
- data/lib/unicorn/app/old_rails/static.rb +1 -1
- data/lib/unicorn/cgi_wrapper.rb +1 -0
- data/lib/unicorn/configurator.rb +120 -91
- data/lib/unicorn/const.rb +1 -0
- data/lib/unicorn/http_request.rb +2 -1
- data/lib/unicorn/http_response.rb +1 -0
- data/lib/unicorn/http_server.rb +26 -9
- data/lib/unicorn/launcher.rb +1 -0
- data/lib/unicorn/preread_input.rb +3 -0
- data/lib/unicorn/socket_helper.rb +1 -1
- data/lib/unicorn/stream_input.rb +1 -1
- data/lib/unicorn/tmpio.rb +1 -1
- data/lib/unicorn/util.rb +5 -4
- data/lib/unicorn/worker.rb +13 -6
- data/script/isolate_for_tests +2 -2
- data/t/t0100-rack-input-tests.sh +1 -1
- data/test/unit/test_http_parser.rb +0 -1
- metadata +6 -24
- data/test/rails/app-2.3.8/.gitignore +0 -2
- data/test/rails/app-2.3.8/Rakefile +0 -7
- data/test/rails/app-2.3.8/app/controllers/application_controller.rb +0 -5
- data/test/rails/app-2.3.8/app/controllers/foo_controller.rb +0 -36
- data/test/rails/app-2.3.8/app/helpers/application_helper.rb +0 -4
- data/test/rails/app-2.3.8/config/boot.rb +0 -109
- data/test/rails/app-2.3.8/config/database.yml +0 -12
- data/test/rails/app-2.3.8/config/environment.rb +0 -17
- data/test/rails/app-2.3.8/config/environments/development.rb +0 -7
- data/test/rails/app-2.3.8/config/environments/production.rb +0 -6
- data/test/rails/app-2.3.8/config/routes.rb +0 -6
- data/test/rails/app-2.3.8/db/.gitignore +0 -0
- data/test/rails/app-2.3.8/public/404.html +0 -1
- data/test/rails/app-2.3.8/public/500.html +0 -1
- data/test/rails/app-2.3.8/public/x.txt +0 -1
data/.document
CHANGED
data/DESIGN
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
only non-Ruby part and there are no plans to add any more
|
12
12
|
non-Ruby components.
|
13
13
|
|
14
|
-
* All HTTP
|
14
|
+
* All HTTP parsing and I/O is done much like Mongrel:
|
15
15
|
1. read/parse HTTP request headers in full
|
16
16
|
2. call Rack application
|
17
17
|
3. write HTTP response back to the client
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -15,7 +15,7 @@ GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
|
15
15
|
-include local.mk
|
16
16
|
ruby_bin := $(shell which $(RUBY))
|
17
17
|
ifeq ($(DLEXT),) # "so" for Linux
|
18
|
-
DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts
|
18
|
+
DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts RbConfig::CONFIG["DLEXT"]')
|
19
19
|
endif
|
20
20
|
ifeq ($(RUBY_VERSION),)
|
21
21
|
RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
|
@@ -205,9 +205,9 @@ $(rails_git)/info/cloned-stamp:
|
|
205
205
|
git clone --mirror -q $(rails_git_url) $(rails_git)
|
206
206
|
> $@
|
207
207
|
|
208
|
-
$(rails_git)/info/v2.3
|
208
|
+
$(rails_git)/info/v2.2.3-stamp: $(rails_git)/info/cloned-stamp
|
209
209
|
cd $(rails_git) && git fetch
|
210
|
-
cd $(rails_git) && git rev-parse --verify refs/tags/v2.3
|
210
|
+
cd $(rails_git) && git rev-parse --verify refs/tags/v2.2.3
|
211
211
|
> $@
|
212
212
|
|
213
213
|
rails_tests := $(addsuffix .r,$(addprefix $(T_r).,$(rails_vers)))
|
@@ -220,7 +220,7 @@ $(T_r).%.r: export PATH := $(test_prefix)/bin:$(PATH)
|
|
220
220
|
$(T_r).%.r: export RUBYLIB := $(test_prefix):$(test_prefix)/lib:$(MYLIBS)
|
221
221
|
$(T_r).%.r: export UNICORN_RAILS_TEST_VERSION = $(rv)
|
222
222
|
$(T_r).%.r: export RAILS_GIT_REPO = $(CURDIR)/$(rails_git)
|
223
|
-
$(T_r).%.r: $(test_prefix)/.stamp $(rails_git)/info/v2.3
|
223
|
+
$(T_r).%.r: $(test_prefix)/.stamp $(rails_git)/info/v2.2.3-stamp
|
224
224
|
$(run_test)
|
225
225
|
|
226
226
|
ifneq ($(VERSION),)
|
data/KNOWN_ISSUES
CHANGED
@@ -3,8 +3,15 @@
|
|
3
3
|
Occasionally odd {issues}[link:ISSUES.html] arise without a transparent or
|
4
4
|
acceptable solution. Those issues are documented here.
|
5
5
|
|
6
|
+
* PRNGs (pseudo-random number generators) loaded before forking
|
7
|
+
(e.g. "preload_app true") may need to have their internal state
|
8
|
+
reset in the after_fork hook. Starting with \Unicorn 3.6.0, we
|
9
|
+
have builtin workarounds for Kernel#rand and OpenSSL::Random users,
|
10
|
+
but applications may use other PRNGs.
|
11
|
+
|
6
12
|
* Under some versions of Ruby 1.8, it is necessary to call +srand+ in an
|
7
|
-
after_fork hook to get correct random number generation.
|
13
|
+
after_fork hook to get correct random number generation. We have a builtin
|
14
|
+
workaround for this starting with \Unicorn 3.6.0
|
8
15
|
|
9
16
|
See http://redmine.ruby-lang.org/issues/show/4338
|
10
17
|
|
data/README
CHANGED
data/bin/unicorn
CHANGED
@@ -7,7 +7,7 @@ ENV["RACK_ENV"] ||= "development"
|
|
7
7
|
rackup_opts = Unicorn::Configurator::RACKUP
|
8
8
|
options = rackup_opts[:options]
|
9
9
|
|
10
|
-
|
10
|
+
op = OptionParser.new("", 24, ' ') do |opts|
|
11
11
|
cmd = File.basename($0)
|
12
12
|
opts.banner = "Usage: #{cmd} " \
|
13
13
|
"[ruby options] [#{cmd} options] [rackup config file]"
|
@@ -105,7 +105,7 @@ opts = OptionParser.new("", 24, ' ') do |opts|
|
|
105
105
|
opts.parse! ARGV
|
106
106
|
end
|
107
107
|
|
108
|
-
app = Unicorn.builder(ARGV[0] || 'config.ru',
|
108
|
+
app = Unicorn.builder(ARGV[0] || 'config.ru', op)
|
109
109
|
|
110
110
|
if $DEBUG
|
111
111
|
require 'pp'
|
data/bin/unicorn_rails
CHANGED
@@ -8,7 +8,7 @@ ENV['RAILS_ENV'] ||= "development"
|
|
8
8
|
rackup_opts = Unicorn::Configurator::RACKUP
|
9
9
|
options = rackup_opts[:options]
|
10
10
|
|
11
|
-
|
11
|
+
op = OptionParser.new("", 24, ' ') do |opts|
|
12
12
|
cmd = File.basename($0)
|
13
13
|
opts.banner = "Usage: #{cmd} " \
|
14
14
|
"[ruby options] [#{cmd} options] [rackup config file]"
|
@@ -124,11 +124,11 @@ def rails_dispatcher
|
|
124
124
|
result || abort("Unable to locate the application dispatcher class")
|
125
125
|
end
|
126
126
|
|
127
|
-
def rails_builder(ru,
|
128
|
-
return Unicorn.builder(ru,
|
127
|
+
def rails_builder(ru, op, daemonize)
|
128
|
+
return Unicorn.builder(ru, op) if ru
|
129
129
|
|
130
130
|
# allow Configurator to parse cli switches embedded in the ru file
|
131
|
-
Unicorn::Configurator::RACKUP.update(:file => :rails, :optparse =>
|
131
|
+
Unicorn::Configurator::RACKUP.update(:file => :rails, :optparse => op)
|
132
132
|
|
133
133
|
# this lambda won't run until after forking if preload_app is false
|
134
134
|
# this runs after config file reloading
|
@@ -136,7 +136,7 @@ def rails_builder(ru, opts, daemonize)
|
|
136
136
|
# Rails 3 includes a config.ru, use it if we find it after
|
137
137
|
# working_directory is bound.
|
138
138
|
::File.exist?('config.ru') and
|
139
|
-
return Unicorn.builder('config.ru',
|
139
|
+
return Unicorn.builder('config.ru', op).call
|
140
140
|
|
141
141
|
# Load Rails and (possibly) the private version of Rack it bundles.
|
142
142
|
begin
|
@@ -185,7 +185,7 @@ def rails_builder(ru, opts, daemonize)
|
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
188
|
-
app = rails_builder(ARGV[0],
|
188
|
+
app = rails_builder(ARGV[0], op, rackup_opts[:daemonize])
|
189
189
|
|
190
190
|
if $DEBUG
|
191
191
|
require 'pp'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# example logrotate config file, I usually keep this in
|
2
|
+
# /etc/logrotate.d/unicorn_app on my Debian systems
|
3
|
+
#
|
4
|
+
# See the logrotate(8) manpage for more information:
|
5
|
+
# http://linux.die.net/man/8/logrotate
|
6
|
+
|
7
|
+
# Modify the following glob to match the logfiles your app writes to:
|
8
|
+
/var/log/unicorn_app/*.log {
|
9
|
+
# this first block is mostly just personal preference, though
|
10
|
+
# I wish logrotate offered an "hourly" option...
|
11
|
+
daily
|
12
|
+
missingok
|
13
|
+
rotate 180
|
14
|
+
compress # must use with delaycompress below
|
15
|
+
dateext
|
16
|
+
|
17
|
+
# this is important if using "compress" since we need to call
|
18
|
+
# the "lastaction" script below before compressing:
|
19
|
+
delaycompress
|
20
|
+
|
21
|
+
# note the lack of the evil "copytruncate" option in this
|
22
|
+
# config. Unicorn supports the USR1 signal and we send it
|
23
|
+
# as our "lastaction" action:
|
24
|
+
lastaction
|
25
|
+
# assuming your pid file is in /var/run/unicorn_app/pid
|
26
|
+
pid=/var/run/unicorn_app/pid
|
27
|
+
test -s $pid && kill -USR1 "$(cat $pid)"
|
28
|
+
endscript
|
29
|
+
}
|
data/examples/unicorn.conf.rb
CHANGED
@@ -12,6 +12,13 @@
|
|
12
12
|
# more will usually help for _short_ waits on databases/caches.
|
13
13
|
worker_processes 4
|
14
14
|
|
15
|
+
# Since Unicorn is never exposed to outside clients, it does not need to
|
16
|
+
# run on the standard HTTP port (80), there is no reason to start Unicorn
|
17
|
+
# as root unless it's from system init scripts.
|
18
|
+
# If running the master process as root and the workers as an unprivileged
|
19
|
+
# user, do this to switch euid/egid in the workers (also chowns logs):
|
20
|
+
# user "unprivileged_user", "unprivileged_group"
|
21
|
+
|
15
22
|
# Help ensure your application will always spawn in the symlinked
|
16
23
|
# "current" directory that Capistrano sets up.
|
17
24
|
working_directory "/path/to/app/current" # available in 0.94.0+
|
data/lib/unicorn.rb
CHANGED
@@ -5,10 +5,27 @@ require 'stringio'
|
|
5
5
|
require 'rack'
|
6
6
|
require 'kgio'
|
7
7
|
|
8
|
+
# :stopdoc:
|
8
9
|
# Unicorn module containing all of the classes (include C extensions) for
|
9
10
|
# running a Unicorn web server. It contains a minimalist HTTP server with just
|
10
11
|
# enough functionality to service web application requests fast as possible.
|
12
|
+
# :startdoc:
|
13
|
+
|
14
|
+
# \Unicorn exposes very little of an user-visible API and most of its
|
15
|
+
# internals are subject to change. \Unicorn is designed to host Rack
|
16
|
+
# applications, so applications should be written against the Rack SPEC
|
17
|
+
# and not \Unicorn internals.
|
11
18
|
module Unicorn
|
19
|
+
|
20
|
+
# Raised inside TeeInput when a client closes the socket inside the
|
21
|
+
# application dispatch. This is always raised with an empty backtrace
|
22
|
+
# since there is nothing in the application stack that is responsible
|
23
|
+
# for client shutdowns/disconnects. This exception is visible to Rack
|
24
|
+
# applications unless PrereadInput middleware is loaded.
|
25
|
+
class ClientShutdown < EOFError
|
26
|
+
end
|
27
|
+
|
28
|
+
# :stopdoc:
|
12
29
|
def self.run(app, options = {})
|
13
30
|
Unicorn::HttpServer.new(app, options).start.join
|
14
31
|
end
|
@@ -63,14 +80,9 @@ module Unicorn
|
|
63
80
|
Unicorn::SocketHelper.sock_name(io)
|
64
81
|
end
|
65
82
|
end
|
83
|
+
# :startdoc:
|
66
84
|
end
|
67
|
-
|
68
|
-
# raised inside TeeInput when a client closes the socket inside the
|
69
|
-
# application dispatch. This is always raised with an empty backtrace
|
70
|
-
# since there is nothing in the application stack that is responsible
|
71
|
-
# for client shutdowns/disconnects.
|
72
|
-
class Unicorn::ClientShutdown < EOFError; end
|
73
|
-
|
85
|
+
# :enddoc:
|
74
86
|
require 'unicorn/const'
|
75
87
|
require 'unicorn/socket_helper'
|
76
88
|
require 'unicorn/stream_input'
|
data/lib/unicorn/app/exec_cgi.rb
CHANGED
data/lib/unicorn/app/inetd.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
|
-
|
2
|
+
# :enddoc:
|
3
3
|
# Copyright (c) 2009 Eric Wong
|
4
4
|
# You can redistribute it and/or modify it under the same terms as Ruby.
|
5
5
|
|
6
6
|
# this class *must* be used with Rack::Chunked
|
7
|
-
|
8
7
|
module Unicorn::App
|
9
8
|
class Inetd < Struct.new(:cmd)
|
10
9
|
|
data/lib/unicorn/cgi_wrapper.rb
CHANGED
data/lib/unicorn/configurator.rb
CHANGED
@@ -103,20 +103,24 @@ class Unicorn::Configurator
|
|
103
103
|
set[key]
|
104
104
|
end
|
105
105
|
|
106
|
-
# sets object to the +
|
106
|
+
# sets object to the +obj+ Logger-like object. The new Logger-like
|
107
107
|
# object must respond to the following methods:
|
108
|
-
#
|
108
|
+
# * debug
|
109
|
+
# * info
|
110
|
+
# * warn
|
111
|
+
# * error
|
112
|
+
# * fatal
|
109
113
|
# The default Logger will log its output to the path specified
|
110
114
|
# by +stderr_path+. If you're running Unicorn daemonized, then
|
111
115
|
# you must specify a path to prevent error messages from going
|
112
116
|
# to /dev/null.
|
113
|
-
def logger(
|
117
|
+
def logger(obj)
|
114
118
|
%w(debug info warn error fatal).each do |m|
|
115
|
-
|
116
|
-
raise ArgumentError, "logger=#{
|
119
|
+
obj.respond_to?(m) and next
|
120
|
+
raise ArgumentError, "logger=#{obj} does not respond to method=#{m}"
|
117
121
|
end
|
118
122
|
|
119
|
-
set[:logger] =
|
123
|
+
set[:logger] = obj
|
120
124
|
end
|
121
125
|
|
122
126
|
# sets after_fork hook to a given block. This block will be called by
|
@@ -132,11 +136,6 @@ class Unicorn::Configurator
|
|
132
136
|
# # Existing options for Unicorn::Configurator#listen such as
|
133
137
|
# # :backlog, :rcvbuf, :sndbuf are available here as well.
|
134
138
|
# server.listen(addr, :tries => -1, :delay => 5, :backlog => 128)
|
135
|
-
#
|
136
|
-
# # drop permissions to "www-data" in the worker
|
137
|
-
# # generally there's no reason to start Unicorn as a priviledged user
|
138
|
-
# # as it is not recommended to expose Unicorn to public clients.
|
139
|
-
# worker.user('www-data', 'www-data') if Process.euid == 0
|
140
139
|
# end
|
141
140
|
def after_fork(*args, &block)
|
142
141
|
set_hook(:after_fork, block_given? ? block : args[0])
|
@@ -208,131 +207,157 @@ class Unicorn::Configurator
|
|
208
207
|
set[:listeners] = addresses
|
209
208
|
end
|
210
209
|
|
211
|
-
#
|
210
|
+
# Adds an +address+ to the existing listener set. May be specified more
|
211
|
+
# than once. +address+ may be an Integer port number for a TCP port, an
|
212
|
+
# "IP_ADDRESS:PORT" for TCP listeners or a pathname for UNIX domain sockets.
|
213
|
+
#
|
214
|
+
# listen 3000 # listen to port 3000 on all TCP interfaces
|
215
|
+
# listen "127.0.0.1:3000" # listen to port 3000 on the loopback interface
|
216
|
+
# listen "/tmp/.unicorn.sock" # listen on the given Unix domain socket
|
217
|
+
# listen "[::1]:3000" # listen to port 3000 on the IPv6 loopback interface
|
212
218
|
#
|
213
219
|
# The following options may be specified (but are generally not needed):
|
214
220
|
#
|
215
|
-
#
|
221
|
+
# [:backlog => number of clients]
|
222
|
+
#
|
223
|
+
# This is the backlog of the listen() syscall.
|
224
|
+
#
|
225
|
+
# Some operating systems allow negative values here to specify the
|
226
|
+
# maximum allowable value. In most cases, this number is only
|
227
|
+
# recommendation and there are other OS-specific tunables and
|
228
|
+
# variables that can affect this number. See the listen(2)
|
229
|
+
# syscall documentation of your OS for the exact semantics of
|
230
|
+
# this.
|
231
|
+
#
|
232
|
+
# If you are running unicorn on multiple machines, lowering this number
|
233
|
+
# can help your load balancer detect when a machine is overloaded
|
234
|
+
# and give requests to a different machine.
|
235
|
+
#
|
236
|
+
# Default: 1024
|
216
237
|
#
|
217
|
-
#
|
218
|
-
# maximum allowable value. In most cases, this number is only
|
219
|
-
# recommendation and there are other OS-specific tunables and
|
220
|
-
# variables that can affect this number. See the listen(2)
|
221
|
-
# syscall documentation of your OS for the exact semantics of
|
222
|
-
# this.
|
238
|
+
# [:rcvbuf => bytes, :sndbuf => bytes]
|
223
239
|
#
|
224
|
-
#
|
225
|
-
# can help your load balancer detect when a machine is overloaded
|
226
|
-
# and give requests to a different machine.
|
240
|
+
# Maximum receive and send buffer sizes (in bytes) of sockets.
|
227
241
|
#
|
228
|
-
#
|
242
|
+
# These correspond to the SO_RCVBUF and SO_SNDBUF settings which
|
243
|
+
# can be set via the setsockopt(2) syscall. Some kernels
|
244
|
+
# (e.g. Linux 2.4+) have intelligent auto-tuning mechanisms and
|
245
|
+
# there is no need (and it is sometimes detrimental) to specify them.
|
229
246
|
#
|
230
|
-
#
|
247
|
+
# See the socket API documentation of your operating system
|
248
|
+
# to determine the exact semantics of these settings and
|
249
|
+
# other operating system-specific knobs where they can be
|
250
|
+
# specified.
|
231
251
|
#
|
232
|
-
#
|
233
|
-
# can be set via the setsockopt(2) syscall. Some kernels
|
234
|
-
# (e.g. Linux 2.4+) have intelligent auto-tuning mechanisms and
|
235
|
-
# there is no need (and it is sometimes detrimental) to specify them.
|
252
|
+
# Defaults: operating system defaults
|
236
253
|
#
|
237
|
-
#
|
238
|
-
# to determine the exact semantics of these settings and
|
239
|
-
# other operating system-specific knobs where they can be
|
240
|
-
# specified.
|
254
|
+
# [:tcp_nodelay => true or false]
|
241
255
|
#
|
242
|
-
#
|
256
|
+
# Disables Nagle's algorithm on TCP sockets if +true+
|
243
257
|
#
|
244
|
-
#
|
258
|
+
# This has no effect on UNIX sockets.
|
245
259
|
#
|
246
|
-
#
|
260
|
+
# Default: operating system defaults (usually Nagle's algorithm enabled)
|
247
261
|
#
|
248
|
-
#
|
262
|
+
# [:tcp_nopush => true or false]
|
249
263
|
#
|
250
|
-
#
|
264
|
+
# Enables/disables TCP_CORK in Linux or TCP_NOPUSH in FreeBSD
|
251
265
|
#
|
252
|
-
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
#
|
256
|
-
#
|
266
|
+
# This is enabled by default as of Unicorn 3.4. This prevents partial
|
267
|
+
# TCP frames from being sent out and reduces wakeups in nginx if it is
|
268
|
+
# on a different machine. Since Unicorn is only designed for applications
|
269
|
+
# that send the response body quickly without keepalive, sockets will
|
270
|
+
# always be flushed on close to prevent delays.
|
257
271
|
#
|
258
|
-
#
|
272
|
+
# This has no effect on UNIX sockets.
|
259
273
|
#
|
260
|
-
#
|
274
|
+
# [:tries => Integer]
|
261
275
|
#
|
262
|
-
#
|
263
|
-
# useful for migrations and upgrades when individual workers
|
264
|
-
# are binding to different ports.
|
276
|
+
# Times to retry binding a socket if it is already in use
|
265
277
|
#
|
266
|
-
#
|
278
|
+
# A negative number indicates we will retry indefinitely, this is
|
279
|
+
# useful for migrations and upgrades when individual workers
|
280
|
+
# are binding to different ports.
|
267
281
|
#
|
268
|
-
#
|
282
|
+
# Default: 5
|
269
283
|
#
|
270
|
-
#
|
284
|
+
# [:delay => seconds]
|
271
285
|
#
|
272
|
-
#
|
286
|
+
# Seconds to wait between successive +tries+
|
273
287
|
#
|
274
|
-
#
|
275
|
-
# file permissions than the rest of the application. By default,
|
276
|
-
# we create UNIX domain sockets to be readable and writable by
|
277
|
-
# all local users to give them the same accessibility as
|
278
|
-
# locally-bound TCP listeners.
|
288
|
+
# Default: 0.5 seconds
|
279
289
|
#
|
280
|
-
#
|
290
|
+
# [:umask => mode]
|
281
291
|
#
|
282
|
-
#
|
292
|
+
# Sets the file mode creation mask for UNIX sockets. If specified,
|
293
|
+
# this is usually in octal notation.
|
283
294
|
#
|
284
|
-
#
|
295
|
+
# Typically UNIX domain sockets are created with more liberal
|
296
|
+
# file permissions than the rest of the application. By default,
|
297
|
+
# we create UNIX domain sockets to be readable and writable by
|
298
|
+
# all local users to give them the same accessibility as
|
299
|
+
# locally-bound TCP listeners.
|
285
300
|
#
|
286
|
-
#
|
287
|
-
# defer an accept() for if no data arrives, but the client will
|
288
|
-
# eventually be accepted after the specified number of retransmits
|
289
|
-
# regardless of whether data is ready.
|
301
|
+
# This has no effect on TCP listeners.
|
290
302
|
#
|
291
|
-
#
|
292
|
-
# accepts are _always_ deferred indefinitely if no data arrives.
|
293
|
-
# This is similar to <code>:accept_filter => "dataready"</code>
|
294
|
-
# under FreeBSD.
|
303
|
+
# Default: 0000 (world-read/writable)
|
295
304
|
#
|
296
|
-
#
|
297
|
-
# and +false+ or +nil+ is synonymous for a value of zero.
|
305
|
+
# [:tcp_defer_accept => Integer]
|
298
306
|
#
|
299
|
-
#
|
300
|
-
# and trusted clients. For Rainbows! and Zbatery users, a higher
|
301
|
-
# value (e.g. +60+) provides more protection against some
|
302
|
-
# denial-of-service attacks. There is no good reason to ever
|
303
|
-
# disable this with a +zero+ value when serving HTTP.
|
307
|
+
# Defer accept() until data is ready (Linux-only)
|
304
308
|
#
|
305
|
-
#
|
309
|
+
# For Linux 2.6.32 and later, this is the number of retransmits to
|
310
|
+
# defer an accept() for if no data arrives, but the client will
|
311
|
+
# eventually be accepted after the specified number of retransmits
|
312
|
+
# regardless of whether data is ready.
|
306
313
|
#
|
307
|
-
#
|
314
|
+
# For Linux before 2.6.32, this is a boolean option, and
|
315
|
+
# accepts are _always_ deferred indefinitely if no data arrives.
|
316
|
+
# This is similar to <code>:accept_filter => "dataready"</code>
|
317
|
+
# under FreeBSD.
|
308
318
|
#
|
309
|
-
#
|
310
|
-
#
|
311
|
-
# optimization to reduce context switches with common GET/HEAD
|
312
|
-
# requests. For Rainbows! and Zbatery users, this provides
|
313
|
-
# some protection against certain denial-of-service attacks, too.
|
319
|
+
# Specifying +true+ is synonymous for the default value(s) below,
|
320
|
+
# and +false+ or +nil+ is synonymous for a value of zero.
|
314
321
|
#
|
315
|
-
#
|
322
|
+
# A value of +1+ is a good optimization for local networks
|
323
|
+
# and trusted clients. For Rainbows! and Zbatery users, a higher
|
324
|
+
# value (e.g. +60+) provides more protection against some
|
325
|
+
# denial-of-service attacks. There is no good reason to ever
|
326
|
+
# disable this with a +zero+ value when serving HTTP.
|
316
327
|
#
|
317
|
-
#
|
318
|
-
|
328
|
+
# Default: 1 retransmit for \Unicorn, 60 for Rainbows! 0.95.0\+
|
329
|
+
#
|
330
|
+
# [:accept_filter => String]
|
331
|
+
#
|
332
|
+
# defer accept() until data is ready (FreeBSD-only)
|
333
|
+
#
|
334
|
+
# This enables either the "dataready" or (default) "httpready"
|
335
|
+
# accept() filter under FreeBSD. This is intended as an
|
336
|
+
# optimization to reduce context switches with common GET/HEAD
|
337
|
+
# requests. For Rainbows! and Zbatery users, this provides
|
338
|
+
# some protection against certain denial-of-service attacks, too.
|
339
|
+
#
|
340
|
+
# There is no good reason to change from the default.
|
341
|
+
#
|
342
|
+
# Default: "httpready"
|
343
|
+
def listen(address, options = {})
|
319
344
|
address = expand_addr(address)
|
320
345
|
if String === address
|
321
346
|
[ :umask, :backlog, :sndbuf, :rcvbuf, :tries ].each do |key|
|
322
|
-
value =
|
347
|
+
value = options[key] or next
|
323
348
|
Integer === value or
|
324
349
|
raise ArgumentError, "not an integer: #{key}=#{value.inspect}"
|
325
350
|
end
|
326
351
|
[ :tcp_nodelay, :tcp_nopush ].each do |key|
|
327
|
-
(value =
|
352
|
+
(value = options[key]).nil? and next
|
328
353
|
TrueClass === value || FalseClass === value or
|
329
354
|
raise ArgumentError, "not boolean: #{key}=#{value.inspect}"
|
330
355
|
end
|
331
|
-
unless (value =
|
356
|
+
unless (value = options[:delay]).nil?
|
332
357
|
Numeric === value or
|
333
358
|
raise ArgumentError, "not numeric: delay=#{value.inspect}"
|
334
359
|
end
|
335
|
-
set[:listener_opts][address].merge!(
|
360
|
+
set[:listener_opts][address].merge!(options)
|
336
361
|
end
|
337
362
|
|
338
363
|
set[:listeners] << address
|
@@ -373,11 +398,11 @@ class Unicorn::Configurator
|
|
373
398
|
set_bool(:preload_app, bool)
|
374
399
|
end
|
375
400
|
|
376
|
-
# Toggles making
|
401
|
+
# Toggles making \env[\"rack.input\"] rewindable.
|
377
402
|
# Disabling rewindability can improve performance by lowering
|
378
403
|
# I/O and memory usage for applications that accept uploads.
|
379
404
|
# Keep in mind that the Rack 1.x spec requires
|
380
|
-
#
|
405
|
+
# \env[\"rack.input\"] to be rewindable, so this allows
|
381
406
|
# intentionally violating the current Rack 1.x spec.
|
382
407
|
#
|
383
408
|
# +rewindable_input+ defaults to +true+ when used with Rack 1.x for
|
@@ -443,6 +468,7 @@ class Unicorn::Configurator
|
|
443
468
|
# The master process always stays running as the user who started it.
|
444
469
|
# This switch will occur after calling the after_fork hook, and only
|
445
470
|
# if the Worker#user method is not called in the after_fork hook
|
471
|
+
# +group+ is optional and will not change if unspecified.
|
446
472
|
def user(user, group = nil)
|
447
473
|
# raises ArgumentError on invalid user/group
|
448
474
|
Etc.getpwnam(user)
|
@@ -455,6 +481,9 @@ class Unicorn::Configurator
|
|
455
481
|
# Rainbows!/Zbatery installations facing untrusted clients directly
|
456
482
|
# should set this to +false+. This is +true+ by default as Unicorn
|
457
483
|
# is designed to only sit behind trusted nginx proxies.
|
484
|
+
#
|
485
|
+
# This has never been publically documented and is subject to removal
|
486
|
+
# in future releases.
|
458
487
|
def trust_x_forwarded(bool) # :nodoc:
|
459
488
|
set_bool(:trust_x_forwarded, bool)
|
460
489
|
end
|
@@ -462,7 +491,7 @@ class Unicorn::Configurator
|
|
462
491
|
# expands "unix:path/to/foo" to a socket relative to the current path
|
463
492
|
# expands pathnames of sockets if relative to "~" or "~username"
|
464
493
|
# expands "*:port and ":port" to "0.0.0.0:port"
|
465
|
-
def expand_addr(address) #:nodoc
|
494
|
+
def expand_addr(address) #:nodoc:
|
466
495
|
return "0.0.0.0:#{address}" if Integer === address
|
467
496
|
return address unless String === address
|
468
497
|
|
data/lib/unicorn/const.rb
CHANGED
data/lib/unicorn/http_request.rb
CHANGED
data/lib/unicorn/http_server.rb
CHANGED
@@ -4,15 +4,19 @@
|
|
4
4
|
# processes which in turn handle the I/O and application process.
|
5
5
|
# Listener sockets are started in the master process and shared with
|
6
6
|
# forked worker children.
|
7
|
+
#
|
8
|
+
# Users do not need to know the internals of this class, but reading the
|
9
|
+
# {source}[http://bogomips.org/unicorn.git/tree/lib/unicorn/http_server.rb]
|
10
|
+
# is education for programmers wishing to learn how \Unicorn works.
|
11
|
+
# See Unicorn::Configurator for information on how to configure \Unicorn.
|
7
12
|
class Unicorn::HttpServer
|
13
|
+
# :stopdoc:
|
8
14
|
attr_accessor :app, :request, :timeout, :worker_processes,
|
9
15
|
:before_fork, :after_fork, :before_exec,
|
10
16
|
:listener_opts, :preload_app,
|
11
17
|
:reexec_pid, :orig_app, :init_listeners,
|
12
18
|
:master_pid, :config, :ready_pipe, :user
|
13
19
|
attr_reader :pid, :logger
|
14
|
-
|
15
|
-
# :stopdoc:
|
16
20
|
include Unicorn::SocketHelper
|
17
21
|
include Unicorn::HttpResponse
|
18
22
|
|
@@ -84,6 +88,7 @@ class Unicorn::HttpServer
|
|
84
88
|
rescue
|
85
89
|
Dir.pwd
|
86
90
|
end
|
91
|
+
# :stopdoc:
|
87
92
|
|
88
93
|
# Creates a working server on host:port (strange things happen if
|
89
94
|
# port isn't a Number). Use HttpServer::run to start the server and
|
@@ -94,7 +99,7 @@ class Unicorn::HttpServer
|
|
94
99
|
@request = Unicorn::HttpRequest.new
|
95
100
|
self.reexec_pid = 0
|
96
101
|
options = options.dup
|
97
|
-
|
102
|
+
@ready_pipe = options.delete(:ready_pipe)
|
98
103
|
self.init_listeners = options[:listeners] ? options[:listeners].dup : []
|
99
104
|
options[:use_defaults] = true
|
100
105
|
self.config = Unicorn::Configurator.new(options)
|
@@ -277,10 +282,10 @@ class Unicorn::HttpServer
|
|
277
282
|
|
278
283
|
proc_name 'master'
|
279
284
|
logger.info "master process ready" # test_exec.rb relies on this message
|
280
|
-
if ready_pipe
|
281
|
-
ready_pipe.syswrite($$.to_s)
|
282
|
-
ready_pipe.close rescue nil
|
283
|
-
|
285
|
+
if @ready_pipe
|
286
|
+
@ready_pipe.syswrite($$.to_s)
|
287
|
+
@ready_pipe.close rescue nil
|
288
|
+
@ready_pipe = nil
|
284
289
|
end
|
285
290
|
begin
|
286
291
|
reap_all_workers
|
@@ -484,14 +489,23 @@ class Unicorn::HttpServer
|
|
484
489
|
next_sleep
|
485
490
|
end
|
486
491
|
|
492
|
+
def after_fork_internal
|
493
|
+
@ready_pipe.close if @ready_pipe
|
494
|
+
self.ready_pipe = nil # XXX Rainbows! compat, change for Unicorn 4.x
|
495
|
+
tmp = srand # http://redmine.ruby-lang.org/issues/4338
|
496
|
+
|
497
|
+
# The OpenSSL PRNG is seeded with only the pid, and apps with frequently
|
498
|
+
# dying workers can recycle pids
|
499
|
+
OpenSSL::Random.seed(tmp.to_s) if defined?(OpenSSL::Random)
|
500
|
+
end
|
501
|
+
|
487
502
|
def spawn_missing_workers
|
488
503
|
(0...worker_processes).each do |worker_nr|
|
489
504
|
WORKERS.values.include?(worker_nr) and next
|
490
505
|
worker = Worker.new(worker_nr, Unicorn::TmpIO.new)
|
491
506
|
before_fork.call(self, worker)
|
492
507
|
WORKERS[fork {
|
493
|
-
|
494
|
-
self.ready_pipe = nil
|
508
|
+
after_fork_internal
|
495
509
|
worker_loop(worker)
|
496
510
|
}] = worker
|
497
511
|
end
|
@@ -568,6 +582,9 @@ class Unicorn::HttpServer
|
|
568
582
|
Unicorn::Util.reopen_logs
|
569
583
|
logger.info "worker=#{worker_nr} done reopening logs"
|
570
584
|
init_self_pipe!
|
585
|
+
rescue => e
|
586
|
+
logger.error(e) rescue nil
|
587
|
+
exit!(77) # EX_NOPERM in sysexits.h
|
571
588
|
end
|
572
589
|
|
573
590
|
# runs inside each forked worker, this sits around and waits
|
data/lib/unicorn/launcher.rb
CHANGED
@@ -17,7 +17,7 @@ module Unicorn
|
|
17
17
|
# denial-of-service attacks
|
18
18
|
:tcp_defer_accept => 1,
|
19
19
|
|
20
|
-
# FreeBSD, we need to override this to 'dataready'
|
20
|
+
# FreeBSD, we need to override this to 'dataready' if we
|
21
21
|
# eventually get HTTPS support
|
22
22
|
:accept_filter => 'httpready',
|
23
23
|
|
data/lib/unicorn/stream_input.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
|
3
3
|
# When processing uploads, Unicorn may expose a StreamInput object under
|
4
|
-
# "rack.input" of the Rack (2.x) environment.
|
4
|
+
# "rack.input" of the (future) Rack (2.x) environment.
|
5
5
|
class Unicorn::StreamInput
|
6
6
|
# The I/O chunk size (in +bytes+) for I/O operations where
|
7
7
|
# the size cannot be user-specified when a method is called.
|
data/lib/unicorn/tmpio.rb
CHANGED
data/lib/unicorn/util.rb
CHANGED
@@ -8,7 +8,6 @@ module Unicorn::Util
|
|
8
8
|
|
9
9
|
! fp.closed? &&
|
10
10
|
fp.sync &&
|
11
|
-
fp.path[0] == ?/ &&
|
12
11
|
(fp.fcntl(Fcntl::F_GETFL) & append_flags) == append_flags
|
13
12
|
rescue IOError, Errno::EBADF
|
14
13
|
false
|
@@ -25,10 +24,12 @@ module Unicorn::Util
|
|
25
24
|
# using logrotate(8) (without copytruncate) or similar tools.
|
26
25
|
# A +File+ object is considered for reopening if it is:
|
27
26
|
# 1) opened with the O_APPEND and O_WRONLY flags
|
28
|
-
# 2)
|
29
|
-
# 3)
|
30
|
-
# 4) unbuffered (as far as userspace buffering goes, not O_SYNC)
|
27
|
+
# 2) the current open file handle does not match its original open path
|
28
|
+
# 3) unbuffered (as far as userspace buffering goes, not O_SYNC)
|
31
29
|
# Returns the number of files reopened
|
30
|
+
#
|
31
|
+
# In Unicorn 3.5.x and earlier, files must be opened with an absolute
|
32
|
+
# path to be considered a log file.
|
32
33
|
def self.reopen_logs
|
33
34
|
to_reopen = []
|
34
35
|
nr = 0
|
data/lib/unicorn/worker.rb
CHANGED
@@ -2,16 +2,23 @@
|
|
2
2
|
|
3
3
|
# This class and its members can be considered a stable interface
|
4
4
|
# and will not change in a backwards-incompatible fashion between
|
5
|
-
# releases of Unicorn.
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# releases of \Unicorn. Knowledge of this class is generally not
|
6
|
+
# not needed for most users of \Unicorn.
|
7
|
+
#
|
8
|
+
# Some users may want to access it in the before_fork/after_fork hooks.
|
9
|
+
# See the Unicorn::Configurator RDoc for examples.
|
8
10
|
class Unicorn::Worker < Struct.new(:nr, :tmp, :switched)
|
9
11
|
|
10
|
-
# worker objects may be compared to just plain
|
11
|
-
def ==(other_nr)
|
12
|
-
|
12
|
+
# worker objects may be compared to just plain Integers
|
13
|
+
def ==(other_nr) # :nodoc:
|
14
|
+
nr == other_nr
|
13
15
|
end
|
14
16
|
|
17
|
+
# In most cases, you should be using the Unicorn::Configurator#user
|
18
|
+
# directive instead. This method should only be used if you need
|
19
|
+
# fine-grained control of exactly when you want to change permissions
|
20
|
+
# in your after_fork hooks.
|
21
|
+
#
|
15
22
|
# Changes the worker process to the specified +user+ and +group+
|
16
23
|
# This is only intended to be called from within the worker
|
17
24
|
# process from the +after_fork+ hook. This should be called in
|
data/script/isolate_for_tests
CHANGED
data/t/t0100-rack-input-tests.sh
CHANGED
@@ -7,7 +7,7 @@ t_plan 10 "rack.input read tests"
|
|
7
7
|
t_begin "setup and startup" && {
|
8
8
|
rtmpfiles curl_out curl_err
|
9
9
|
unicorn_setup
|
10
|
-
unicorn -D rack-input-tests.ru -c $unicorn_config
|
10
|
+
unicorn -E none -D rack-input-tests.ru -c $unicorn_config
|
11
11
|
blob_sha1=$(rsha1 < random_blob)
|
12
12
|
blob_size=$(wc -c < random_blob)
|
13
13
|
t_info "blob_sha1=$blob_sha1"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unicorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 3
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 0
|
10
|
-
version: 3.
|
10
|
+
version: 3.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Unicorn hackers
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
18
|
+
date: 2011-04-21 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: rack
|
@@ -125,7 +124,6 @@ extra_rdoc_files:
|
|
125
124
|
- lib/unicorn/tmpio.rb
|
126
125
|
- lib/unicorn/util.rb
|
127
126
|
- lib/unicorn/worker.rb
|
128
|
-
- ext/unicorn_http/unicorn_http.c
|
129
127
|
- ISSUES
|
130
128
|
- Sandbox
|
131
129
|
files:
|
@@ -167,6 +165,7 @@ files:
|
|
167
165
|
- examples/git.ru
|
168
166
|
- examples/init.sh
|
169
167
|
- examples/logger_mp_safe.rb
|
168
|
+
- examples/logrotate.conf
|
170
169
|
- examples/nginx.conf
|
171
170
|
- examples/unicorn.conf.minimal.rb
|
172
171
|
- examples/unicorn.conf.rb
|
@@ -348,22 +347,6 @@ files:
|
|
348
347
|
- test/rails/app-2.2.2/log/.gitignore
|
349
348
|
- test/rails/app-2.2.2/public/404.html
|
350
349
|
- test/rails/app-2.2.2/public/500.html
|
351
|
-
- test/rails/app-2.3.8/.gitignore
|
352
|
-
- test/rails/app-2.3.8/Rakefile
|
353
|
-
- test/rails/app-2.3.8/app/controllers/application_controller.rb
|
354
|
-
- test/rails/app-2.3.8/app/controllers/foo_controller.rb
|
355
|
-
- test/rails/app-2.3.8/app/helpers/application_helper.rb
|
356
|
-
- test/rails/app-2.3.8/config/boot.rb
|
357
|
-
- test/rails/app-2.3.8/config/database.yml
|
358
|
-
- test/rails/app-2.3.8/config/environment.rb
|
359
|
-
- test/rails/app-2.3.8/config/environments/development.rb
|
360
|
-
- test/rails/app-2.3.8/config/environments/production.rb
|
361
|
-
- test/rails/app-2.3.8/config/routes.rb
|
362
|
-
- test/rails/app-2.3.8/db/.gitignore
|
363
|
-
- test/rails/app-2.3.8/log/.gitignore
|
364
|
-
- test/rails/app-2.3.8/public/404.html
|
365
|
-
- test/rails/app-2.3.8/public/500.html
|
366
|
-
- test/rails/app-2.3.8/public/x.txt
|
367
350
|
- test/rails/test_rails.rb
|
368
351
|
- test/test_helper.rb
|
369
352
|
- test/unit/test_configurator.rb
|
@@ -380,7 +363,6 @@ files:
|
|
380
363
|
- test/unit/test_upload.rb
|
381
364
|
- test/unit/test_util.rb
|
382
365
|
- unicorn.gemspec
|
383
|
-
has_rdoc: true
|
384
366
|
homepage: http://unicorn.bogomips.org/
|
385
367
|
licenses: []
|
386
368
|
|
@@ -413,7 +395,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
413
395
|
requirements: []
|
414
396
|
|
415
397
|
rubyforge_project: mongrel
|
416
|
-
rubygems_version: 1.
|
398
|
+
rubygems_version: 1.7.2
|
417
399
|
signing_key:
|
418
400
|
specification_version: 3
|
419
401
|
summary: Rack HTTP server for fast clients and Unix
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# -*- encoding: binary -*-
|
2
|
-
|
3
|
-
require 'digest/sha1'
|
4
|
-
class FooController < ApplicationController
|
5
|
-
def index
|
6
|
-
render :text => "FOO\n"
|
7
|
-
end
|
8
|
-
|
9
|
-
def xcookie
|
10
|
-
cookies["foo"] = "cookie-#$$-#{session[:gotta_use_the_session_in_2_3]}"
|
11
|
-
render :text => ""
|
12
|
-
end
|
13
|
-
|
14
|
-
def xnotice
|
15
|
-
flash[:notice] = "session #$$"
|
16
|
-
render :text => ""
|
17
|
-
end
|
18
|
-
|
19
|
-
def xpost
|
20
|
-
if request.post?
|
21
|
-
digest = Digest::SHA1.new
|
22
|
-
out = "params: #{params.inspect}\n"
|
23
|
-
if file = params[:file]
|
24
|
-
loop do
|
25
|
-
buf = file.read(4096) or break
|
26
|
-
digest.update(buf)
|
27
|
-
end
|
28
|
-
out << "sha1: #{digest.to_s}\n"
|
29
|
-
end
|
30
|
-
headers['content-type'] = 'text/plain'
|
31
|
-
render :text => out
|
32
|
-
else
|
33
|
-
render :status => 403, :text => "need post\n"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
# -*- encoding: binary -*-
|
2
|
-
|
3
|
-
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
|
4
|
-
|
5
|
-
module Rails
|
6
|
-
class << self
|
7
|
-
def boot!
|
8
|
-
unless booted?
|
9
|
-
preinitialize
|
10
|
-
pick_boot.run
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def booted?
|
15
|
-
defined? Rails::Initializer
|
16
|
-
end
|
17
|
-
|
18
|
-
def pick_boot
|
19
|
-
(vendor_rails? ? VendorBoot : GemBoot).new
|
20
|
-
end
|
21
|
-
|
22
|
-
def vendor_rails?
|
23
|
-
File.exist?("#{RAILS_ROOT}/vendor/rails")
|
24
|
-
end
|
25
|
-
|
26
|
-
def preinitialize
|
27
|
-
load(preinitializer_path) if File.exist?(preinitializer_path)
|
28
|
-
end
|
29
|
-
|
30
|
-
def preinitializer_path
|
31
|
-
"#{RAILS_ROOT}/config/preinitializer.rb"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class Boot
|
36
|
-
def run
|
37
|
-
load_initializer
|
38
|
-
Rails::Initializer.run(:set_load_path)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class VendorBoot < Boot
|
43
|
-
def load_initializer
|
44
|
-
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
|
45
|
-
Rails::Initializer.run(:install_gem_spec_stubs)
|
46
|
-
Rails::GemDependency.add_frozen_gem_path
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class GemBoot < Boot
|
51
|
-
def load_initializer
|
52
|
-
self.class.load_rubygems
|
53
|
-
load_rails_gem
|
54
|
-
require 'initializer'
|
55
|
-
end
|
56
|
-
|
57
|
-
def load_rails_gem
|
58
|
-
if version = self.class.gem_version
|
59
|
-
gem 'rails', version
|
60
|
-
else
|
61
|
-
gem 'rails'
|
62
|
-
end
|
63
|
-
rescue Gem::LoadError => load_error
|
64
|
-
$stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
|
65
|
-
exit 1
|
66
|
-
end
|
67
|
-
|
68
|
-
class << self
|
69
|
-
def rubygems_version
|
70
|
-
Gem::RubyGemsVersion rescue nil
|
71
|
-
end
|
72
|
-
|
73
|
-
def gem_version
|
74
|
-
if defined? RAILS_GEM_VERSION
|
75
|
-
RAILS_GEM_VERSION
|
76
|
-
elsif ENV.include?('RAILS_GEM_VERSION')
|
77
|
-
ENV['RAILS_GEM_VERSION']
|
78
|
-
else
|
79
|
-
parse_gem_version(read_environment_rb)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def load_rubygems
|
84
|
-
require 'rubygems'
|
85
|
-
min_version = '1.3.1'
|
86
|
-
unless rubygems_version >= min_version
|
87
|
-
$stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
|
88
|
-
exit 1
|
89
|
-
end
|
90
|
-
|
91
|
-
rescue LoadError
|
92
|
-
$stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
|
93
|
-
exit 1
|
94
|
-
end
|
95
|
-
|
96
|
-
def parse_gem_version(text)
|
97
|
-
$1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
def read_environment_rb
|
102
|
-
File.read("#{RAILS_ROOT}/config/environment.rb")
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
# All that for this:
|
109
|
-
Rails.boot!
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# -*- encoding: binary -*-
|
2
|
-
|
3
|
-
unless defined? RAILS_GEM_VERSION
|
4
|
-
RAILS_GEM_VERSION = ENV['UNICORN_RAILS_VERSION']
|
5
|
-
end
|
6
|
-
|
7
|
-
# Bootstrap the Rails environment, frameworks, and default configuration
|
8
|
-
require File.join(File.dirname(__FILE__), 'boot')
|
9
|
-
|
10
|
-
Rails::Initializer.run do |config|
|
11
|
-
config.frameworks -= [ :active_resource, :action_mailer ]
|
12
|
-
config.action_controller.session_store = :active_record_store
|
13
|
-
config.action_controller.session = {
|
14
|
-
:session_key => "_unicorn_rails_test.#{rand}",
|
15
|
-
:secret => "#{rand}#{rand}#{rand}#{rand}",
|
16
|
-
}
|
17
|
-
end
|
File without changes
|
@@ -1 +0,0 @@
|
|
1
|
-
404 Not Found
|
@@ -1 +0,0 @@
|
|
1
|
-
500 Internal Server Error
|
@@ -1 +0,0 @@
|
|
1
|
-
HELLO
|