passenger 1.0.1 → 1.0.2
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/LICENSE +3 -1
- data/Rakefile +17 -12
- data/bin/passenger-config +22 -0
- data/bin/passenger-install-apache2-module +2 -31
- data/bin/passenger-make-enterprisey +66 -0
- data/bin/passenger-memory-stats +192 -0
- data/doc/Users guide.html +150 -66
- data/doc/Users guide.txt +141 -51
- data/doc/cxxapi/ApplicationPoolClientServer_8h-source.html +1 -1
- data/doc/cxxapi/ApplicationPoolServer_8h-source.html +545 -0
- data/doc/cxxapi/ApplicationPool_8h-source.html +1 -1
- data/doc/cxxapi/Application_8h-source.html +1 -1
- data/doc/cxxapi/Configuration_8h-source.html +2 -2
- data/doc/cxxapi/DummySpawnManager_8h-source.html +1 -1
- data/doc/cxxapi/Exceptions_8h-source.html +1 -1
- data/doc/cxxapi/Hooks_8h-source.html +1 -1
- data/doc/cxxapi/Logging_8h-source.html +1 -1
- data/doc/cxxapi/MessageChannel_8h-source.html +210 -205
- data/doc/cxxapi/SpawnManager_8h-source.html +1 -1
- data/doc/cxxapi/StandardApplicationPool_8h-source.html +1 -1
- data/doc/cxxapi/Utils_8h-source.html +1 -1
- data/doc/cxxapi/annotated.html +1 -1
- data/doc/cxxapi/classClient-members.html +30 -0
- data/doc/cxxapi/classClient.html +112 -0
- data/doc/cxxapi/classPassenger_1_1Application-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1Application.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +1 -1
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +28 -0
- data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +41 -0
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +1 -1
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +1 -1
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1IOException.html +1 -1
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +1 -1
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SystemException.html +1 -1
- data/doc/cxxapi/definitions_8h-source.html +1 -1
- data/doc/cxxapi/files.html +1 -1
- data/doc/cxxapi/functions.html +1 -1
- data/doc/cxxapi/functions_func.html +1 -1
- data/doc/cxxapi/functions_type.html +1 -1
- data/doc/cxxapi/graph_legend.html +1 -1
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Configuration.html +3 -3
- data/doc/cxxapi/group__Configuration.png +0 -0
- data/doc/cxxapi/group__Core.html +1 -1
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +1 -1
- data/doc/cxxapi/group__Hooks.html +1 -1
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +1 -1
- data/doc/cxxapi/hierarchy.html +1 -1
- data/doc/cxxapi/inherit__graph__0.png +0 -0
- data/doc/cxxapi/inherit__graph__1.png +0 -0
- data/doc/cxxapi/inherit__graph__10.map +1 -0
- data/doc/cxxapi/inherit__graph__10.md5 +1 -0
- data/doc/cxxapi/inherit__graph__10.png +0 -0
- data/doc/cxxapi/inherit__graph__2.png +0 -0
- data/doc/cxxapi/inherit__graph__3.png +0 -0
- data/doc/cxxapi/inherit__graph__4.png +0 -0
- data/doc/cxxapi/inherit__graph__5.png +0 -0
- data/doc/cxxapi/inherit__graph__6.png +0 -0
- data/doc/cxxapi/inherit__graph__7.png +0 -0
- data/doc/cxxapi/inherit__graph__8.png +0 -0
- data/doc/cxxapi/inherit__graph__9.png +0 -0
- data/doc/cxxapi/inherits.html +1 -1
- data/doc/cxxapi/main.html +1 -1
- data/doc/cxxapi/modules.html +1 -1
- data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -1
- data/doc/cxxapi/structPassenger_1_1AnythingToString.html +1 -1
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -1
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +1 -1
- data/doc/rdoc/classes/Passenger/RequestHandler.html +84 -74
- data/doc/rdoc/classes/Passenger/SpawnManager.html +54 -49
- data/doc/rdoc/classes/PlatformInfo.html +25 -12
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +1 -1
- data/doc/rdoc/files/ext/passenger/native_support_c.html +1 -1
- data/doc/rdoc/files/lib/passenger/abstract_server_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/application_spawner_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/dependencies_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/framework_spawner_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/platform_info_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/request_handler_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/spawn_manager_rb.html +1 -1
- data/ext/apache2/Configuration.h +1 -1
- data/ext/apache2/Hooks.cpp +68 -16
- data/ext/apache2/Logging.cpp +1 -1
- data/ext/apache2/MessageChannel.h +48 -43
- data/ext/passenger/native_support.c +46 -43
- data/lib/passenger/application_spawner.rb +37 -4
- data/lib/passenger/dependencies.rb +5 -1
- data/lib/passenger/framework_spawner.rb +2 -0
- data/lib/passenger/platform_info.rb +32 -17
- data/lib/passenger/request_handler.rb +10 -1
- data/lib/passenger/spawn_manager.rb +14 -8
- data/lib/passenger/templates/error_layout.html.erb +2 -2
- data/test/CxxTestMain.cpp +1 -0
- data/test/MessageChannelTest.cpp +3 -1
- data/test/application_spawner_spec.rb +2 -0
- data/test/framework_spawner_spec.rb +2 -0
- data/test/integration_tests.rb +1 -0
- data/test/spawn_manager_spec.rb +2 -0
- data/test/spawner_privilege_lowering_spec.rb +1 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +4 -0
- data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +7 -0
- data/test/stub/rails_apps/foobar/config/environments/test.rb +22 -0
- metadata +28 -22
- data/lib/passenger/templates/osx_broken_apache_warning.txt.erb +0 -23
@@ -41,32 +41,32 @@ static VALUE mNativeSupport;
|
|
41
41
|
static VALUE
|
42
42
|
send_fd(VALUE self, VALUE socket_fd, VALUE fd_to_send) {
|
43
43
|
int fd;
|
44
|
-
struct msghdr msg;
|
45
|
-
struct iovec vec[1];
|
46
|
-
char buf[1];
|
47
|
-
|
48
44
|
struct {
|
49
|
-
struct cmsghdr
|
45
|
+
struct cmsghdr header;
|
50
46
|
int fd;
|
51
|
-
}
|
47
|
+
} control;
|
48
|
+
struct msghdr msg;
|
49
|
+
struct iovec vec;
|
50
|
+
char dummy[1];
|
51
|
+
|
52
|
+
control.header.cmsg_len = sizeof(control);
|
53
|
+
control.header.cmsg_level = SOL_SOCKET;
|
54
|
+
control.header.cmsg_type = SCM_RIGHTS;
|
55
|
+
control.fd = NUM2INT(fd_to_send);
|
52
56
|
|
53
57
|
msg.msg_name = NULL;
|
54
58
|
msg.msg_namelen = 0;
|
55
|
-
|
56
|
-
/* Linux and Solaris
|
57
|
-
|
58
|
-
vec
|
59
|
-
vec
|
60
|
-
msg.msg_iov
|
59
|
+
|
60
|
+
/* Linux and Solaris require msg_iov to be non-NULL.. */
|
61
|
+
dummy[0] = '\0';
|
62
|
+
vec.iov_base = dummy;
|
63
|
+
vec.iov_len = sizeof(dummy);
|
64
|
+
msg.msg_iov = &vec;
|
61
65
|
msg.msg_iovlen = 1;
|
62
|
-
|
63
|
-
msg.msg_control
|
64
|
-
msg.msg_controllen =
|
65
|
-
msg.msg_flags
|
66
|
-
cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));
|
67
|
-
cmsg.hdr.cmsg_level = SOL_SOCKET;
|
68
|
-
cmsg.hdr.cmsg_type = SCM_RIGHTS;
|
69
|
-
cmsg.fd = NUM2INT(fd_to_send);
|
66
|
+
|
67
|
+
msg.msg_control = (caddr_t) &control;
|
68
|
+
msg.msg_controllen = sizeof(control);
|
69
|
+
msg.msg_flags = 0;
|
70
70
|
|
71
71
|
if (sendmsg(NUM2INT(socket_fd), &msg, 0) == -1) {
|
72
72
|
rb_sys_fail("sendmsg(2)");
|
@@ -88,43 +88,46 @@ send_fd(VALUE self, VALUE socket_fd, VALUE fd_to_send) {
|
|
88
88
|
*/
|
89
89
|
static VALUE
|
90
90
|
recv_fd(VALUE self, VALUE socket_fd) {
|
91
|
-
struct msghdr msg;
|
92
|
-
struct iovec vec[2];
|
93
|
-
char buf[1];
|
94
91
|
struct {
|
95
|
-
struct cmsghdr
|
92
|
+
struct cmsghdr header;
|
96
93
|
int fd;
|
97
|
-
}
|
94
|
+
} control;
|
98
95
|
|
99
|
-
|
100
|
-
|
96
|
+
control.header.cmsg_len = sizeof(control);
|
97
|
+
control.header.cmsg_level = SOL_SOCKET;
|
98
|
+
control.header.cmsg_type = SCM_RIGHTS;
|
99
|
+
control.fd = -1;
|
100
|
+
|
101
|
+
struct msghdr msg;
|
102
|
+
struct iovec vec;
|
103
|
+
char dummy[1];
|
101
104
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
+
msg.msg_name = NULL;
|
106
|
+
msg.msg_namelen = 0;
|
107
|
+
|
108
|
+
dummy[0] = '\0';
|
109
|
+
vec.iov_base = dummy;
|
110
|
+
vec.iov_len = sizeof(dummy);
|
111
|
+
msg.msg_iov = &vec;
|
105
112
|
msg.msg_iovlen = 1;
|
106
113
|
|
107
|
-
msg.msg_control
|
108
|
-
msg.msg_controllen =
|
109
|
-
msg.msg_flags
|
110
|
-
cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));
|
111
|
-
cmsg.hdr.cmsg_level = SOL_SOCKET;
|
112
|
-
cmsg.hdr.cmsg_type = SCM_RIGHTS;
|
113
|
-
cmsg.fd = -1;
|
114
|
+
msg.msg_control = (caddr_t) &control;
|
115
|
+
msg.msg_controllen = sizeof(control);
|
116
|
+
msg.msg_flags = 0;
|
114
117
|
|
115
118
|
if (recvmsg(NUM2INT(socket_fd), &msg, 0) == -1) {
|
116
119
|
rb_sys_fail("Cannot read file descriptor with recvmsg()");
|
117
120
|
return Qnil;
|
118
121
|
}
|
119
|
-
|
120
|
-
if (msg.msg_controllen
|
121
|
-
||
|
122
|
-
||
|
123
|
-
||
|
122
|
+
|
123
|
+
if (msg.msg_controllen != sizeof(control)
|
124
|
+
|| control.header.cmsg_len != sizeof(control)
|
125
|
+
|| control.header.cmsg_level != SOL_SOCKET
|
126
|
+
|| control.header.cmsg_type != SCM_RIGHTS) {
|
124
127
|
rb_sys_fail("No valid file descriptor received.");
|
125
128
|
return Qnil;
|
126
129
|
}
|
127
|
-
return INT2NUM(
|
130
|
+
return INT2NUM(control.fd);
|
128
131
|
}
|
129
132
|
|
130
133
|
/*
|
@@ -182,6 +182,9 @@ protected
|
|
182
182
|
lower_privilege! if @lower_privilege
|
183
183
|
preload_application
|
184
184
|
rescue StandardError, ScriptError, NoMemoryError => e
|
185
|
+
if ENV['TESTING_PASSENGER'] == '1'
|
186
|
+
print_exception(self.class.to_s, e)
|
187
|
+
end
|
185
188
|
client.write('exception')
|
186
189
|
client.write_scalar(marshal_exception(e))
|
187
190
|
return
|
@@ -208,11 +211,14 @@ private
|
|
208
211
|
begin
|
209
212
|
if user.is_a?(String)
|
210
213
|
pw = Etc.getpwnam(user)
|
214
|
+
username = user
|
211
215
|
uid = pw.uid
|
212
216
|
gid = pw.gid
|
213
217
|
else
|
218
|
+
pw = Etc.getpwuid(user)
|
219
|
+
username = pw.name
|
214
220
|
uid = user
|
215
|
-
gid =
|
221
|
+
gid = pw.gid
|
216
222
|
end
|
217
223
|
rescue
|
218
224
|
return false
|
@@ -220,6 +226,7 @@ private
|
|
220
226
|
if uid == ROOT_UID
|
221
227
|
return false
|
222
228
|
else
|
229
|
+
Process.groups = Process.initgroups(username, gid)
|
223
230
|
Process::Sys.setgid(gid)
|
224
231
|
Process::Sys.setuid(uid)
|
225
232
|
return true
|
@@ -230,9 +237,26 @@ private
|
|
230
237
|
Object.const_set(:RAILS_ROOT, @app_root)
|
231
238
|
if defined?(Rails::Initializer)
|
232
239
|
Rails::Initializer.run(:set_load_path)
|
240
|
+
|
241
|
+
# The Rails framework is loaded at the moment.
|
242
|
+
# environment.rb may set ENV['RAILS_ENV']. So we re-initialize
|
243
|
+
# RAILS_ENV in Rails::Initializer.load_environment.
|
244
|
+
Rails::Initializer.class_eval do
|
245
|
+
def load_environment_with_passenger
|
246
|
+
if defined?(::RAILS_ENV)
|
247
|
+
Object.send(:remove_const, :RAILS_ENV)
|
248
|
+
end
|
249
|
+
Object.const_set(:RAILS_ENV, (ENV['RAILS_ENV'] || 'development').dup)
|
250
|
+
load_environment_without_passenger
|
251
|
+
end
|
252
|
+
|
253
|
+
alias_method_chain :load_environment, :passenger
|
254
|
+
end
|
233
255
|
end
|
234
256
|
require 'config/environment'
|
235
|
-
ActionController::Base.page_cache_directory
|
257
|
+
if ActionController::Base.page_cache_directory.blank?
|
258
|
+
ActionController::Base.page_cache_directory = "#{RAILS_ROOT}/public"
|
259
|
+
end
|
236
260
|
if defined?(ActionController::Dispatcher) \
|
237
261
|
&& ActionController::Dispatcher.respond_to?(:error_file_path)
|
238
262
|
ActionController::Dispatcher.error_file_path = "#{RAILS_ROOT}/public"
|
@@ -241,8 +265,10 @@ private
|
|
241
265
|
require 'dispatcher'
|
242
266
|
end
|
243
267
|
require_dependency 'application'
|
244
|
-
|
245
|
-
|
268
|
+
if GC.copy_on_write_friendly?
|
269
|
+
Dir.glob('app/{models,controllers,helpers}/*.rb').each do |file|
|
270
|
+
require_dependency normalize_path(file)
|
271
|
+
end
|
246
272
|
end
|
247
273
|
end
|
248
274
|
|
@@ -277,6 +303,13 @@ private
|
|
277
303
|
$0 = "Rails: #{@app_root}"
|
278
304
|
reader, writer = IO.pipe
|
279
305
|
begin
|
306
|
+
# Re-establish connection if a connection was established
|
307
|
+
# in environment.rb. This prevents us from concurrently
|
308
|
+
# accessing the same MySQL connection handle.
|
309
|
+
if defined?(::ActiveRecord::Base) && ::ActiveRecord::Base.connected?
|
310
|
+
::ActiveRecord::Base.establish_connection
|
311
|
+
end
|
312
|
+
|
280
313
|
handler = RequestHandler.new(reader)
|
281
314
|
client.write(Process.pid, handler.socket_name,
|
282
315
|
handler.using_abstract_namespace?)
|
@@ -248,7 +248,7 @@ module Dependencies # :nodoc: all
|
|
248
248
|
APR_DevHeaders = Dependency.new do |dep|
|
249
249
|
dep.name = "Apache Portable Runtime (APR) development headers"
|
250
250
|
dep.define_checker do |result|
|
251
|
-
result.found(
|
251
|
+
result.found(APR_CONFIG)
|
252
252
|
end
|
253
253
|
if RUBY_PLATFORM =~ /linux/
|
254
254
|
case LINUX_DISTRO
|
@@ -259,6 +259,10 @@ module Dependencies # :nodoc: all
|
|
259
259
|
when :gentoo
|
260
260
|
dep.install_command = "emerge -av apr"
|
261
261
|
end
|
262
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
263
|
+
dep.install_instructions = "Please install Apache from MacPorts, which will " <<
|
264
|
+
"provide APR automatically. <b>Or</b>, if you're installing against MacOS X's " <<
|
265
|
+
"default provided Apache, then please install the OS X Developer SDK."
|
262
266
|
end
|
263
267
|
dep.website = "http://httpd.apache.org/"
|
264
268
|
dep.website_comments = "APR is an integrated part of Apache."
|
@@ -120,27 +120,40 @@ private
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
def self.
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
123
|
+
def self.find_apr_config
|
124
|
+
if env_defined?('APR_CONFIG')
|
125
|
+
apr_config = ENV['APR_CONFIG']
|
126
|
+
elsif RUBY_PLATFORM =~ /darwin/ && HTTPD == "/usr/sbin/httpd"
|
127
|
+
# If we're on MacOS X, and we're compiling against the
|
128
|
+
# default provided Apache, then we'll want to query the
|
129
|
+
# correct 'apr-1-config' command. However, that command
|
130
|
+
# is not in $PATH by default. Instead, it lives in
|
131
|
+
# /Developer/SDKs/MacOSX*sdk/usr/bin.
|
132
|
+
sdk_dir = Dir["/Developer/SDKs/MacOSX*sdk"].sort.last
|
133
|
+
if sdk_dir
|
134
|
+
apr_config = "#{sdk_dir}/usr/bin/apr-1-config"
|
135
|
+
if !File.executable?(apr_config)
|
136
|
+
apr_config = nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
else
|
131
140
|
apr_config = find_command('apr-1-config')
|
132
141
|
if apr_config.nil?
|
133
142
|
apr_config = find_command('apr-config')
|
134
143
|
end
|
135
|
-
if apr_config.nil?
|
136
|
-
return nil
|
137
|
-
else
|
138
|
-
flags = `#{apr_config} --cppflags --includes`.strip
|
139
|
-
libs = `#{apr_config} --link-ld`.strip
|
140
|
-
end
|
141
144
|
end
|
142
|
-
|
143
|
-
|
145
|
+
return apr_config
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.determine_apr_info
|
149
|
+
if APR_CONFIG.nil?
|
150
|
+
return nil
|
151
|
+
else
|
152
|
+
flags = `#{APR_CONFIG} --cppflags --includes`.strip
|
153
|
+
libs = `#{APR_CONFIG} --link-ld`.strip
|
154
|
+
flags.gsub!(/-O\d? /, '')
|
155
|
+
return [flags, libs]
|
156
|
+
end
|
144
157
|
end
|
145
158
|
|
146
159
|
def self.determine_multi_arch_flags
|
@@ -231,11 +244,13 @@ public
|
|
231
244
|
APACHE2CTL = find_apache2ctl
|
232
245
|
# The absolute path to the Apache binary (that is, 'httpd', 'httpd2', 'apache' or 'apache2').
|
233
246
|
HTTPD = find_httpd
|
247
|
+
# The absolute path to the 'apr-config' or 'apr-1-config' executable.
|
248
|
+
APR_CONFIG = find_apr_config
|
234
249
|
|
235
250
|
# The C compiler flags that are necessary to compile an Apache module.
|
236
251
|
APXS2_FLAGS = determine_apxs2_flags
|
237
252
|
# The C compiler flags that are necessary for programs that use APR.
|
238
|
-
|
253
|
+
APR_FLAGS, APR_LIBS = determine_apr_info
|
239
254
|
|
240
255
|
# The C compiler flags that are necessary for building binaries in the same architecture(s) as Apache.
|
241
256
|
MULTI_ARCH_FLAGS = determine_multi_arch_flags
|
@@ -97,12 +97,17 @@ class RequestHandler
|
|
97
97
|
DEFAULT = 'DEFAULT' # :nodoc:
|
98
98
|
CONTENT_LENGTH = 'CONTENT_LENGTH' # :nodoc:
|
99
99
|
HTTP_CONTENT_LENGTH = 'HTTP_CONTENT_LENGTH' # :nodoc:
|
100
|
+
X_POWERED_BY = 'X-Powered-By'
|
100
101
|
|
101
102
|
NINJA_PATCHING_LOCK = Mutex.new
|
102
103
|
@@ninja_patched_action_controller = false
|
103
104
|
|
104
105
|
File.read("#{File.dirname(__FILE__)}/../../Rakefile") =~ /^PACKAGE_VERSION = "(.*)"$/
|
105
106
|
PASSENGER_VERSION = $1
|
107
|
+
PASSENGER_HEADER = "Phusion Passenger (mod_rails) #{PASSENGER_VERSION}"
|
108
|
+
if File.exist?("#{File.dirname(__FILE__)}/../../enterprisey.txt")
|
109
|
+
PASSENGER_HEADER << ", Enterprise Edition"
|
110
|
+
end
|
106
111
|
|
107
112
|
# The name of the socket on which the request handler accepts
|
108
113
|
# new connections. This is either a Unix socket filename, or
|
@@ -136,7 +141,7 @@ class RequestHandler
|
|
136
141
|
alias passenger_orig_perform_action perform_action
|
137
142
|
|
138
143
|
def perform_action(*whatever)
|
139
|
-
headers[
|
144
|
+
headers[X_POWERED_BY] = PASSENGER_HEADER
|
140
145
|
passenger_orig_perform_action(*whatever)
|
141
146
|
end
|
142
147
|
end
|
@@ -273,6 +278,10 @@ private
|
|
273
278
|
def write(block)
|
274
279
|
@io.write(block)
|
275
280
|
end
|
281
|
+
|
282
|
+
def <<(block)
|
283
|
+
@io.write(block)
|
284
|
+
end
|
276
285
|
end
|
277
286
|
|
278
287
|
def process_request(socket)
|
@@ -106,14 +106,19 @@ class SpawnManager < AbstractServer
|
|
106
106
|
spawner.start
|
107
107
|
@spawners[key] = spawner
|
108
108
|
end
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
109
|
+
spawner.time = Time.now
|
110
|
+
begin
|
111
|
+
if spawner.is_a?(FrameworkSpawner)
|
112
|
+
return spawner.spawn_application(app_root, lower_privilege,
|
113
|
+
lowest_user)
|
114
|
+
else
|
115
|
+
return spawner.spawn_application
|
116
|
+
end
|
117
|
+
rescue AbstractServer::ServerError
|
118
|
+
spawner.stop
|
119
|
+
@spawners.delete(key)
|
120
|
+
raise
|
121
|
+
end
|
117
122
|
end
|
118
123
|
end
|
119
124
|
|
@@ -242,6 +247,7 @@ private
|
|
242
247
|
end
|
243
248
|
|
244
249
|
def send_error_page(channel, template_name, options = {})
|
250
|
+
options["enterprisey"] = File.exist?("#{File.dirname(__FILE__)}/../../enterprisey.txt")
|
245
251
|
data = HTMLTemplate.new(template_name, options).result
|
246
252
|
channel.write('error_page')
|
247
253
|
channel.write_scalar(data)
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
<div id="site_container">
|
16
16
|
<div id="site_header">
|
17
|
-
<ul class="corporate_identity">
|
17
|
+
<ul class="corporate_identity <% if @enterprisey %>enterprise_edition<% end %>">
|
18
18
|
<li class="logo"><a href="http://www.modrails.com"><span>Phusion Passenger</span></a></li>
|
19
19
|
</ul>
|
20
20
|
</div>
|
@@ -28,7 +28,7 @@
|
|
28
28
|
text. Thank you.
|
29
29
|
-->
|
30
30
|
<div class="container">
|
31
|
-
Powered by <a href="http://www.modrails.com/">Phusion Passenger</a
|
31
|
+
Powered by <a href="http://www.modrails.com/">Phusion Passenger</a><% if @enterprisey %> (Enterprise Edition)<% end %>,
|
32
32
|
<tt>mod_rails</tt> for Apache.
|
33
33
|
</div>
|
34
34
|
</div>
|
data/test/CxxTestMain.cpp
CHANGED
data/test/MessageChannelTest.cpp
CHANGED
@@ -6,6 +6,8 @@ require 'spawner_privilege_lowering_spec'
|
|
6
6
|
require 'spawner_error_handling_spec'
|
7
7
|
include Passenger
|
8
8
|
|
9
|
+
# TODO: write unit test which checks whether setting ENV['RAILS_ENV'] in environment.rb is respected (issue #6)
|
10
|
+
|
9
11
|
describe ApplicationSpawner do
|
10
12
|
before :all do
|
11
13
|
ENV['RAILS_ENV'] = 'production'
|
@@ -6,6 +6,8 @@ require 'spawner_privilege_lowering_spec'
|
|
6
6
|
require 'spawner_error_handling_spec'
|
7
7
|
include Passenger
|
8
8
|
|
9
|
+
# TODO: test whether FrameworkSpawner restarts ApplicationSpawner if it crashed
|
10
|
+
|
9
11
|
describe FrameworkSpawner do
|
10
12
|
before :all do
|
11
13
|
ENV['RAILS_ENV'] = 'production'
|
data/test/integration_tests.rb
CHANGED
@@ -11,6 +11,7 @@ require 'passenger/platform_info'
|
|
11
11
|
include PlatformInfo
|
12
12
|
|
13
13
|
# TODO: test the 'RailsUserSwitching' and 'RailsDefaultUser' option.
|
14
|
+
# TODO: test custom page caching directory
|
14
15
|
|
15
16
|
shared_examples_for "MyCook(tm) beta" do
|
16
17
|
it "should be possible to fetch static assets" do
|