unicorn 3.5.0 → 3.6.0
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.
- 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
|