passenger 4.0.14 → 4.0.16
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- data.tar.gz.asc +7 -7
- data/NEWS +69 -0
- data/bin/passenger-install-apache2-module +7 -1
- data/bin/passenger-install-nginx-module +18 -1
- data/build/apache2.rb +25 -1
- data/build/basics.rb +7 -4
- data/build/debian.rb +72 -25
- data/build/nginx.rb +24 -0
- data/build/packaging.rb +45 -3
- data/debian.template/{control → control.template} +17 -8
- data/debian.template/ruby-passenger.install.template +1 -0
- data/debian.template/rules.template +9 -3
- data/dev/run_travis.sh +14 -0
- data/doc/Users guide Apache.idmap.txt +64 -48
- data/doc/Users guide Apache.txt +127 -93
- data/doc/Users guide Nginx.idmap.txt +46 -28
- data/doc/Users guide Nginx.txt +100 -12
- data/doc/images/{conservative_spawning.png → direct_spawning.png} +0 -0
- data/doc/images/{conservative_spawning.svg → direct_spawning.svg} +0 -0
- data/doc/users_guide_snippets/installation.txt +107 -66
- data/doc/users_guide_snippets/passenger_spawn_method.txt +1 -1
- data/doc/users_guide_snippets/rvm_helper_tool.txt +0 -12
- data/doc/users_guide_snippets/tips.txt +70 -3
- data/doc/users_guide_snippets/under_the_hood/page_caching_support.txt +2 -0
- data/doc/users_guide_snippets/under_the_hood/relationship_with_ruby.txt +114 -0
- data/ext/apache2/Configuration.cpp +53 -101
- data/ext/apache2/Configuration.hpp +19 -41
- data/ext/apache2/ConfigurationCommands.cpp +95 -0
- data/ext/apache2/ConfigurationCommands.cpp.erb +91 -0
- data/ext/apache2/ConfigurationFields.hpp +59 -0
- data/ext/apache2/ConfigurationFields.hpp.erb +89 -0
- data/ext/apache2/ConfigurationSetters.cpp +223 -0
- data/ext/apache2/ConfigurationSetters.cpp.erb +126 -0
- data/ext/apache2/CreateDirConfig.cpp +50 -0
- data/ext/apache2/CreateDirConfig.cpp.erb +71 -0
- data/ext/apache2/Hooks.cpp +6 -0
- data/ext/apache2/MergeDirConfig.cpp +103 -0
- data/ext/apache2/MergeDirConfig.cpp.erb +81 -0
- data/ext/common/ApplicationPool2/AppTypes.cpp +2 -0
- data/ext/common/ApplicationPool2/AppTypes.h +2 -0
- data/ext/common/ApplicationPool2/Common.h +1 -1
- data/ext/common/ApplicationPool2/Group.h +56 -7
- data/ext/common/ApplicationPool2/Implementation.cpp +133 -31
- data/ext/common/ApplicationPool2/Options.h +23 -2
- data/ext/common/ApplicationPool2/Pool.h +8 -1
- data/ext/common/ApplicationPool2/Process.h +9 -0
- data/ext/common/ApplicationPool2/Session.h +1 -0
- data/ext/common/ApplicationPool2/Spawner.h +21 -19
- data/ext/common/ApplicationPool2/SuperGroup.h +1 -1
- data/ext/common/Constants.h +21 -17
- data/ext/common/Constants.h.erb +1 -1
- data/ext/common/Exceptions.h +19 -0
- data/ext/common/ServerInstanceDir.h +8 -4
- data/ext/common/Utils.cpp +33 -1
- data/ext/common/Utils.h +14 -0
- data/ext/common/Utils/StrIntUtils.cpp +16 -0
- data/ext/common/Utils/StrIntUtils.h +5 -0
- data/ext/common/agents/HelperAgent/Main.cpp +5 -5
- data/ext/common/agents/HelperAgent/RequestHandler.h +94 -45
- data/ext/common/agents/LoggingAgent/Main.cpp +10 -26
- data/ext/common/agents/Watchdog/Main.cpp +4 -15
- data/ext/nginx/CacheLocationConfig.c +501 -0
- data/ext/nginx/CacheLocationConfig.c.erb +140 -0
- data/ext/nginx/Configuration.c +29 -453
- data/ext/nginx/Configuration.h +3 -21
- data/ext/nginx/ConfigurationCommands.c +501 -0
- data/ext/nginx/ConfigurationCommands.c.erb +136 -0
- data/ext/nginx/ConfigurationFields.h +89 -0
- data/ext/nginx/ConfigurationFields.h.erb +85 -0
- data/ext/nginx/ContentHandler.c +3 -166
- data/ext/nginx/CreateLocationConfig.c +146 -0
- data/ext/nginx/CreateLocationConfig.c.erb +70 -0
- data/ext/nginx/MergeLocationConfig.c +166 -0
- data/ext/nginx/MergeLocationConfig.c.erb +72 -0
- data/ext/nginx/config +4 -0
- data/ext/oxt/detail/tracable_exception_disabled.hpp +21 -1
- data/ext/oxt/detail/tracable_exception_enabled.hpp +4 -1
- data/ext/oxt/implementation.cpp +7 -1
- data/ext/oxt/macros.hpp +9 -7
- data/helper-scripts/backtrace-sanitizer.rb +23 -0
- data/helper-scripts/classic-rails-loader.rb +23 -0
- data/helper-scripts/classic-rails-preloader.rb +23 -0
- data/helper-scripts/download_binaries/extconf.rb +10 -5
- data/helper-scripts/meteor-loader.rb +127 -0
- data/helper-scripts/node-loader.js +1 -1
- data/helper-scripts/rack-preloader.rb +23 -0
- data/helper-scripts/system-memory-stats.py +22 -0
- data/helper-scripts/touch-dir.sh +48 -0
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/apache2/config_options.rb +104 -0
- data/lib/phusion_passenger/constants.rb +8 -0
- data/lib/phusion_passenger/native_support.rb +9 -1
- data/lib/phusion_passenger/nginx/config_options.rb +328 -0
- data/lib/phusion_passenger/packaging.rb +2 -2
- data/lib/phusion_passenger/platform_info/apache.rb +8 -0
- data/lib/phusion_passenger/platform_info/compiler.rb +2 -2
- data/lib/phusion_passenger/rails3_extensions/init.rb +19 -4
- data/lib/phusion_passenger/ruby_core_enhancements.rb +4 -1
- data/lib/phusion_passenger/standalone/app_finder.rb +3 -2
- data/lib/phusion_passenger/standalone/command.rb +1 -0
- data/lib/phusion_passenger/standalone/runtime_installer.rb +1 -6
- data/lib/phusion_passenger/standalone/runtime_locator.rb +9 -2
- data/lib/phusion_passenger/standalone/start_command.rb +45 -9
- data/lib/phusion_passenger/utils.rb +4 -1
- data/resources/templates/{nginx → installer_common}/run_installer_as_root.txt.erb +3 -1
- data/resources/templates/nginx/nginx_module_sources_not_available.txt.erb +6 -0
- data/resources/templates/standalone/config.erb +8 -8
- data/test/cxx/ApplicationPool2/PoolTest.cpp +120 -3
- data/test/cxx/RequestHandlerTest.cpp +66 -3
- data/test/integration_tests/native_packaging_spec.rb +41 -0
- data/test/integration_tests/nginx_tests.rb +1 -0
- data/test/integration_tests/standalone_tests.rb +4 -0
- data/test/ruby/shared/rails/analytics_logging_extensions_sharedspec.rb +22 -0
- data/test/stub/rails3.0/config/initializers/passenger.rb +2 -1
- data/test/stub/rails3.1/config/initializers/passenger.rb +2 -1
- data/test/stub/rails3.2/config/initializers/passenger.rb +2 -1
- data/test/stub/rails4.0/config/initializers/passenger.rb +5 -1
- data/test/stub/wsgi/passenger_wsgi.py +5 -0
- metadata +32 -7
- metadata.gz.asc +7 -7
- data/resources/templates/apache2/run_installer_as_root.txt.erb +0 -8
@@ -76,8 +76,8 @@ module Packaging
|
|
76
76
|
'rpm/**/*',
|
77
77
|
'helper-scripts/**/*',
|
78
78
|
'ext/common/**/*.{cpp,c,h,hpp,md,erb}',
|
79
|
-
'ext/apache2/*.{cpp,h,hpp,c}',
|
80
|
-
'ext/nginx/*.{c,cpp,h}',
|
79
|
+
'ext/apache2/*.{cpp,h,hpp,c,erb}',
|
80
|
+
'ext/nginx/*.{c,cpp,h,erb}',
|
81
81
|
'ext/nginx/config',
|
82
82
|
'ext/boost/**/*',
|
83
83
|
'ext/libev/{LICENSE,Changes,README,Makefile.am,Makefile.in}',
|
@@ -182,6 +182,14 @@ module PlatformInfo
|
|
182
182
|
if filename.include?("${")
|
183
183
|
# We couldn't substitute everything.
|
184
184
|
return nil
|
185
|
+
end
|
186
|
+
if filename !~ /\A\//
|
187
|
+
# Not an absolute path. Infer from root.
|
188
|
+
if root = httpd_root(options)
|
189
|
+
return "#{root}/#{filename}"
|
190
|
+
else
|
191
|
+
return nil
|
192
|
+
end
|
185
193
|
else
|
186
194
|
return filename
|
187
195
|
end
|
@@ -75,12 +75,12 @@ private
|
|
75
75
|
output = `#{command} 2>&1`
|
76
76
|
result = $?.exitstatus == 0
|
77
77
|
rescue SystemCallError => e
|
78
|
-
result =
|
78
|
+
result = nil
|
79
79
|
exec_error_reason = e.message
|
80
80
|
end
|
81
81
|
log("Output:\n" <<
|
82
82
|
"-------------------------\n" <<
|
83
|
-
output <<
|
83
|
+
output.to_s <<
|
84
84
|
"\n-------------------------")
|
85
85
|
elsif verbose?
|
86
86
|
result = system(command)
|
@@ -27,8 +27,8 @@ require 'digest/md5'
|
|
27
27
|
module PhusionPassenger
|
28
28
|
|
29
29
|
module Rails3Extensions
|
30
|
-
def self.init!(options)
|
31
|
-
if !AnalyticsLogging.install!(options)
|
30
|
+
def self.init!(options, user_options = {})
|
31
|
+
if !AnalyticsLogging.install!(options, user_options)
|
32
32
|
# Remove code to save memory.
|
33
33
|
PhusionPassenger::Rails3Extensions.send(:remove_const, :AnalyticsLogging)
|
34
34
|
PhusionPassenger.send(:remove_const, :Rails3Extensions)
|
@@ -38,7 +38,7 @@ end
|
|
38
38
|
|
39
39
|
module Rails3Extensions
|
40
40
|
class AnalyticsLogging < ActiveSupport::LogSubscriber
|
41
|
-
def self.install!(options)
|
41
|
+
def self.install!(options, user_options)
|
42
42
|
analytics_logger = options["analytics_logger"]
|
43
43
|
app_group_name = options["app_group_name"]
|
44
44
|
return false if !analytics_logger || !options["analytics"]
|
@@ -47,7 +47,7 @@ class AnalyticsLogging < ActiveSupport::LogSubscriber
|
|
47
47
|
# so that the info can be logged.
|
48
48
|
GC.enable_stats if GC.respond_to?(:enable_stats)
|
49
49
|
|
50
|
-
subscriber = self.new
|
50
|
+
subscriber = self.new(user_options)
|
51
51
|
AnalyticsLogging.attach_to(:action_controller, subscriber)
|
52
52
|
AnalyticsLogging.attach_to(:active_record, subscriber)
|
53
53
|
if defined?(ActiveSupport::Cache::Store)
|
@@ -87,6 +87,10 @@ class AnalyticsLogging < ActiveSupport::LogSubscriber
|
|
87
87
|
|
88
88
|
return true
|
89
89
|
end
|
90
|
+
|
91
|
+
def initialize(options)
|
92
|
+
install_event_preprocessor(options[:event_preprocessor]) if options[:event_preprocessor]
|
93
|
+
end
|
90
94
|
|
91
95
|
def process_action(event)
|
92
96
|
log = Thread.current[PASSENGER_ANALYTICS_WEB_LOG]
|
@@ -215,6 +219,17 @@ class AnalyticsLogging < ActiveSupport::LogSubscriber
|
|
215
219
|
end
|
216
220
|
end
|
217
221
|
end
|
222
|
+
|
223
|
+
private
|
224
|
+
def install_event_preprocessor(event_preprocessor)
|
225
|
+
public_methods(false).each do |name|
|
226
|
+
singleton = class << self; self end
|
227
|
+
singleton.send(:define_method, name, lambda do |event|
|
228
|
+
event_preprocessor.call(event)
|
229
|
+
super(event)
|
230
|
+
end)
|
231
|
+
end
|
232
|
+
end
|
218
233
|
end # class AnalyticsLogging
|
219
234
|
end # module Rails3Extensions
|
220
235
|
|
@@ -22,7 +22,10 @@
|
|
22
22
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
23
|
# THE SOFTWARE.
|
24
24
|
|
25
|
-
|
25
|
+
begin
|
26
|
+
require 'rubygems'
|
27
|
+
rescue LoadError
|
28
|
+
end
|
26
29
|
require 'socket'
|
27
30
|
require 'thread'
|
28
31
|
if (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby") && RUBY_VERSION < "1.8.7"
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
-
# Copyright (c) 2010 Phusion
|
2
|
+
# Copyright (c) 2010-2013 Phusion
|
3
3
|
#
|
4
4
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
5
5
|
#
|
@@ -33,7 +33,8 @@ class AppFinder
|
|
33
33
|
def self.looks_like_app_directory?(dir)
|
34
34
|
return File.exist?("#{dir}/config.ru") ||
|
35
35
|
File.exist?("#{dir}/config/environment.rb") ||
|
36
|
-
File.exist?("#{dir}/passenger_wsgi.py")
|
36
|
+
File.exist?("#{dir}/passenger_wsgi.py") ||
|
37
|
+
File.exist?("#{dir}/passenger_node.js")
|
37
38
|
end
|
38
39
|
|
39
40
|
def initialize(dirs, options = {})
|
@@ -241,6 +241,7 @@ private
|
|
241
241
|
def create_nginx_controller(extra_options = {})
|
242
242
|
require_daemon_controller
|
243
243
|
require 'socket' unless defined?(UNIXSocket)
|
244
|
+
require 'thread' unless defined?(Mutex)
|
244
245
|
if @options[:socket_file]
|
245
246
|
ping_spec = [:unix, @options[:socket_file]]
|
246
247
|
else
|
@@ -572,12 +572,7 @@ private
|
|
572
572
|
# work around the problem by configure Nginx with prefix
|
573
573
|
# /tmp.
|
574
574
|
command << "#{shell} ./configure --prefix=/tmp " <<
|
575
|
-
"
|
576
|
-
"--without-http_fastcgi_module " <<
|
577
|
-
"--without-http_scgi_module " <<
|
578
|
-
"--without-http_uwsgi_module " <<
|
579
|
-
"--with-http_gzip_static_module " <<
|
580
|
-
"--with-http_stub_status_module " <<
|
575
|
+
"#{STANDALONE_NGINX_CONFIGURE_OPTIONS} " <<
|
581
576
|
"'--add-module=#{PhusionPassenger.nginx_module_source_dir}'"
|
582
577
|
run_command_with_throbber(command, "Preparing Nginx...") do |status_text|
|
583
578
|
yield(0, 1, status_text)
|
@@ -138,8 +138,15 @@ class RuntimeLocator
|
|
138
138
|
|
139
139
|
private
|
140
140
|
def default_runtime_dir
|
141
|
-
|
142
|
-
|
141
|
+
if Process.uid == 0
|
142
|
+
# It is important that the default runtime dir for the root user
|
143
|
+
# is a publicly accessible directory, because when --user is given,
|
144
|
+
# the agents are run as non-root users.
|
145
|
+
return "/var/lib/#{GLOBAL_NAMESPACE_DIRNAME}/standalone"
|
146
|
+
else
|
147
|
+
home = Etc.getpwuid.dir
|
148
|
+
return "#{home}/#{USER_NAMESPACE_DIRNAME}/standalone"
|
149
|
+
end
|
143
150
|
end
|
144
151
|
|
145
152
|
def debugging?
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
-
# Copyright (c) 2010-
|
2
|
+
# Copyright (c) 2010-2013 Phusion
|
3
3
|
#
|
4
4
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
5
5
|
#
|
@@ -83,7 +83,7 @@ class StartCommand < Command
|
|
83
83
|
########################
|
84
84
|
touch_temp_dir_in_background
|
85
85
|
watch_log_files_in_background if should_watch_logs?
|
86
|
-
wait_until_nginx_has_exited
|
86
|
+
wait_until_nginx_has_exited if should_wait_until_nginx_has_exited?
|
87
87
|
rescue Interrupt
|
88
88
|
stop_threads
|
89
89
|
stop_nginx
|
@@ -101,6 +101,7 @@ class StartCommand < Command
|
|
101
101
|
stop_nginx
|
102
102
|
raise
|
103
103
|
ensure
|
104
|
+
stop_touching_temp_dir_in_background if should_wait_until_nginx_has_exited?
|
104
105
|
stop_threads
|
105
106
|
end
|
106
107
|
ensure
|
@@ -166,6 +167,18 @@ private
|
|
166
167
|
wrap_desc("Disable passenger_friendly_error_pages")) do
|
167
168
|
@options[:friendly_error_pages] = false
|
168
169
|
end
|
170
|
+
opts.on("--ssl",
|
171
|
+
wrap_desc("Enable SSL support")) do
|
172
|
+
@options[:ssl] = true
|
173
|
+
end
|
174
|
+
opts.on("--ssl-certificate PATH", String,
|
175
|
+
wrap_desc("Specify the SSL certificate path")) do |val|
|
176
|
+
@options[:ssl_certificate] = File.expand_path(val)
|
177
|
+
end
|
178
|
+
opts.on("--ssl-certificate-key PATH", String,
|
179
|
+
wrap_desc("Specify the SSL key path")) do |val|
|
180
|
+
@options[:ssl_certificate_key] = File.expand_path(val)
|
181
|
+
end
|
169
182
|
opts.on("--union-station-gateway HOST:PORT", String,
|
170
183
|
wrap_desc("Specify Union Station Gateway host and port")) do |value|
|
171
184
|
host, port = value.split(":", 2)
|
@@ -248,6 +261,14 @@ private
|
|
248
261
|
error "You cannot specify both --address/--port and --socket. Please choose either one."
|
249
262
|
exit 1
|
250
263
|
end
|
264
|
+
if @options[:ssl] && !@options[:ssl_certificate]
|
265
|
+
error "You specified --ssl. Please specify --ssl-certificate as well."
|
266
|
+
exit 1
|
267
|
+
end
|
268
|
+
if @options[:ssl] && !@options[:ssl_certificate_key]
|
269
|
+
error "You specified --ssl. Please specify --ssl-certificate-key as well."
|
270
|
+
exit 1
|
271
|
+
end
|
251
272
|
check_port_bind_permission_and_display_sudo_suggestion
|
252
273
|
check_port_availability
|
253
274
|
end
|
@@ -361,12 +382,21 @@ private
|
|
361
382
|
return !@options[:daemonize] && @options[:log_file] != "/dev/null"
|
362
383
|
end
|
363
384
|
|
385
|
+
def should_wait_until_nginx_has_exited?
|
386
|
+
return !@options[:daemonize]
|
387
|
+
end
|
388
|
+
|
364
389
|
# Returns the URL that Nginx will be listening on.
|
365
390
|
def listen_url
|
366
391
|
if @options[:socket_file]
|
367
392
|
return @options[:socket_file]
|
368
393
|
else
|
369
|
-
|
394
|
+
if @options[:ssl]
|
395
|
+
scheme = "https"
|
396
|
+
else
|
397
|
+
scheme = "http"
|
398
|
+
end
|
399
|
+
result = "#{scheme}://#{@options[:address]}"
|
370
400
|
if @options[:port] != 80
|
371
401
|
result << ":#{@options[:port]}"
|
372
402
|
end
|
@@ -524,13 +554,19 @@ private
|
|
524
554
|
end
|
525
555
|
|
526
556
|
def touch_temp_dir_in_background
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
557
|
+
require 'shellwords'
|
558
|
+
script = Shellwords.escape("#{PhusionPassenger.helper_scripts_dir}/touch-dir.sh")
|
559
|
+
dir = Shellwords.escape(@temp_dir)
|
560
|
+
@toucher = IO.popen("sh #{script} #{dir}", "r")
|
561
|
+
end
|
562
|
+
|
563
|
+
def stop_touching_temp_dir_in_background
|
564
|
+
if @toucher
|
565
|
+
begin
|
566
|
+
Process.kill('TERM', @toucher.pid)
|
567
|
+
rescue Errno::ESRCH, Errno::ECHILD
|
533
568
|
end
|
569
|
+
@toucher.close
|
534
570
|
end
|
535
571
|
end
|
536
572
|
|
@@ -22,7 +22,10 @@
|
|
22
22
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
23
|
# THE SOFTWARE.
|
24
24
|
|
25
|
-
|
25
|
+
begin
|
26
|
+
require 'rubygems'
|
27
|
+
rescue LoadError
|
28
|
+
end
|
26
29
|
require 'phusion_passenger/native_support'
|
27
30
|
|
28
31
|
module PhusionPassenger
|
@@ -5,4 +5,6 @@ This installer must be able to write to the following directory:
|
|
5
5
|
<b><%= @dir %></b>
|
6
6
|
|
7
7
|
But it can't do that, because you're running the installer as <b><%= `whoami`.strip %></b>.
|
8
|
-
Please re-run this installer
|
8
|
+
Please re-run this installer using <%= @sudo %>:
|
9
|
+
|
10
|
+
<b><%= @sudo_e %> <%= @ruby %> <%= @installer %></b>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<red>Nginx module sources not available</red>
|
2
|
+
|
3
|
+
You didn't install the Phusion Passenger Nginx module sources. If you're on
|
4
|
+
Debian or Ubuntu, please run <b>sudo apt-get install ruby-passenger-dev</b>
|
5
|
+
first. If you're not on Debian/Ubuntu, or if you cannot run apt-get, please
|
6
|
+
install Phusion Passenger from source: https://www.phusionpassenger.com/
|
@@ -10,13 +10,6 @@ worker_processes 1;
|
|
10
10
|
daemon on;
|
11
11
|
error_log '<%= @options[:log_file] %>' <% if debugging? %>info<% end %>;
|
12
12
|
pid '<%= @options[:pid_file] %>';
|
13
|
-
<% if Process.euid == 0 %>
|
14
|
-
<% if @options[:user] %>
|
15
|
-
user <%= @options[:user] %> <%= default_group_for(@options[:user]) %>;
|
16
|
-
<% else %>
|
17
|
-
user <%= current_user %> <%= default_group_for(current_user) %>;
|
18
|
-
<% end %>
|
19
|
-
<% end %>
|
20
13
|
|
21
14
|
events {
|
22
15
|
worker_connections 1024;
|
@@ -34,9 +27,11 @@ http {
|
|
34
27
|
<% if @options[:user] %>
|
35
28
|
passenger_user <%= @options[:user] %>;
|
36
29
|
passenger_default_user <%= @options[:user] %>;
|
30
|
+
passenger_analytics_log_user <%= @options[:user] %>;
|
37
31
|
<% else %>
|
38
32
|
passenger_user <%= current_user %>;
|
39
33
|
passenger_default_user <%= current_user %>;
|
34
|
+
passenger_analytics_log_user <%= current_user %>;
|
40
35
|
<% end %>
|
41
36
|
<% if debugging? %>passenger_log_level 2;<% end %>
|
42
37
|
<% if @options[:rolling_restarts] %>passenger_rolling_restarts on;<% end %>
|
@@ -79,7 +74,7 @@ http {
|
|
79
74
|
|
80
75
|
<% for app in @apps %>
|
81
76
|
server {
|
82
|
-
listen <%= nginx_listen_address(app) %>;
|
77
|
+
listen <%= nginx_listen_address(app) %> <%= "ssl" if app[:ssl] %>;
|
83
78
|
server_name <%= app[:server_names].join(' ') %>;
|
84
79
|
root '<%= app[:root] %>/public';
|
85
80
|
passenger_app_root '<%= app[:root] %>';
|
@@ -91,6 +86,11 @@ http {
|
|
91
86
|
union_station_support on;
|
92
87
|
union_station_key <%= app[:union_station_key] %>;
|
93
88
|
<% end %>
|
89
|
+
<% if app[:ssl] %>
|
90
|
+
ssl on;
|
91
|
+
ssl_certificate <%= app[:ssl_certificate] %>;
|
92
|
+
ssl_certificate_key <%= app[:ssl_certificate_key] %>;
|
93
|
+
<% end %>
|
94
94
|
|
95
95
|
# Rails asset pipeline support.
|
96
96
|
location ~ ^/assets/ {
|
@@ -961,7 +961,8 @@ namespace tut {
|
|
961
961
|
}
|
962
962
|
|
963
963
|
TEST_METHOD(41) {
|
964
|
-
// Disabling the sole process in a group
|
964
|
+
// Disabling the sole process in a group, in case the pool settings allow
|
965
|
+
// spawning another process, should trigger a new process spawn.
|
965
966
|
ensureMinProcesses(1);
|
966
967
|
Options options = createOptions();
|
967
968
|
SessionPtr session = pool->get(options, &ticket);
|
@@ -987,6 +988,20 @@ namespace tut {
|
|
987
988
|
}
|
988
989
|
|
989
990
|
TEST_METHOD(42) {
|
991
|
+
// Disabling the sole process in a group, in case pool settings don't allow
|
992
|
+
// spawning another process, should fail.
|
993
|
+
pool->setMax(1);
|
994
|
+
ensureMinProcesses(1);
|
995
|
+
|
996
|
+
vector<ProcessPtr> processes = pool->getProcesses();
|
997
|
+
ensure_equals("(1)", processes.size(), 1u);
|
998
|
+
|
999
|
+
DisableResult result = pool->disableProcess(processes[0]->gupid);
|
1000
|
+
ensure_equals("(2)", result, DR_ERROR);
|
1001
|
+
ensure_equals("(3)", pool->getProcessCount(), 1u);
|
1002
|
+
}
|
1003
|
+
|
1004
|
+
TEST_METHOD(43) {
|
990
1005
|
// If there are no enabled processes in the group, then disabling should
|
991
1006
|
// succeed after the new process has been spawned.
|
992
1007
|
initPoolDebugging();
|
@@ -1031,7 +1046,7 @@ namespace tut {
|
|
1031
1046
|
}
|
1032
1047
|
}
|
1033
1048
|
|
1034
|
-
TEST_METHOD(
|
1049
|
+
TEST_METHOD(44) {
|
1035
1050
|
// Suppose that a previous disable command triggered a new process spawn,
|
1036
1051
|
// and the spawn fails. Then any disabling processes should become enabled
|
1037
1052
|
// again, and the callbacks for the previous disable commands should be called.
|
@@ -1116,6 +1131,27 @@ namespace tut {
|
|
1116
1131
|
// TODO: Enabling a process that's disabling succeeds immediately. The disable
|
1117
1132
|
// callbacks will be called with DR_CANCELED.
|
1118
1133
|
|
1134
|
+
TEST_METHOD(51) {
|
1135
|
+
// If the number of processes is already at maximum, then disabling
|
1136
|
+
// a process will cause that process to be disabled, without spawning
|
1137
|
+
// a new process.
|
1138
|
+
pool->setMax(2);
|
1139
|
+
ensureMinProcesses(2);
|
1140
|
+
|
1141
|
+
vector<ProcessPtr> processes = pool->getProcesses();
|
1142
|
+
ensure_equals(processes.size(), 2u);
|
1143
|
+
DisableResult result = pool->disableProcess(processes[0]->gupid);
|
1144
|
+
ensure_equals(result, DR_SUCCESS);
|
1145
|
+
|
1146
|
+
{
|
1147
|
+
ScopedLock l(pool->syncher);
|
1148
|
+
GroupPtr group = processes[0]->getGroup();
|
1149
|
+
ensure_equals(group->enabledCount, 1);
|
1150
|
+
ensure_equals(group->disablingCount, 0);
|
1151
|
+
ensure_equals(group->disabledCount, 1);
|
1152
|
+
}
|
1153
|
+
}
|
1154
|
+
|
1119
1155
|
|
1120
1156
|
/*********** Other tests ***********/
|
1121
1157
|
|
@@ -1587,6 +1623,87 @@ namespace tut {
|
|
1587
1623
|
}
|
1588
1624
|
}
|
1589
1625
|
|
1626
|
+
TEST_METHOD(76) {
|
1627
|
+
// No more than maxOutOfBandWorkInstances process will be performing
|
1628
|
+
// out-of-band work at the same time.
|
1629
|
+
TempDirCopy dir("stub/wsgi", "tmp.wsgi");
|
1630
|
+
Options options = createOptions();
|
1631
|
+
options.appRoot = "tmp.wsgi";
|
1632
|
+
options.appType = "wsgi";
|
1633
|
+
options.spawnMethod = "direct";
|
1634
|
+
options.maxOutOfBandWorkInstances = 2;
|
1635
|
+
initPoolDebugging();
|
1636
|
+
debug->restarting = false;
|
1637
|
+
debug->spawning = false;
|
1638
|
+
debug->oobw = true;
|
1639
|
+
|
1640
|
+
// Spawn 3 processes and initiate 2 OOBW requests.
|
1641
|
+
SessionPtr session1 = pool->get(options, &ticket);
|
1642
|
+
SessionPtr session2 = pool->get(options, &ticket);
|
1643
|
+
SessionPtr session3 = pool->get(options, &ticket);
|
1644
|
+
session1->requestOOBW();
|
1645
|
+
session1.reset();
|
1646
|
+
session2->requestOOBW();
|
1647
|
+
session2.reset();
|
1648
|
+
|
1649
|
+
// 2 OOBW requests eventually start.
|
1650
|
+
debug->debugger->recv("OOBW request about to start");
|
1651
|
+
debug->debugger->recv("OOBW request about to start");
|
1652
|
+
|
1653
|
+
// Request another OOBW, but this one is not initiated.
|
1654
|
+
session3->requestOOBW();
|
1655
|
+
session3.reset();
|
1656
|
+
SHOULD_NEVER_HAPPEN(100,
|
1657
|
+
result = debug->debugger->peek("OOBW request about to start") != NULL;
|
1658
|
+
);
|
1659
|
+
|
1660
|
+
// Let one OOBW request finish. The third one should eventually
|
1661
|
+
// start.
|
1662
|
+
debug->messages->send("Proceed with OOBW request");
|
1663
|
+
debug->debugger->recv("OOBW request about to start");
|
1664
|
+
|
1665
|
+
debug->messages->send("Proceed with OOBW request");
|
1666
|
+
debug->messages->send("Proceed with OOBW request");
|
1667
|
+
debug->debugger->recv("OOBW request finished");
|
1668
|
+
debug->debugger->recv("OOBW request finished");
|
1669
|
+
debug->debugger->recv("OOBW request finished");
|
1670
|
+
}
|
1671
|
+
|
1672
|
+
TEST_METHOD(77) {
|
1673
|
+
// If the getWaitlist already has maxRequestQueueSize items,
|
1674
|
+
// then an exception is returned.
|
1675
|
+
Options options = createOptions();
|
1676
|
+
options.appGroupName = "test1";
|
1677
|
+
options.maxRequestQueueSize = 3;
|
1678
|
+
GroupPtr group = pool->findOrCreateGroup(options);
|
1679
|
+
spawnerConfig->concurrency = 3;
|
1680
|
+
initPoolDebugging();
|
1681
|
+
pool->setMax(1);
|
1682
|
+
|
1683
|
+
for (int i = 0; i < 3; i++) {
|
1684
|
+
pool->asyncGet(options, callback);
|
1685
|
+
}
|
1686
|
+
ensure_equals(number, 0);
|
1687
|
+
{
|
1688
|
+
LockGuard l(pool->syncher);
|
1689
|
+
ensure_equals(group->getWaitlist.size(),
|
1690
|
+
3u);
|
1691
|
+
}
|
1692
|
+
|
1693
|
+
try {
|
1694
|
+
pool->get(options, &ticket);
|
1695
|
+
fail("Expected RequestQueueFullException");
|
1696
|
+
} catch (const RequestQueueFullException &e) {
|
1697
|
+
// OK
|
1698
|
+
}
|
1699
|
+
|
1700
|
+
debug->messages->send("Proceed with spawn loop iteration 1");
|
1701
|
+
debug->messages->send("Spawn loop done");
|
1702
|
+
EVENTUALLY(5,
|
1703
|
+
result = number == 3;
|
1704
|
+
);
|
1705
|
+
}
|
1706
|
+
|
1590
1707
|
// TODO: Persistent connections.
|
1591
1708
|
// TODO: If one closes the session before it has reached EOF, and process's maximum concurrency
|
1592
1709
|
// has already been reached, then the pool should ping the process so that it can detect
|
@@ -1595,7 +1712,7 @@ namespace tut {
|
|
1595
1712
|
|
1596
1713
|
/*********** Test previously discovered bugs ***********/
|
1597
1714
|
|
1598
|
-
TEST_METHOD(
|
1715
|
+
TEST_METHOD(79) {
|
1599
1716
|
// Test detaching, then restarting. This should not violate any invariants.
|
1600
1717
|
TempDirCopy dir("stub/wsgi", "tmp.wsgi");
|
1601
1718
|
Options options = createOptions();
|