passenger 5.0.0.beta3 → 5.0.0.rc1
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.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +11 -5
- data/CHANGELOG +38 -0
- data/CONTRIBUTING.md +1 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/Rakefile +33 -33
- data/bin/passenger +1 -1
- data/bin/passenger-config +1 -1
- data/bin/passenger-install-apache2-module +800 -800
- data/bin/passenger-install-nginx-module +592 -592
- data/bin/passenger-memory-stats +127 -127
- data/bin/passenger-status +216 -216
- data/build/agents.rb +127 -127
- data/build/apache2.rb +87 -87
- data/build/basics.rb +60 -60
- data/build/common_library.rb +165 -165
- data/build/cplusplus_support.rb +51 -51
- data/build/cxx_tests.rb +268 -268
- data/build/debian.rb +143 -143
- data/build/documentation.rb +58 -58
- data/build/integration_tests.rb +81 -81
- data/build/misc.rb +132 -132
- data/build/nginx.rb +20 -20
- data/build/node_tests.rb +7 -7
- data/build/oxt_tests.rb +14 -14
- data/build/packaging.rb +570 -570
- data/build/preprocessor.rb +260 -260
- data/build/rake_extensions.rb +71 -71
- data/build/ruby_extension.rb +29 -29
- data/build/ruby_tests.rb +6 -6
- data/build/test_basics.rb +37 -37
- data/debian.template/control.template +3 -5
- data/dev/copy_boost_headers +134 -134
- data/dev/install_scripts_bootstrap_code.rb +25 -25
- data/dev/list_tests +20 -20
- data/dev/ruby_server.rb +223 -223
- data/dev/runner +18 -18
- data/doc/ServerOptimizationGuide.txt.md +55 -2
- data/doc/Users guide Nginx.txt +0 -26
- data/doc/Users guide Standalone.txt +5 -1
- data/doc/users_guide_snippets/tips.txt +9 -0
- data/ext/common/ApplicationPool2/Group.h +23 -11
- data/ext/common/ApplicationPool2/Implementation.cpp +32 -7
- data/ext/common/ApplicationPool2/Pool.h +22 -17
- data/ext/common/ApplicationPool2/SmartSpawner.h +4 -1
- data/ext/common/ApplicationPool2/Spawner.h +1 -1
- data/ext/common/Constants.h +1 -1
- data/ext/common/agents/Base.cpp +35 -20
- data/ext/common/agents/HelperAgent/Main.cpp +8 -1
- data/ext/common/agents/HelperAgent/OptionParser.h +18 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +2 -83
- data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +54 -1
- data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +7 -4
- data/ext/common/agents/Main.cpp +1 -1
- data/ext/common/agents/Watchdog/Main.cpp +54 -19
- data/ext/nginx/Configuration.c +7 -0
- data/ext/nginx/ContentHandler.c +9 -1
- data/helper-scripts/backtrace-sanitizer.rb +106 -87
- data/helper-scripts/crash-watch.rb +32 -0
- data/helper-scripts/download_binaries/extconf.rb +38 -38
- data/helper-scripts/meteor-loader.rb +107 -107
- data/helper-scripts/prespawn +101 -101
- data/helper-scripts/rack-loader.rb +96 -96
- data/helper-scripts/rack-preloader.rb +137 -137
- data/lib/phusion_passenger.rb +292 -292
- data/lib/phusion_passenger/abstract_installer.rb +438 -438
- data/lib/phusion_passenger/active_support3_extensions/init.rb +168 -170
- data/lib/phusion_passenger/admin_tools.rb +20 -20
- data/lib/phusion_passenger/admin_tools/instance.rb +178 -178
- data/lib/phusion_passenger/admin_tools/instance_registry.rb +61 -61
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +267 -267
- data/lib/phusion_passenger/apache2/config_options.rb +182 -182
- data/lib/phusion_passenger/common_library.rb +479 -485
- data/lib/phusion_passenger/config/about_command.rb +161 -161
- data/lib/phusion_passenger/config/admin_command_command.rb +129 -129
- data/lib/phusion_passenger/config/agent_compiler.rb +121 -121
- data/lib/phusion_passenger/config/build_native_support_command.rb +43 -43
- data/lib/phusion_passenger/config/command.rb +25 -25
- data/lib/phusion_passenger/config/compile_agent_command.rb +62 -62
- data/lib/phusion_passenger/config/compile_nginx_engine_command.rb +88 -73
- data/lib/phusion_passenger/config/detach_process_command.rb +72 -72
- data/lib/phusion_passenger/config/download_agent_command.rb +246 -227
- data/lib/phusion_passenger/config/download_nginx_engine_command.rb +245 -224
- data/lib/phusion_passenger/config/install_agent_command.rb +144 -132
- data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +205 -185
- data/lib/phusion_passenger/config/installation_utils.rb +204 -204
- data/lib/phusion_passenger/config/list_instances_command.rb +64 -64
- data/lib/phusion_passenger/config/main.rb +152 -152
- data/lib/phusion_passenger/config/nginx_engine_compiler.rb +319 -300
- data/lib/phusion_passenger/config/reopen_logs_command.rb +67 -67
- data/lib/phusion_passenger/config/restart_app_command.rb +155 -155
- data/lib/phusion_passenger/config/system_metrics_command.rb +13 -13
- data/lib/phusion_passenger/config/utils.rb +95 -95
- data/lib/phusion_passenger/config/validate_install_command.rb +198 -198
- data/lib/phusion_passenger/console_text_template.rb +25 -25
- data/lib/phusion_passenger/constants.rb +90 -90
- data/lib/phusion_passenger/debug_logging.rb +106 -106
- data/lib/phusion_passenger/loader_shared_helpers.rb +447 -432
- data/lib/phusion_passenger/message_channel.rb +312 -312
- data/lib/phusion_passenger/message_client.rb +176 -176
- data/lib/phusion_passenger/native_support.rb +369 -369
- data/lib/phusion_passenger/nginx/config_options.rb +297 -297
- data/lib/phusion_passenger/packaging.rb +131 -131
- data/lib/phusion_passenger/platform_info.rb +360 -360
- data/lib/phusion_passenger/platform_info/apache.rb +767 -767
- data/lib/phusion_passenger/platform_info/apache_detector.rb +199 -199
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +107 -107
- data/lib/phusion_passenger/platform_info/compiler.rb +570 -570
- data/lib/phusion_passenger/platform_info/curl.rb +32 -32
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +188 -188
- data/lib/phusion_passenger/platform_info/depcheck.rb +372 -372
- data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +109 -109
- data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
- data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +10 -34
- data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +101 -101
- data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -5
- data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +13 -13
- data/lib/phusion_passenger/platform_info/linux.rb +55 -55
- data/lib/phusion_passenger/platform_info/operating_system.rb +149 -149
- data/lib/phusion_passenger/platform_info/ruby.rb +468 -448
- data/lib/phusion_passenger/platform_info/zlib.rb +9 -9
- data/lib/phusion_passenger/plugin.rb +66 -66
- data/lib/phusion_passenger/preloader_shared_helpers.rb +126 -126
- data/lib/phusion_passenger/public_api.rb +191 -191
- data/lib/phusion_passenger/rack/out_of_band_gc.rb +93 -94
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +231 -227
- data/lib/phusion_passenger/request_handler.rb +567 -577
- data/lib/phusion_passenger/request_handler/thread_handler.rb +379 -381
- data/lib/phusion_passenger/ruby_core_enhancements.rb +86 -86
- data/lib/phusion_passenger/ruby_core_io_enhancements.rb +74 -74
- data/lib/phusion_passenger/simple_benchmarking.rb +25 -25
- data/lib/phusion_passenger/standalone/app_finder.rb +153 -150
- data/lib/phusion_passenger/standalone/command.rb +44 -40
- data/lib/phusion_passenger/standalone/config_utils.rb +53 -53
- data/lib/phusion_passenger/standalone/control_utils.rb +38 -59
- data/lib/phusion_passenger/standalone/main.rb +73 -73
- data/lib/phusion_passenger/standalone/start_command.rb +697 -685
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +193 -155
- data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +162 -133
- data/lib/phusion_passenger/standalone/status_command.rb +64 -64
- data/lib/phusion_passenger/standalone/stop_command.rb +72 -72
- data/lib/phusion_passenger/standalone/version_command.rb +9 -9
- data/lib/phusion_passenger/union_station/connection.rb +32 -32
- data/lib/phusion_passenger/union_station/core.rb +251 -251
- data/lib/phusion_passenger/union_station/transaction.rb +126 -126
- data/lib/phusion_passenger/utils.rb +199 -167
- data/lib/phusion_passenger/utils/ansi_colors.rb +128 -128
- data/lib/phusion_passenger/utils/download.rb +196 -196
- data/lib/phusion_passenger/utils/file_system_watcher.rb +158 -158
- data/lib/phusion_passenger/utils/hosts_file_parser.rb +101 -101
- data/lib/phusion_passenger/utils/lock.rb +31 -31
- data/lib/phusion_passenger/utils/native_support_utils.rb +31 -31
- data/lib/phusion_passenger/utils/progress_bar.rb +26 -26
- data/lib/phusion_passenger/utils/shellwords.rb +20 -20
- data/lib/phusion_passenger/utils/terminal_choice_menu.rb +206 -206
- data/lib/phusion_passenger/utils/unseekable_socket.rb +272 -272
- data/lib/phusion_passenger/vendor/crash_watch/app.rb +129 -0
- data/lib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +341 -0
- data/lib/phusion_passenger/vendor/crash_watch/version.rb +24 -0
- data/lib/phusion_passenger/vendor/daemon_controller.rb +877 -0
- data/lib/phusion_passenger/vendor/daemon_controller/lock_file.rb +127 -0
- data/lib/phusion_passenger/vendor/daemon_controller/spawn.rb +26 -0
- data/lib/phusion_passenger/vendor/daemon_controller/version.rb +29 -0
- data/packaging/rpm/passenger_spec/passenger.spec.template +0 -1
- data/passenger.gemspec +0 -1
- data/resources/templates/config/nginx_engine_compiler/possible_solutions_for_download_and_extraction_problems.txt.erb +27 -0
- data/resources/templates/standalone/config.erb +19 -15
- data/test/integration_tests/apache2_tests.rb +566 -566
- data/test/integration_tests/downloaded_binaries_tests.rb +126 -125
- data/test/integration_tests/native_packaging_spec.rb +296 -296
- data/test/integration_tests/nginx_tests.rb +393 -393
- data/test/integration_tests/shared/example_webapp_tests.rb +282 -280
- data/test/integration_tests/source_packaging_test.rb +138 -138
- data/test/integration_tests/spec_helper.rb +5 -5
- data/test/integration_tests/standalone_tests.rb +367 -367
- data/test/ruby/debug_logging_spec.rb +133 -133
- data/test/ruby/message_channel_spec.rb +186 -186
- data/test/ruby/rack/loader_spec.rb +28 -28
- data/test/ruby/rack/preloader_spec.rb +34 -34
- data/test/ruby/rails3.0/loader_spec.rb +12 -12
- data/test/ruby/rails3.0/preloader_spec.rb +18 -18
- data/test/ruby/rails3.1/loader_spec.rb +12 -12
- data/test/ruby/rails3.1/preloader_spec.rb +18 -18
- data/test/ruby/rails3.2/loader_spec.rb +12 -12
- data/test/ruby/rails3.2/preloader_spec.rb +18 -18
- data/test/ruby/rails4.0/loader_spec.rb +12 -12
- data/test/ruby/rails4.0/preloader_spec.rb +18 -18
- data/test/ruby/rails4.1/loader_spec.rb +12 -12
- data/test/ruby/rails4.1/preloader_spec.rb +18 -18
- data/test/ruby/request_handler_spec.rb +730 -730
- data/test/ruby/shared/loader_sharedspec.rb +224 -224
- data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +327 -327
- data/test/ruby/shared/ruby_loader_sharedspec.rb +47 -47
- data/test/ruby/spec_helper.rb +65 -65
- data/test/ruby/standalone/runtime_installer_spec.rb +384 -384
- data/test/ruby/union_station_spec.rb +276 -276
- data/test/ruby/utils/file_system_watcher_spec.rb +220 -220
- data/test/ruby/utils/hosts_file_parser.rb +248 -248
- data/test/ruby/utils/tee_input_spec.rb +215 -215
- data/test/ruby/utils/unseekable_socket_spec.rb +57 -57
- data/test/ruby/utils_spec.rb +21 -21
- data/test/stub/rack/config.ru +87 -87
- data/test/stub/rack/library.rb +8 -8
- data/test/stub/rack/start.rb +30 -30
- data/test/support/apache2_controller.rb +191 -191
- data/test/support/nginx_controller.rb +90 -99
- data/test/support/placebo-preloader.rb +57 -57
- data/test/support/test_helper.rb +435 -435
- metadata +11 -21
- metadata.gz.asc +7 -7
- data/lib/phusion_passenger/standalone/command2.rb +0 -292
- data/lib/phusion_passenger/standalone/start2_command.rb +0 -799
- data/resources/templates/standalone/download_tool_missing.txt.erb +0 -18
- data/resources/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -17
- data/resources/templates/standalone/run_installer_as_root.txt.erb +0 -8
@@ -0,0 +1,127 @@
|
|
1
|
+
# daemon_controller, library for robust daemon management
|
2
|
+
# Copyright (c) 2010-2015 Phusion
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'fcntl'
|
23
|
+
|
24
|
+
module PhusionPassenger
|
25
|
+
class DaemonController
|
26
|
+
# A lock file is a synchronization mechanism, like a Mutex, but it also allows
|
27
|
+
# inter-process synchronization (as opposed to only inter-thread synchronization
|
28
|
+
# within a single process).
|
29
|
+
#
|
30
|
+
# Processes can obtain either a shared lock or an exclusive lock. It's possible
|
31
|
+
# for multiple processes to obtain a shared lock on a file as long as no
|
32
|
+
# exclusive lock has been obtained by a process. If a process has obtained an
|
33
|
+
# exclusive lock, then no other processes can lock the file, whether they're
|
34
|
+
# trying to obtain a shared lock or an exclusive lock.
|
35
|
+
#
|
36
|
+
# Note that on JRuby, LockFile can only guarantee synchronization between
|
37
|
+
# threads if the different threads use the same LockFile object. Specifying the
|
38
|
+
# same filename is not enough.
|
39
|
+
class LockFile
|
40
|
+
class AlreadyLocked < StandardError
|
41
|
+
end
|
42
|
+
|
43
|
+
# Create a LockFile object. The lock file is initially not locked.
|
44
|
+
#
|
45
|
+
# +filename+ may point to a nonexistant file. In that case, the lock
|
46
|
+
# file will not be created until one's trying to obtain a lock.
|
47
|
+
#
|
48
|
+
# Note that LockFile will use this exact filename. So if +filename+
|
49
|
+
# is a relative filename, then the actual lock file that will be used
|
50
|
+
# depends on the current working directory.
|
51
|
+
def initialize(filename)
|
52
|
+
@filename = filename
|
53
|
+
end
|
54
|
+
|
55
|
+
# Obtain an exclusive lock on the lock file, yield the given block,
|
56
|
+
# then unlock the lockfile. If the lock file was already locked (whether
|
57
|
+
# shared or exclusively) by another process/thread then this method will
|
58
|
+
# block until the lock file has been unlocked.
|
59
|
+
#
|
60
|
+
# The lock file *must* be writable, otherwise an Errno::EACCESS
|
61
|
+
# exception will be raised.
|
62
|
+
def exclusive_lock
|
63
|
+
File.open(@filename, 'w') do |f|
|
64
|
+
if Fcntl.const_defined? :F_SETFD
|
65
|
+
f.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
66
|
+
end
|
67
|
+
f.flock(File::LOCK_EX)
|
68
|
+
yield
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Obtain an exclusive lock on the lock file, yield the given block,
|
73
|
+
# then unlock the lockfile. If the lock file was already exclusively
|
74
|
+
# locked by another process/thread then this method will
|
75
|
+
# block until the exclusive lock has been released. This method will not
|
76
|
+
# block if only shared locks have been obtained.
|
77
|
+
#
|
78
|
+
# The lock file *must* be writable, otherwise an Errno::EACCESS
|
79
|
+
# exception will be raised.
|
80
|
+
def shared_lock
|
81
|
+
File.open(@filename, 'w+') do |f|
|
82
|
+
if Fcntl.const_defined? :F_SETFD
|
83
|
+
f.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
84
|
+
end
|
85
|
+
f.flock(File::LOCK_SH)
|
86
|
+
yield
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Try to obtain a shared lock on the lock file, similar to #shared_lock.
|
91
|
+
# But unlike #shared_lock, this method will raise AlreadyLocked if
|
92
|
+
# no lock can be obtained, instead of blocking.
|
93
|
+
#
|
94
|
+
# If a lock can be obtained, then the given block will be yielded.
|
95
|
+
def try_shared_lock
|
96
|
+
File.open(@filename, 'w+') do |f|
|
97
|
+
if Fcntl.const_defined? :F_SETFD
|
98
|
+
f.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
99
|
+
end
|
100
|
+
if f.flock(File::LOCK_SH | File::LOCK_NB)
|
101
|
+
yield
|
102
|
+
else
|
103
|
+
raise AlreadyLocked
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Try to obtain an exclusive lock on the lock file, similar to #exclusive_lock.
|
109
|
+
# But unlike #exclusive_lock, this method will raise AlreadyLocked if
|
110
|
+
# no lock can be obtained, instead of blocking.
|
111
|
+
#
|
112
|
+
# If a lock can be obtained, then the given block will be yielded.
|
113
|
+
def try_exclusive_lock
|
114
|
+
File.open(@filename, 'w') do |f|
|
115
|
+
if Fcntl.const_defined? :F_SETFD
|
116
|
+
f.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
117
|
+
end
|
118
|
+
if f.flock(File::LOCK_EX | File::LOCK_NB)
|
119
|
+
yield
|
120
|
+
else
|
121
|
+
raise AlreadyLocked
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end # class LockFile
|
126
|
+
end # class DaemonController
|
127
|
+
end # module PhusionPassenger
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# daemon_controller, library for robust daemon management
|
2
|
+
# Copyright (c) 2010 Phusion
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
|
22
|
+
# This helper script is used for daemonizing a command by executing it and
|
23
|
+
# then exiting ourselves. Used on Ruby 1.9 and JRuby because forking may not
|
24
|
+
# be safe/supported on all platforms.
|
25
|
+
Process.setsid
|
26
|
+
Process.spawn(ARGV[0])
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# daemon_controller, library for robust daemon management
|
2
|
+
# Copyright (c) 2010-2015 Phusion
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
|
22
|
+
module PhusionPassenger
|
23
|
+
class DaemonController
|
24
|
+
MAJOR = 1
|
25
|
+
MINOR = 2
|
26
|
+
TINY = 1
|
27
|
+
VERSION_STRING = "#{MAJOR}.#{MINOR}.#{TINY}"
|
28
|
+
end # class DaemonController
|
29
|
+
end # module PhusionPassenger
|
data/passenger.gemspec
CHANGED
@@ -15,7 +15,6 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.email = "software-signing@phusion.nl"
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.add_dependency 'rake', '>= 0.8.1'
|
18
|
-
s.add_dependency 'daemon_controller', '>= 1.2.0'
|
19
18
|
s.add_dependency 'rack'
|
20
19
|
s.files = Dir[*PhusionPassenger::Packaging::GLOB] -
|
21
20
|
Dir[*PhusionPassenger::Packaging::EXCLUDE_GLOB]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<red><b>Unable to download or extract Nginx source tarball</b></red>
|
2
|
+
|
3
|
+
Possible reasons:
|
4
|
+
|
5
|
+
<b>* Your Internet connection is unstable.</b>
|
6
|
+
If this is the case, try re-running this installer with higher connection
|
7
|
+
timeouts:
|
8
|
+
|
9
|
+
passenger-config compile-nginx-engine --connect-timeout 60 --idle-timeout 60
|
10
|
+
|
11
|
+
<b>* You are not connected to the Internet.</b>
|
12
|
+
If this is the case, then please connect to the Internet and try again.
|
13
|
+
|
14
|
+
<b>* The URL that this installer tried to download from no longer exists.</b>
|
15
|
+
Please file a bug report if this is the case:
|
16
|
+
https://github.com/phusion/passenger/issues
|
17
|
+
|
18
|
+
<b>* The download was corrupted.</b>
|
19
|
+
Please try to re-run this installer:
|
20
|
+
|
21
|
+
passenger-config compile-nginx-engine
|
22
|
+
|
23
|
+
<b>* Phusion Passenger Standalone is not able to write to /tmp.</b>
|
24
|
+
Please fix the permissions for this directory, or run this installer with
|
25
|
+
root privileges:
|
26
|
+
|
27
|
+
<%= PlatformInfo.ruby_sudo_command %> passenger-config compile-nginx-engine
|
@@ -73,7 +73,7 @@ http {
|
|
73
73
|
union_station_gateway_port <%= @options[:union_station_gateway_port] %>;
|
74
74
|
union_station_gateway_cert -;
|
75
75
|
<% end %>
|
76
|
-
|
76
|
+
|
77
77
|
<% @options[:ctls].each do |ctl| %>
|
78
78
|
passenger_ctl '<%= ctl.split("=", 2)[0] %>' '<%= ctl.split("=", 2)[1] %>';
|
79
79
|
<% end %>
|
@@ -93,22 +93,22 @@ http {
|
|
93
93
|
application/javascript application/x-javascript application/json \
|
94
94
|
application/rss+xml application/vnd.ms-fontobject application/x-font-ttf \
|
95
95
|
application/xml font/opentype image/svg+xml text/xml;
|
96
|
-
|
97
|
-
<% if @
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
96
|
+
|
97
|
+
<% if @app_finder.multi_mode? %>
|
98
|
+
# Default server entry for mass deployment mode.
|
99
|
+
server {
|
100
|
+
<% if @options[:ssl] %>
|
101
|
+
<% if @options[:ssl_port] %>
|
102
|
+
listen <%= nginx_listen_address %>;
|
103
|
+
listen <%= nginx_listen_address_with_ssl_port %> ssl;
|
104
|
+
<% else %>
|
105
|
+
listen <%= nginx_listen_address %> ssl;
|
106
|
+
<% end %>
|
104
107
|
<% else %>
|
105
|
-
listen <%= nginx_listen_address
|
108
|
+
listen <%= nginx_listen_address %>;
|
106
109
|
<% end %>
|
107
|
-
|
108
|
-
|
109
|
-
<% end %>
|
110
|
-
root '<%= PhusionPassenger.resources_dir %>/standalone_default_root';
|
111
|
-
}
|
110
|
+
root '<%= PhusionPassenger.resources_dir %>/standalone_default_root';
|
111
|
+
}
|
112
112
|
<% end %>
|
113
113
|
|
114
114
|
<% for app in @apps %>
|
@@ -151,6 +151,10 @@ http {
|
|
151
151
|
ssl_certificate_key <%= app[:ssl_certificate_key] %>;
|
152
152
|
<% end %>
|
153
153
|
|
154
|
+
<% @options[:envvars].each_pair do |name, value| %>
|
155
|
+
passenger_env_var '<%= name %>' '<%= value %>';
|
156
|
+
<% end %>
|
157
|
+
|
154
158
|
# Rails asset pipeline support.
|
155
159
|
location ~ "^/assets/.+-[0-9a-f]{32}\..+" {
|
156
160
|
error_page 490 = @static_asset;
|
@@ -16,570 +16,570 @@ require 'integration_tests/shared/example_webapp_tests'
|
|
16
16
|
# TODO: test custom page caching directory
|
17
17
|
|
18
18
|
describe "Apache 2 module" do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
19
|
+
before :all do
|
20
|
+
check_hosts_configuration
|
21
|
+
@passenger_temp_dir = "/tmp/passenger-test.#{$$}"
|
22
|
+
Dir.mkdir(@passenger_temp_dir)
|
23
|
+
FileUtils.chmod_R(0777, @passenger_temp_dir)
|
24
|
+
ENV['TMPDIR'] = @passenger_temp_dir
|
25
|
+
end
|
26
|
+
|
27
|
+
after :all do
|
28
|
+
@apache2.stop if @apache2
|
29
|
+
FileUtils.chmod_R(0777, @passenger_temp_dir)
|
30
|
+
FileUtils.rm_rf(@passenger_temp_dir)
|
31
|
+
end
|
32
|
+
|
33
|
+
before :each do
|
34
|
+
File.open("test.log", "a") do |f|
|
35
|
+
# Make sure that all Apache log output is prepended by the test description
|
36
|
+
# so that we know which messages are associated with which tests.
|
37
|
+
f.puts "\n#### #{Time.now}: #{example.full_description}"
|
38
|
+
@test_log_pos = f.pos
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
after :each do
|
43
|
+
log "End of test"
|
44
|
+
if example.exception
|
45
|
+
puts "\t---------------- Begin logs -------------------"
|
46
|
+
File.open("test.log", "r") do |f|
|
47
|
+
f.seek(@test_log_pos)
|
48
|
+
puts f.read.split("\n").map{ |line| "\t#{line}" }.join("\n")
|
49
|
+
end
|
50
|
+
puts "\t---------------- End logs -------------------"
|
51
|
+
puts "\tThe following test failed. The web server logs are printed above."
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_apache2_controller
|
56
|
+
@apache2 = Apache2Controller.new
|
57
|
+
@apache2.set(:passenger_temp_dir => @passenger_temp_dir)
|
58
|
+
if Process.uid == 0
|
59
|
+
@apache2.set(
|
60
|
+
:www_user => CONFIG['normal_user_1'],
|
61
|
+
:www_group => Etc.getgrgid(Etc.getpwnam(CONFIG['normal_user_1']).gid).name
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def log(message)
|
67
|
+
File.open("test.log", "a") do |f|
|
68
|
+
f.puts "[#{Time.now}] Spec: #{message}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "a Ruby app running on the root URI" do
|
73
|
+
before :all do
|
74
|
+
create_apache2_controller
|
75
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
76
|
+
@stub = RackStub.new('rack')
|
77
|
+
@apache2 << "PassengerMaxPoolSize 1"
|
78
|
+
@apache2.set_vhost("1.passenger.test", "#{@stub.full_app_root}/public")
|
79
|
+
@apache2.start
|
80
|
+
end
|
81
|
+
|
82
|
+
after :all do
|
83
|
+
@stub.destroy
|
84
|
+
@apache2.stop if @apache2
|
85
|
+
end
|
86
|
+
|
87
|
+
before :each do
|
88
|
+
@stub.reset
|
89
|
+
end
|
90
|
+
|
91
|
+
it_should_behave_like "an example web app"
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "a Ruby app running in a sub-URI" do
|
95
|
+
before :all do
|
96
|
+
create_apache2_controller
|
97
|
+
@server = "http://1.passenger.test:#{@apache2.port}/subapp"
|
98
|
+
@stub = RackStub.new('rack')
|
99
|
+
@apache2 << "PassengerMaxPoolSize 1"
|
100
|
+
@apache2.set_vhost("1.passenger.test", File.expand_path("stub")) do |vhost|
|
101
|
+
vhost << %Q{
|
102
|
+
Alias /subapp #{@stub.full_app_root}/public
|
103
|
+
<Location /subapp>
|
104
|
+
PassengerBaseURI /subapp
|
105
|
+
PassengerAppRoot #{@stub.full_app_root}
|
106
|
+
</Location>
|
107
|
+
}
|
108
|
+
end
|
109
|
+
@apache2.start
|
110
|
+
end
|
111
|
+
|
112
|
+
after :all do
|
113
|
+
@stub.destroy
|
114
|
+
@apache2.stop if @apache2
|
115
|
+
end
|
116
|
+
|
117
|
+
before :each do
|
118
|
+
@stub.reset
|
119
|
+
end
|
120
|
+
|
121
|
+
it_should_behave_like "an example web app"
|
122
|
+
|
123
|
+
it "does not interfere with the root website" do
|
124
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
125
|
+
get('/').should == "This is the stub directory."
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "a Python app running on the root URI" do
|
130
|
+
before :all do
|
131
|
+
create_apache2_controller
|
132
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
133
|
+
@stub = PythonStub.new('wsgi')
|
134
|
+
@apache2 << "PassengerMaxPoolSize 1"
|
135
|
+
@apache2.set_vhost("1.passenger.test", "#{@stub.full_app_root}/public")
|
136
|
+
@apache2.start
|
137
|
+
end
|
138
|
+
|
139
|
+
after :all do
|
140
|
+
@stub.destroy
|
141
|
+
@apache2.stop if @apache2
|
142
|
+
end
|
143
|
+
|
144
|
+
before :each do
|
145
|
+
@stub.reset
|
146
|
+
end
|
147
|
+
|
148
|
+
it_should_behave_like "an example web app"
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "a Python app running in a sub-URI" do
|
152
|
+
before :all do
|
153
|
+
create_apache2_controller
|
154
|
+
@server = "http://1.passenger.test:#{@apache2.port}/subapp"
|
155
|
+
@stub = PythonStub.new('wsgi')
|
156
|
+
@apache2 << "PassengerMaxPoolSize 1"
|
157
|
+
@apache2.set_vhost("1.passenger.test", File.expand_path("stub")) do |vhost|
|
158
|
+
vhost << %Q{
|
159
|
+
Alias /subapp #{@stub.full_app_root}/public
|
160
|
+
<Location /subapp>
|
161
|
+
PassengerBaseURI /subapp
|
162
|
+
PassengerAppRoot #{@stub.full_app_root}
|
163
|
+
</Location>
|
164
|
+
}
|
165
|
+
end
|
166
|
+
@apache2.start
|
167
|
+
end
|
168
|
+
|
169
|
+
after :all do
|
170
|
+
@stub.destroy
|
171
|
+
@apache2.stop if @apache2
|
172
|
+
end
|
173
|
+
|
174
|
+
before :each do
|
175
|
+
@stub.reset
|
176
|
+
end
|
177
|
+
|
178
|
+
it_should_behave_like "an example web app"
|
179
|
+
|
180
|
+
it "does not interfere with the root website" do
|
181
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
182
|
+
get('/').should == "This is the stub directory."
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "a Node.js app running on the root URI" do
|
187
|
+
before :all do
|
188
|
+
create_apache2_controller
|
189
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
190
|
+
@stub = NodejsStub.new('node')
|
191
|
+
@apache2 << "PassengerMaxPoolSize 1"
|
192
|
+
@apache2.set_vhost("1.passenger.test", "#{@stub.full_app_root}/public")
|
193
|
+
@apache2.start
|
194
|
+
end
|
195
|
+
|
196
|
+
after :all do
|
197
|
+
@stub.destroy
|
198
|
+
@apache2.stop if @apache2
|
199
|
+
end
|
200
|
+
|
201
|
+
before :each do
|
202
|
+
@stub.reset
|
203
|
+
end
|
204
|
+
|
205
|
+
it_should_behave_like "an example web app"
|
206
|
+
end
|
207
|
+
|
208
|
+
describe "a Node.js app running in a sub-URI" do
|
209
|
+
before :all do
|
210
|
+
create_apache2_controller
|
211
|
+
@server = "http://1.passenger.test:#{@apache2.port}/subapp"
|
212
|
+
@stub = NodejsStub.new('node')
|
213
|
+
@apache2 << "PassengerMaxPoolSize 1"
|
214
|
+
@apache2.set_vhost("1.passenger.test", File.expand_path("stub")) do |vhost|
|
215
|
+
vhost << %Q{
|
216
|
+
Alias /subapp #{@stub.full_app_root}/public
|
217
|
+
<Location /subapp>
|
218
|
+
PassengerBaseURI /subapp
|
219
|
+
PassengerAppRoot #{@stub.full_app_root}
|
220
|
+
</Location>
|
221
|
+
}
|
222
|
+
end
|
223
|
+
@apache2.start
|
224
|
+
end
|
225
|
+
|
226
|
+
after :all do
|
227
|
+
@stub.destroy
|
228
|
+
@apache2.stop if @apache2
|
229
|
+
end
|
230
|
+
|
231
|
+
before :each do
|
232
|
+
@stub.reset
|
233
|
+
end
|
234
|
+
|
235
|
+
it_should_behave_like "an example web app"
|
236
|
+
|
237
|
+
it "does not interfere with the root website" do
|
238
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
239
|
+
get('/').should == "This is the stub directory."
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe "compatibility with other modules" do
|
244
|
+
before :all do
|
245
|
+
create_apache2_controller
|
246
|
+
@apache2 << "PassengerMaxPoolSize 1"
|
247
|
+
@apache2 << "PassengerStatThrottleRate 0"
|
248
|
+
|
249
|
+
@stub = RackStub.new('rack')
|
250
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
251
|
+
@apache2.set_vhost("1.passenger.test", "#{@stub.full_app_root}/public") do |vhost|
|
252
|
+
vhost << "RewriteEngine on"
|
253
|
+
vhost << "RewriteRule ^/rewritten_frontpage$ / [PT,QSA,L]"
|
254
|
+
vhost << "RewriteRule ^/rewritten_env$ /env [PT,QSA,L]"
|
255
|
+
end
|
256
|
+
@apache2.start
|
257
|
+
end
|
258
|
+
|
259
|
+
after :all do
|
260
|
+
@stub.destroy
|
261
|
+
@apache2.stop if @apache2
|
262
|
+
end
|
263
|
+
|
264
|
+
before :each do
|
265
|
+
@stub.reset
|
266
|
+
end
|
267
|
+
|
268
|
+
it "supports environment variable passing through mod_env" do
|
269
|
+
File.write("#{@stub.app_root}/public/.htaccess", 'SetEnv FOO "Foo Bar!"')
|
270
|
+
File.touch("#{@stub.app_root}/tmp/restart.txt", 2) # Activate ENV changes.
|
271
|
+
get('/system_env').should =~ /^FOO = Foo Bar\!$/
|
272
|
+
end
|
273
|
+
|
274
|
+
it "supports mod_rewrite in the virtual host block" do
|
275
|
+
get('/rewritten_frontpage').should == "front page"
|
276
|
+
cgi_envs = get('/rewritten_env?foo=bar+baz')
|
277
|
+
cgi_envs.should include("REQUEST_URI = /env?foo=bar+baz\n")
|
278
|
+
cgi_envs.should include("PATH_INFO = /env\n")
|
279
|
+
end
|
280
|
+
|
281
|
+
it "supports mod_rewrite in .htaccess" do
|
282
|
+
File.write("#{@stub.app_root}/public/.htaccess", %Q{
|
283
|
+
RewriteEngine on
|
284
|
+
RewriteRule ^htaccess_frontpage$ / [PT,QSA,L]
|
285
|
+
RewriteRule ^htaccess_env$ env [PT,QSA,L]
|
286
|
+
})
|
287
|
+
get('/htaccess_frontpage').should == "front page"
|
288
|
+
cgi_envs = get('/htaccess_env?foo=bar+baz')
|
289
|
+
cgi_envs.should include("REQUEST_URI = /env?foo=bar+baz\n")
|
290
|
+
cgi_envs.should include("PATH_INFO = /env\n")
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
describe "configuration options" do
|
295
|
+
before :all do
|
296
|
+
create_apache2_controller
|
297
|
+
@apache2 << "PassengerMaxPoolSize 3"
|
298
|
+
@apache2 << "PassengerStatThrottleRate 0"
|
299
|
+
|
300
|
+
@stub = RackStub.new('rack')
|
301
|
+
@stub_url_root = "http://5.passenger.test:#{@apache2.port}"
|
302
|
+
@apache2.set_vhost('5.passenger.test', "#{@stub.full_app_root}/public") do |vhost|
|
303
|
+
vhost << "PassengerBufferUpload off"
|
304
|
+
vhost << "PassengerFriendlyErrorPages on"
|
305
|
+
vhost << "AllowEncodedSlashes on"
|
306
|
+
end
|
307
|
+
|
308
|
+
@stub2 = RackStub.new('rack')
|
309
|
+
@stub2_url_root = "http://6.passenger.test:#{@apache2.port}"
|
310
|
+
@apache2.set_vhost('6.passenger.test', "#{@stub2.full_app_root}/public") do |vhost|
|
311
|
+
vhost << "PassengerAppEnv development"
|
312
|
+
vhost << "PassengerSpawnMethod conservative"
|
313
|
+
vhost << "PassengerRestartDir #{@stub2.full_app_root}/public"
|
314
|
+
vhost << "AllowEncodedSlashes off"
|
315
|
+
end
|
316
|
+
|
317
|
+
@apache2.start
|
318
|
+
end
|
319
|
+
|
320
|
+
after :all do
|
321
|
+
@stub.destroy
|
322
|
+
@stub2.destroy
|
323
|
+
@apache2.stop if @apache2
|
324
|
+
end
|
325
|
+
|
326
|
+
before :each do
|
327
|
+
@stub.reset
|
328
|
+
@stub2.reset
|
329
|
+
end
|
330
|
+
|
331
|
+
specify "PassengerAppEnv is per-virtual host" do
|
332
|
+
@server = @stub_url_root
|
333
|
+
get('/system_env').should =~ /PASSENGER_APP_ENV = production/
|
334
|
+
|
335
|
+
@server = @stub2_url_root
|
336
|
+
get('/system_env').should =~ /PASSENGER_APP_ENV = development/
|
337
|
+
end
|
338
|
+
|
339
|
+
it "looks for restart.txt in the directory specified by PassengerRestartDir" do
|
340
|
+
@server = @stub2_url_root
|
341
|
+
startup_file = "#{@stub2.app_root}/config.ru"
|
342
|
+
restart_file = "#{@stub2.app_root}/public/restart.txt"
|
343
|
+
|
344
|
+
File.write(startup_file, %Q{
|
345
|
+
require File.expand_path(File.dirname(__FILE__) + "/library")
|
346
|
+
|
347
|
+
app = lambda do |env|
|
348
|
+
case env['PATH_INFO']
|
349
|
+
when '/'
|
350
|
+
text_response("hello world")
|
351
|
+
else
|
352
|
+
[404, { "Content-Type" => "text/plain" }, ["Unknown URI"]]
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
run app
|
357
|
+
})
|
358
|
+
|
359
|
+
now = Time.now
|
360
|
+
File.touch(restart_file, now - 5)
|
361
|
+
get('/').should == "hello world"
|
362
|
+
|
363
|
+
File.write(startup_file, %Q{
|
364
|
+
require File.expand_path(File.dirname(__FILE__) + "/library")
|
365
|
+
|
366
|
+
app = lambda do |env|
|
367
|
+
case env['PATH_INFO']
|
368
|
+
when '/'
|
369
|
+
text_response("oh hai")
|
370
|
+
else
|
371
|
+
[404, { "Content-Type" => "text/plain" }, ["Unknown URI"]]
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
run app
|
376
|
+
})
|
377
|
+
|
378
|
+
File.touch(restart_file, now - 10)
|
379
|
+
get('/').should == "oh hai"
|
380
|
+
end
|
381
|
+
|
382
|
+
describe "PassengerAppRoot" do
|
383
|
+
before :each do
|
384
|
+
@server = @stub_url_root
|
385
|
+
File.write("#{@stub.full_app_root}/public/cached.html", "Static cached.html")
|
386
|
+
File.write("#{@stub.full_app_root}/public/dir.html", "Static dir.html")
|
387
|
+
Dir.mkdir("#{@stub.full_app_root}/public/dir")
|
388
|
+
end
|
389
|
+
|
390
|
+
it "supports page caching on non-index URIs" do
|
391
|
+
get('/cached').should == "Static cached.html"
|
392
|
+
end
|
393
|
+
|
394
|
+
it "supports page caching on directory index URIs" do
|
395
|
+
get('/dir').should == "Static dir.html"
|
396
|
+
end
|
397
|
+
|
398
|
+
it "works" do
|
399
|
+
result = get('/parameters?first=one&second=Green+Bananas')
|
400
|
+
result.should =~ %r{First: one\n}
|
401
|
+
result.should =~ %r{Second: Green Bananas\n}
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
it "resolves symlinks in the document root if PassengerResolveSymlinksInDocumentRoot is set" do
|
406
|
+
orig_app_root = @stub.app_root
|
407
|
+
@stub.move(File.expand_path('tmp.mycook.symlinktest'))
|
408
|
+
FileUtils.mkdir_p(orig_app_root)
|
409
|
+
File.symlink("#{@stub.app_root}/public", "#{orig_app_root}/public")
|
410
|
+
begin
|
411
|
+
File.write("#{@stub.app_root}/public/.htaccess", "PassengerResolveSymlinksInDocumentRoot on")
|
412
|
+
@server = @stub_url_root
|
413
|
+
get('/').should == "front page"
|
414
|
+
ensure
|
415
|
+
FileUtils.rm_rf(orig_app_root)
|
416
|
+
@stub.move(orig_app_root)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
it "supports encoded slashes in the URL if AllowEncodedSlashes is turned on" do
|
421
|
+
@server = @stub_url_root
|
422
|
+
get('/env/foo%2fbar').should =~ %r{PATH_INFO = /env/foo/bar\n}
|
423
|
+
|
424
|
+
@server = @stub2_url_root
|
425
|
+
get('/env/foo%2fbar').should =~ %r{404 Not Found}
|
426
|
+
end
|
427
|
+
|
428
|
+
describe "when handling POST requests with 'chunked' transfer encoding, if PassengerBufferUpload is off" do
|
429
|
+
it "sets Transfer-Encoding to 'chunked' and removes Content-Length" do
|
430
|
+
@uri = URI.parse(@stub_url_root)
|
431
|
+
socket = TCPSocket.new(@uri.host, @uri.port)
|
432
|
+
begin
|
433
|
+
socket.write("POST #{@stub_url_root}/env HTTP/1.1\r\n")
|
434
|
+
socket.write("Host: #{@uri.host}:#{@uri.port}\r\n")
|
435
|
+
socket.write("Transfer-Encoding: chunked\r\n")
|
436
|
+
socket.write("Content-Type: text/plain\r\n")
|
437
|
+
socket.write("Connection: close\r\n")
|
438
|
+
socket.write("\r\n")
|
439
|
+
|
440
|
+
chunk = "foo=bar!"
|
441
|
+
socket.write("%X\r\n%s\r\n" % [chunk.size, chunk])
|
442
|
+
socket.write("0\r\n\r\n")
|
443
|
+
socket.flush
|
444
|
+
|
445
|
+
response = socket.read
|
446
|
+
response.should_not include("CONTENT_LENGTH = ")
|
447
|
+
response.should include("HTTP_TRANSFER_ENCODING = chunked\n")
|
448
|
+
ensure
|
449
|
+
socket.close
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
####################################
|
455
|
+
end
|
456
|
+
|
457
|
+
describe "error handling" do
|
458
|
+
before :all do
|
459
|
+
create_apache2_controller
|
460
|
+
FileUtils.rm_rf('tmp.webdir')
|
461
|
+
FileUtils.mkdir_p('tmp.webdir')
|
462
|
+
@webdir = File.expand_path('tmp.webdir')
|
463
|
+
@apache2.set_vhost('1.passenger.test', @webdir) do |vhost|
|
464
|
+
vhost << "PassengerBaseURI /app-that-crashes-during-startup/public"
|
465
|
+
end
|
466
|
+
|
467
|
+
@stub = RackStub.new('rack')
|
468
|
+
@stub_url_root = "http://2.passenger.test:#{@apache2.port}"
|
469
|
+
@apache2.set_vhost('2.passenger.test', "#{@stub.full_app_root}/public")
|
470
|
+
|
471
|
+
@apache2 << "PassengerFriendlyErrorPages on"
|
472
|
+
@apache2.start
|
473
|
+
end
|
474
|
+
|
475
|
+
after :all do
|
476
|
+
FileUtils.rm_rf('tmp.webdir')
|
477
|
+
@stub.destroy
|
478
|
+
@apache2.stop if @apache2
|
479
|
+
end
|
480
|
+
|
481
|
+
before :each do
|
482
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
483
|
+
@error_page_signature = /<meta name="generator" content="Phusion Passenger">/
|
484
|
+
@stub.reset
|
485
|
+
end
|
486
|
+
|
487
|
+
it "displays an error page if the application crashes during startup" do
|
488
|
+
RackStub.use('rack', "#{@webdir}/app-that-crashes-during-startup") do |stub|
|
489
|
+
File.prepend(stub.startup_file, "raise 'app crash'")
|
490
|
+
result = get("/app-that-crashes-during-startup/public")
|
491
|
+
result.should =~ @error_page_signature
|
492
|
+
result.should =~ /app crash/
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
it "doesn't display a Ruby spawn error page if PassengerFriendlyErrorPages is off" do
|
497
|
+
RackStub.use('rack', "#{@webdir}/app-that-crashes-during-startup") do |stub|
|
498
|
+
File.write("#{stub.app_root}/public/.htaccess", "PassengerFriendlyErrorPages off")
|
499
|
+
File.prepend(stub.startup_file, "raise 'app crash'")
|
500
|
+
result = get("/app-that-crashes-during-startup/public")
|
501
|
+
result.should_not =~ @error_page_signature
|
502
|
+
result.should_not =~ /app crash/
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
describe "HelperAgent" do
|
508
|
+
AdminTools = PhusionPassenger::AdminTools
|
509
|
+
|
510
|
+
before :all do
|
511
|
+
create_apache2_controller
|
512
|
+
@stub = RackStub.new('rack')
|
513
|
+
@stub_url_root = "http://1.passenger.test:#{@apache2.port}"
|
514
|
+
@apache2 << "PassengerStatThrottleRate 0"
|
515
|
+
@apache2.set_vhost('1.passenger.test', "#{@stub.full_app_root}/public")
|
516
|
+
@apache2.start
|
517
|
+
@server = "http://1.passenger.test:#{@apache2.port}"
|
518
|
+
end
|
519
|
+
|
520
|
+
after :all do
|
521
|
+
@stub.destroy
|
522
|
+
@apache2.stop if @apache2
|
523
|
+
end
|
524
|
+
|
525
|
+
before :each do
|
526
|
+
@stub.reset
|
527
|
+
end
|
528
|
+
|
529
|
+
it "is restarted if it crashes" do
|
530
|
+
# Make sure that all Apache worker processes have connected to
|
531
|
+
# the helper agent.
|
532
|
+
10.times do
|
533
|
+
get('/').should == "front page"
|
534
|
+
sleep 0.1
|
535
|
+
end
|
536
|
+
|
537
|
+
# Now kill the helper agent.
|
538
|
+
instance = AdminTools::InstanceRegistry.new.list.first
|
539
|
+
Process.kill('SIGKILL', instance.server_pid)
|
540
|
+
sleep 0.02 # Give the signal a small amount of time to take effect.
|
541
|
+
|
542
|
+
# Each worker process should detect that the old
|
543
|
+
# helper agent has died, and should reconnect.
|
544
|
+
10.times do
|
545
|
+
get('/').should == "front page"
|
546
|
+
sleep 0.1
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
it "exposes the application pool for passenger-status" do
|
551
|
+
File.touch("#{@stub.app_root}/tmp/restart.txt", 1) # Get rid of all previous app processes.
|
552
|
+
get('/').should == "front page"
|
553
|
+
instance = AdminTools::InstanceRegistry.new.list.first
|
554
|
+
|
555
|
+
# Wait until the server has processed the session close event.
|
556
|
+
sleep 0.1
|
557
|
+
|
558
|
+
request = Net::HTTP::Get.new("/pool.xml")
|
559
|
+
request.basic_auth("ro_admin", instance.read_only_admin_password)
|
560
|
+
response = instance.http_request("agents.s/server_admin", request)
|
561
|
+
if response.code.to_i / 100 == 2
|
562
|
+
doc = REXML::Document.new(response.body)
|
563
|
+
else
|
564
|
+
raise response.body
|
565
|
+
end
|
566
|
+
|
567
|
+
groups = doc.get_elements("info/supergroups/supergroup/group")
|
568
|
+
groups.should have(1).item
|
569
|
+
groups.each do |group|
|
570
|
+
group.elements["name"].text.should == "#{@stub.full_app_root} (production)#default"
|
571
|
+
processes = group.get_elements("processes/process")
|
572
|
+
processes.should have(1).item
|
573
|
+
processes[0].elements["processed"].text.should == "1"
|
574
|
+
end
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
##### Helper methods #####
|
579
|
+
|
580
|
+
def start_web_server_if_necessary
|
581
|
+
if !@apache2.running?
|
582
|
+
@apache2.start
|
583
|
+
end
|
584
|
+
end
|
585
585
|
end
|