colouringcode-passenger 0.1 → 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/NEWS +129 -0
- data/Rakefile +2 -2
- data/bin/passenger-install-apache2-module +1 -0
- data/bin/passenger-install-nginx-module +4 -2
- data/ext/apache2/Hooks.cpp +4 -2
- data/ext/common/ApplicationPoolServer.h +1 -1
- data/ext/common/ApplicationPoolServerExecutable.cpp +1 -1
- data/ext/common/MessageChannel.h +48 -4
- data/ext/common/StandardApplicationPool.h +4 -2
- data/ext/common/Version.h +1 -1
- data/ext/nginx/Configuration.c +1 -1
- data/ext/nginx/HttpStatusExtractor.h +1 -0
- data/ext/nginx/ScgiRequestParser.h +1 -0
- data/ext/oxt/system_calls.cpp +11 -0
- data/ext/oxt/system_calls.hpp +2 -1
- data/ext/oxt/thread.hpp +97 -1
- data/ext/phusion_passenger/native_support.c +30 -1
- data/lib/phusion_passenger/constants.rb +1 -1
- data/lib/phusion_passenger/dependencies.rb +32 -0
- data/lib/phusion_passenger/message_channel.rb +45 -3
- data/lib/phusion_passenger/platform_info.rb +1 -1
- data/lib/phusion_passenger/rack/application_spawner.rb +10 -4
- data/lib/phusion_passenger/rack/request_handler.rb +2 -5
- data/lib/phusion_passenger/railz/application_spawner.rb +59 -7
- data/lib/phusion_passenger/utils.rb +70 -16
- data/{vendor/rack-1.0.0-git/lib/rack → lib/phusion_passenger/utils}/rewindable_input.rb +34 -9
- data/test/ApplicationPoolTest.cpp +1 -1
- data/test/MessageChannelTest.cpp +9 -1
- data/test/stub/message_channel.rb +1 -1
- data/test/stub/message_channel_2.rb +1 -1
- data/test/stub/message_channel_3.rb +2 -2
- metadata +43 -155
- data/doc/Architectural overview.html +0 -1
- data/doc/rdoc/classes/ConditionVariable.html +0 -194
- data/doc/rdoc/classes/Exception.html +0 -120
- data/doc/rdoc/classes/GC.html +0 -113
- data/doc/rdoc/classes/IO.html +0 -169
- data/doc/rdoc/classes/PhusionPassenger.html +0 -238
- data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +0 -153
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +0 -517
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +0 -719
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +0 -97
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +0 -96
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +0 -97
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +0 -96
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +0 -598
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +0 -140
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +0 -317
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +0 -138
- data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +0 -154
- data/doc/rdoc/classes/PhusionPassenger/Application.html +0 -283
- data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +0 -172
- data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +0 -145
- data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +0 -181
- data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +0 -141
- data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +0 -92
- data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +0 -489
- data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +0 -350
- data/doc/rdoc/classes/PhusionPassenger/Rack.html +0 -91
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +0 -188
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +0 -199
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +0 -95
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +0 -438
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +0 -98
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +0 -200
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +0 -436
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +0 -98
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +0 -155
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +0 -402
- data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +0 -125
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +0 -803
- data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +0 -169
- data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +0 -140
- data/doc/rdoc/classes/PhusionPassenger/WSGI.html +0 -89
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +0 -188
- data/doc/rdoc/classes/PlatformInfo.html +0 -866
- data/doc/rdoc/classes/RakeExtensions.html +0 -197
- data/doc/rdoc/classes/Signal.html +0 -131
- data/doc/rdoc/created.rid +0 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +0 -255
- data/doc/rdoc/files/README.html +0 -175
- data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +0 -92
- data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +0 -129
- data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +0 -129
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +0 -126
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +0 -128
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +0 -130
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +0 -127
- data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +0 -126
- data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +0 -134
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +0 -126
- data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +0 -120
- data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +0 -127
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +0 -133
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +0 -125
- data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +0 -140
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +0 -126
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +0 -145
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +0 -125
- data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +0 -159
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +0 -174
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +0 -129
- data/doc/rdoc/files/misc/rake/extensions_rb.html +0 -130
- data/doc/rdoc/fr_class_index.html +0 -91
- data/doc/rdoc/fr_file_index.html +0 -76
- data/doc/rdoc/fr_method_index.html +0 -205
- data/doc/rdoc/index.html +0 -26
- data/doc/rdoc/rdoc-style.css +0 -187
- data/vendor/README +0 -13
- data/vendor/README_FOR_PACKAGERS +0 -1
- data/vendor/rack-1.0.0-git/COPYING +0 -18
- data/vendor/rack-1.0.0-git/KNOWN-ISSUES +0 -18
- data/vendor/rack-1.0.0-git/README +0 -353
- data/vendor/rack-1.0.0-git/Rakefile +0 -164
- data/vendor/rack-1.0.0-git/lib/rack.rb +0 -90
- data/vendor/rack-1.0.0-git/lib/rack/adapter/camping.rb +0 -22
- data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/handler.rb +0 -37
- data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/request.rb +0 -37
- data/vendor/rack-1.0.0-git/lib/rack/auth/basic.rb +0 -58
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/md5.rb +0 -124
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/nonce.rb +0 -51
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/params.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/request.rb +0 -40
- data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +0 -487
- data/vendor/rack-1.0.0-git/lib/rack/builder.rb +0 -63
- data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +0 -41
- data/vendor/rack-1.0.0-git/lib/rack/chunked.rb +0 -49
- data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +0 -52
- data/vendor/rack-1.0.0-git/lib/rack/conditionalget.rb +0 -47
- data/vendor/rack-1.0.0-git/lib/rack/content_length.rb +0 -29
- data/vendor/rack-1.0.0-git/lib/rack/content_type.rb +0 -23
- data/vendor/rack-1.0.0-git/lib/rack/deflater.rb +0 -96
- data/vendor/rack-1.0.0-git/lib/rack/directory.rb +0 -153
- data/vendor/rack-1.0.0-git/lib/rack/file.rb +0 -88
- data/vendor/rack-1.0.0-git/lib/rack/handler.rb +0 -69
- data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +0 -61
- data/vendor/rack-1.0.0-git/lib/rack/handler/evented_mongrel.rb +0 -8
- data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +0 -88
- data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +0 -84
- data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +0 -59
- data/vendor/rack-1.0.0-git/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/vendor/rack-1.0.0-git/lib/rack/handler/thin.rb +0 -18
- data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +0 -67
- data/vendor/rack-1.0.0-git/lib/rack/head.rb +0 -19
- data/vendor/rack-1.0.0-git/lib/rack/lint.rb +0 -537
- data/vendor/rack-1.0.0-git/lib/rack/lobster.rb +0 -65
- data/vendor/rack-1.0.0-git/lib/rack/lock.rb +0 -16
- data/vendor/rack-1.0.0-git/lib/rack/methodoverride.rb +0 -27
- data/vendor/rack-1.0.0-git/lib/rack/mime.rb +0 -204
- data/vendor/rack-1.0.0-git/lib/rack/mock.rb +0 -184
- data/vendor/rack-1.0.0-git/lib/rack/recursive.rb +0 -57
- data/vendor/rack-1.0.0-git/lib/rack/reloader.rb +0 -106
- data/vendor/rack-1.0.0-git/lib/rack/request.rb +0 -248
- data/vendor/rack-1.0.0-git/lib/rack/response.rb +0 -183
- data/vendor/rack-1.0.0-git/lib/rack/session/abstract/id.rb +0 -142
- data/vendor/rack-1.0.0-git/lib/rack/session/cookie.rb +0 -91
- data/vendor/rack-1.0.0-git/lib/rack/session/memcache.rb +0 -109
- data/vendor/rack-1.0.0-git/lib/rack/session/pool.rb +0 -100
- data/vendor/rack-1.0.0-git/lib/rack/showexceptions.rb +0 -349
- data/vendor/rack-1.0.0-git/lib/rack/showstatus.rb +0 -106
- data/vendor/rack-1.0.0-git/lib/rack/static.rb +0 -38
- data/vendor/rack-1.0.0-git/lib/rack/urlmap.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/utils.rb +0 -522
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
#include <string.h>
|
|
31
31
|
#include <unistd.h>
|
|
32
32
|
#include <errno.h>
|
|
33
|
+
#include <grp.h>
|
|
33
34
|
#ifdef __OpenBSD__
|
|
34
35
|
// OpenBSD needs this for 'struct iovec'. Apparently it isn't
|
|
35
36
|
// always included by unistd.h and sys/types.h.
|
|
@@ -158,10 +159,14 @@ recv_fd(VALUE self, VALUE socket_fd) {
|
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
control_header = CMSG_FIRSTHDR(&msg);
|
|
162
|
+
if (control_header == NULL) {
|
|
163
|
+
rb_raise(rb_eIOError, "No valid file descriptor received.");
|
|
164
|
+
return Qnil;
|
|
165
|
+
}
|
|
161
166
|
if (control_header->cmsg_len != EXPECTED_CMSG_LEN
|
|
162
167
|
|| control_header->cmsg_level != SOL_SOCKET
|
|
163
168
|
|| control_header->cmsg_type != SCM_RIGHTS) {
|
|
164
|
-
|
|
169
|
+
rb_raise(rb_eIOError, "No valid file descriptor received.");
|
|
165
170
|
return Qnil;
|
|
166
171
|
}
|
|
167
172
|
#if defined(__APPLE__) || defined(__SOLARIS__) || defined(__arm__)
|
|
@@ -282,6 +287,29 @@ disable_stdio_buffering() {
|
|
|
282
287
|
return Qnil;
|
|
283
288
|
}
|
|
284
289
|
|
|
290
|
+
/**
|
|
291
|
+
* Ruby's implementations of initgroups, setgid and setuid are broken various ways,
|
|
292
|
+
* sigh...
|
|
293
|
+
* Ruby's setgid and setuid can't handle negative UIDs and initgroups is just broken.
|
|
294
|
+
* Work around it by using our own implementation.
|
|
295
|
+
*/
|
|
296
|
+
static VALUE
|
|
297
|
+
switch_user(VALUE self, VALUE username, VALUE uid, VALUE gid) {
|
|
298
|
+
uid_t the_uid = NUM2LL(uid);
|
|
299
|
+
gid_t the_gid = NUM2LL(gid);
|
|
300
|
+
|
|
301
|
+
if (initgroups(RSTRING_PTR(username), the_gid) == -1) {
|
|
302
|
+
rb_sys_fail("initgroups");
|
|
303
|
+
}
|
|
304
|
+
if (setgid(the_gid) == -1) {
|
|
305
|
+
rb_sys_fail("setgid");
|
|
306
|
+
}
|
|
307
|
+
if (setuid(the_uid) == -1) {
|
|
308
|
+
rb_sys_fail("setuid");
|
|
309
|
+
}
|
|
310
|
+
return Qnil;
|
|
311
|
+
}
|
|
312
|
+
|
|
285
313
|
/***************************/
|
|
286
314
|
|
|
287
315
|
void
|
|
@@ -302,6 +330,7 @@ Init_native_support() {
|
|
|
302
330
|
rb_define_singleton_method(mNativeSupport, "accept", f_accept, 1);
|
|
303
331
|
rb_define_singleton_method(mNativeSupport, "close_all_file_descriptors", close_all_file_descriptors, 1);
|
|
304
332
|
rb_define_singleton_method(mNativeSupport, "disable_stdio_buffering", disable_stdio_buffering, 0);
|
|
333
|
+
rb_define_singleton_method(mNativeSupport, "switch_user", switch_user, 3);
|
|
305
334
|
|
|
306
335
|
/* The maximum length of a Unix socket path, including terminating null. */
|
|
307
336
|
rb_define_const(mNativeSupport, "UNIX_PATH_MAX", INT2NUM(sizeof(addr.sun_path)));
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
module PhusionPassenger
|
|
25
25
|
# Phusion Passenger version number.
|
|
26
26
|
# Don't forget to edit ext/common/Version.h too.
|
|
27
|
-
VERSION_STRING = '2.2.
|
|
27
|
+
VERSION_STRING = '2.2.12'
|
|
28
28
|
|
|
29
29
|
DEFAULT_FRAMEWORK_SPAWNER_MAX_IDLE_TIME = 30 * 60
|
|
30
30
|
DEFAULT_APP_SPAWNER_MAX_IDLE_TIME = 10 * 60
|
|
@@ -357,6 +357,38 @@ module Dependencies # :nodoc: all
|
|
|
357
357
|
dep.install_instructions = "Please install RubyGems first, then run <b>#{PlatformInfo::GEM || "gem"} install rack</b>"
|
|
358
358
|
end
|
|
359
359
|
|
|
360
|
+
OpenSSL_Dev = Dependency.new do |dep|
|
|
361
|
+
dep.name = "OpenSSL development headers"
|
|
362
|
+
dep.define_checker do |result|
|
|
363
|
+
source_file = '/tmp/passenger-openssl-check.c'
|
|
364
|
+
object_file = '/tmp/passenger-openssl-check.o'
|
|
365
|
+
begin
|
|
366
|
+
File.open(source_file, 'w') do |f|
|
|
367
|
+
f.write("#include <openssl/ssl.h>")
|
|
368
|
+
end
|
|
369
|
+
Dir.chdir(File.dirname(source_file)) do
|
|
370
|
+
if system("(gcc #{ENV['CFLAGS']} -c '#{source_file}') >/dev/null 2>/dev/null")
|
|
371
|
+
result.found
|
|
372
|
+
else
|
|
373
|
+
result.not_found
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
ensure
|
|
377
|
+
File.unlink(source_file) rescue nil
|
|
378
|
+
File.unlink(object_file) rescue nil
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
if RUBY_PLATFORM =~ /linux/
|
|
382
|
+
tags = PlatformInfo.linux_distro_tags
|
|
383
|
+
if tags.include?(:debian)
|
|
384
|
+
dep.install_command = "apt-get install libssl-dev"
|
|
385
|
+
elsif tags.include?(:redhat)
|
|
386
|
+
dep.install_command = "yum install openssl-devel"
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
dep.website = "http://www.openssl.org/"
|
|
390
|
+
end
|
|
391
|
+
|
|
360
392
|
Zlib_Dev = Dependency.new do |dep|
|
|
361
393
|
dep.name = "Zlib development headers"
|
|
362
394
|
dep.define_checker do |result|
|
|
@@ -193,8 +193,11 @@ class MessageChannel
|
|
|
193
193
|
#
|
|
194
194
|
# Might raise SystemCallError, IOError or SocketError when something
|
|
195
195
|
# goes wrong.
|
|
196
|
-
def recv_io
|
|
197
|
-
|
|
196
|
+
def recv_io(klass = IO, negotiate = true)
|
|
197
|
+
write("pass IO") if negotiate
|
|
198
|
+
io = @io.recv_io(klass)
|
|
199
|
+
write("got IO") if negotiate
|
|
200
|
+
return io
|
|
198
201
|
end
|
|
199
202
|
|
|
200
203
|
# Send an IO object (a file descriptor) over the channel. The other
|
|
@@ -204,7 +207,46 @@ class MessageChannel
|
|
|
204
207
|
# Might raise SystemCallError, IOError or SocketError when something
|
|
205
208
|
# goes wrong.
|
|
206
209
|
def send_io(io)
|
|
207
|
-
|
|
210
|
+
# We read a message before actually calling #send_io
|
|
211
|
+
# in order to prevent the other side from accidentally
|
|
212
|
+
# read()ing past the normal data and reading our file
|
|
213
|
+
# descriptor too.
|
|
214
|
+
#
|
|
215
|
+
# For example suppose that side A looks like this:
|
|
216
|
+
#
|
|
217
|
+
# read(fd, buf, 1024)
|
|
218
|
+
# read_io(fd)
|
|
219
|
+
#
|
|
220
|
+
# and side B:
|
|
221
|
+
#
|
|
222
|
+
# write(fd, buf, 100)
|
|
223
|
+
# send_io(fd_to_pass)
|
|
224
|
+
#
|
|
225
|
+
# If B completes both write() and send_io(), then A's read() call
|
|
226
|
+
# reads past the 100 bytes that B sent. On some platforms, like
|
|
227
|
+
# Linux, this will cause read_io() to fail. And it just so happens
|
|
228
|
+
# that Ruby's IO#read method slurps more than just the given amount
|
|
229
|
+
# of bytes.
|
|
230
|
+
result = read
|
|
231
|
+
if !result
|
|
232
|
+
raise EOFError, "End of stream"
|
|
233
|
+
elsif result != ["pass IO"]
|
|
234
|
+
raise IOError, "IO passing pre-negotiation header expected"
|
|
235
|
+
else
|
|
236
|
+
@io.send_io(io)
|
|
237
|
+
# Once you've sent the IO you expect to be able to close it on the
|
|
238
|
+
# sender's side, even if the other side hasn't read the IO yet.
|
|
239
|
+
# Not so: on some operating systems (I'm looking at you OS X) this
|
|
240
|
+
# can cause the receiving side to receive a bad file descriptor.
|
|
241
|
+
# The post negotiation protocol ensures that we block until the
|
|
242
|
+
# other side has really received the IO.
|
|
243
|
+
result = read
|
|
244
|
+
if !result
|
|
245
|
+
raise EOFError, "End of stream"
|
|
246
|
+
elsif result != ["got IO"]
|
|
247
|
+
raise IOError, "IO passing post-negotiation header expected"
|
|
248
|
+
end
|
|
249
|
+
end
|
|
208
250
|
end
|
|
209
251
|
|
|
210
252
|
# Return the file descriptor of the underlying IO object.
|
|
@@ -346,7 +346,7 @@ public
|
|
|
346
346
|
flags << '-DBOOST_HAS_STDINT_H -D_GLIBCPP__PTHREADS'
|
|
347
347
|
elsif RUBY_PLATFORM =~ /aix/
|
|
348
348
|
flags << '-DOXT_DISABLE_BACKTRACES'
|
|
349
|
-
elsif RUBY_PLATFORM =~ /(sparc-linux|arm-linux)/
|
|
349
|
+
elsif RUBY_PLATFORM =~ /(sparc-linux|arm-linux|sh4-linux)/
|
|
350
350
|
# http://code.google.com/p/phusion-passenger/issues/detail?id=200
|
|
351
351
|
# http://groups.google.com/group/phusion-passenger/t/6b904a962ee28e5c
|
|
352
352
|
flags << '-DBOOST_SP_USE_PTHREADS'
|
|
@@ -21,10 +21,6 @@
|
|
|
21
21
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
22
|
# THE SOFTWARE.
|
|
23
23
|
|
|
24
|
-
rack_dir = File.expand_path(File.dirname(__FILE__) + "/../../../vendor/rack-1.0.0-git/lib")
|
|
25
|
-
$LOAD_PATH.unshift(rack_dir) if !$LOAD_PATH.include?(rack_dir)
|
|
26
|
-
require 'rack'
|
|
27
|
-
|
|
28
24
|
require 'socket'
|
|
29
25
|
require 'phusion_passenger/application'
|
|
30
26
|
require 'phusion_passenger/events'
|
|
@@ -90,6 +86,7 @@ private
|
|
|
90
86
|
app = nil
|
|
91
87
|
success = report_app_init_status(channel) do
|
|
92
88
|
ENV['RACK_ENV'] = options["environment"]
|
|
89
|
+
ENV['RAILS_ENV'] = options["environment"]
|
|
93
90
|
if options["base_uri"] && options["base_uri"] != "/"
|
|
94
91
|
ENV['RACK_BASE_URI'] = options["base_uri"]
|
|
95
92
|
ENV['RAILS_RELATIVE_URL_ROOT'] = options["base_uri"]
|
|
@@ -101,6 +98,11 @@ private
|
|
|
101
98
|
if options["lower_privilege"]
|
|
102
99
|
lower_privilege('config.ru', options["lowest_user"])
|
|
103
100
|
end
|
|
101
|
+
# Make sure RubyGems uses any new environment variable values
|
|
102
|
+
# that have been set now (e.g. $HOME, $GEM_HOME, etc) and that
|
|
103
|
+
# it is able to detect newly installed gems.
|
|
104
|
+
Gem.clear_paths
|
|
105
|
+
setup_bundler_support
|
|
104
106
|
app = load_rack_app
|
|
105
107
|
end
|
|
106
108
|
|
|
@@ -137,6 +139,10 @@ private
|
|
|
137
139
|
end
|
|
138
140
|
|
|
139
141
|
def load_rack_app
|
|
142
|
+
# Load Rack inside the spawned child process so that the spawn manager
|
|
143
|
+
# itself doesn't preload Rack. This is necessary because some broken
|
|
144
|
+
# Rails apps explicitly specify a Rack version as dependency.
|
|
145
|
+
require 'rack'
|
|
140
146
|
rackup_code = ::File.read("config.ru")
|
|
141
147
|
eval("Rack::Builder.new {( #{rackup_code}\n )}.to_app", TOPLEVEL_BINDING, "config.ru")
|
|
142
148
|
end
|
|
@@ -22,11 +22,8 @@
|
|
|
22
22
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
23
|
# THE SOFTWARE.
|
|
24
24
|
|
|
25
|
-
rack_dir = File.expand_path(File.dirname(__FILE__) + "/../../../vendor/rack-1.0.0-git/lib")
|
|
26
|
-
$LOAD_PATH.unshift(rack_dir) if !$LOAD_PATH.include?(rack_dir)
|
|
27
|
-
require 'rack/rewindable_input'
|
|
28
|
-
|
|
29
25
|
require 'phusion_passenger/abstract_request_handler'
|
|
26
|
+
require 'phusion_passenger/utils/rewindable_input'
|
|
30
27
|
|
|
31
28
|
module PhusionPassenger
|
|
32
29
|
module Rack
|
|
@@ -64,7 +61,7 @@ class RequestHandler < AbstractRequestHandler
|
|
|
64
61
|
protected
|
|
65
62
|
# Overrided method.
|
|
66
63
|
def process_request(env, input, output)
|
|
67
|
-
rewindable_input = ::
|
|
64
|
+
rewindable_input = Utils::RewindableInput.new(input)
|
|
68
65
|
begin
|
|
69
66
|
env[RACK_VERSION] = RACK_VERSION_VALUE
|
|
70
67
|
env[RACK_INPUT] = rewindable_input
|
|
@@ -161,6 +161,7 @@ class ApplicationSpawner < AbstractServer
|
|
|
161
161
|
channel = MessageChannel.new(b)
|
|
162
162
|
success = report_app_init_status(channel) do
|
|
163
163
|
ENV['RAILS_ENV'] = @environment
|
|
164
|
+
ENV['RACK_ENV'] = @environment
|
|
164
165
|
ENV['RAILS_RELATIVE_URL_ROOT'] = @base_uri
|
|
165
166
|
Dir.chdir(@app_root)
|
|
166
167
|
if @encoded_environment_variables
|
|
@@ -169,6 +170,11 @@ class ApplicationSpawner < AbstractServer
|
|
|
169
170
|
if @lower_privilege
|
|
170
171
|
lower_privilege('config/environment.rb', @lowest_user)
|
|
171
172
|
end
|
|
173
|
+
# Make sure RubyGems uses any new environment variable values
|
|
174
|
+
# that have been set now (e.g. $HOME, $GEM_HOME, etc) and that
|
|
175
|
+
# it is able to detect newly installed gems.
|
|
176
|
+
Gem.clear_paths
|
|
177
|
+
setup_bundler_support
|
|
172
178
|
|
|
173
179
|
require File.expand_path('config/environment')
|
|
174
180
|
require 'dispatcher'
|
|
@@ -233,6 +239,7 @@ protected
|
|
|
233
239
|
report_app_init_status(client) do
|
|
234
240
|
$0 = "Passenger ApplicationSpawner: #{@app_root}"
|
|
235
241
|
ENV['RAILS_ENV'] = @environment
|
|
242
|
+
ENV['RACK_ENV'] = @environment
|
|
236
243
|
ENV['RAILS_RELATIVE_URL_ROOT'] = @base_uri
|
|
237
244
|
if defined?(RAILS_ENV)
|
|
238
245
|
Object.send(:remove_const, :RAILS_ENV)
|
|
@@ -245,6 +252,11 @@ protected
|
|
|
245
252
|
if @lower_privilege
|
|
246
253
|
lower_privilege('config/environment.rb', @lowest_user)
|
|
247
254
|
end
|
|
255
|
+
# Make sure RubyGems uses any new environment variable values
|
|
256
|
+
# that have been set now (e.g. $HOME, $GEM_HOME, etc) and that
|
|
257
|
+
# it is able to detect newly installed gems.
|
|
258
|
+
Gem.clear_paths
|
|
259
|
+
setup_bundler_support
|
|
248
260
|
preload_application
|
|
249
261
|
end
|
|
250
262
|
end
|
|
@@ -307,17 +319,28 @@ private
|
|
|
307
319
|
if !defined?(Dispatcher)
|
|
308
320
|
require 'dispatcher'
|
|
309
321
|
end
|
|
322
|
+
# Rails 2.2+ uses application_controller.rb while older versions use application.rb.
|
|
310
323
|
begin
|
|
311
324
|
require_dependency 'application_controller'
|
|
312
|
-
rescue LoadError
|
|
313
|
-
|
|
325
|
+
rescue LoadError => e
|
|
326
|
+
begin
|
|
327
|
+
require_dependency 'application'
|
|
328
|
+
rescue LoadError
|
|
329
|
+
# Considering that most apps these das are written in Rails
|
|
330
|
+
# 2.2+, if application.rb cannot be loaded either then it
|
|
331
|
+
# probably just means that application_controller.rb threw
|
|
332
|
+
# a LoadError. So we raise the original error here; if the
|
|
333
|
+
# app is based on Rails < 2.2 then the error will make less
|
|
334
|
+
# sense but we can only choose one or the other.
|
|
335
|
+
raise e
|
|
336
|
+
end
|
|
314
337
|
end
|
|
315
338
|
|
|
316
339
|
# - No point in preloading the application sources if the garbage collector
|
|
317
340
|
# isn't copy-on-write friendly.
|
|
318
341
|
# - Rails >= 2.2 already preloads application sources by default, so no need
|
|
319
342
|
# to do that again.
|
|
320
|
-
if GC.copy_on_write_friendly? &&
|
|
343
|
+
if GC.copy_on_write_friendly? && !rails_will_preload_app_code?
|
|
321
344
|
['models','controllers','helpers'].each do |section|
|
|
322
345
|
Dir.glob("app/#{section}}/*.rb").each do |file|
|
|
323
346
|
require_dependency canonicalize_path(file)
|
|
@@ -325,11 +348,22 @@ private
|
|
|
325
348
|
end
|
|
326
349
|
end
|
|
327
350
|
end
|
|
351
|
+
|
|
352
|
+
def rails_will_preload_app_code?
|
|
353
|
+
if defined?(Rails::Initializer)
|
|
354
|
+
return ::Rails::Initializer.method_defined?(:load_application_classes)
|
|
355
|
+
else
|
|
356
|
+
return defined?(::Rails3)
|
|
357
|
+
end
|
|
358
|
+
end
|
|
328
359
|
|
|
329
360
|
def handle_spawn_application
|
|
361
|
+
a, b = UNIXSocket.pair
|
|
330
362
|
safe_fork('application', true) do
|
|
331
363
|
begin
|
|
332
|
-
|
|
364
|
+
a.close
|
|
365
|
+
client.close
|
|
366
|
+
start_request_handler(MessageChannel.new(b), true)
|
|
333
367
|
rescue SignalException => e
|
|
334
368
|
if e.message != AbstractRequestHandler::HARD_TERMINATION_SIGNAL &&
|
|
335
369
|
e.message != AbstractRequestHandler::SOFT_TERMINATION_SIGNAL
|
|
@@ -337,6 +371,17 @@ private
|
|
|
337
371
|
end
|
|
338
372
|
end
|
|
339
373
|
end
|
|
374
|
+
|
|
375
|
+
b.close
|
|
376
|
+
worker_channel = MessageChannel.new(a)
|
|
377
|
+
info = worker_channel.read
|
|
378
|
+
owner_pipe = worker_channel.recv_io
|
|
379
|
+
client.write(*info)
|
|
380
|
+
client.send_io(owner_pipe)
|
|
381
|
+
ensure
|
|
382
|
+
a.close if a
|
|
383
|
+
b.close if b && !b.closed?
|
|
384
|
+
owner_pipe.close if owner_pipe
|
|
340
385
|
end
|
|
341
386
|
|
|
342
387
|
# Initialize the request handler and enter its main loop.
|
|
@@ -348,11 +393,18 @@ private
|
|
|
348
393
|
$0 = "Rails: #{@app_root}"
|
|
349
394
|
reader, writer = IO.pipe
|
|
350
395
|
begin
|
|
351
|
-
#
|
|
396
|
+
# Clear or re-establish connection if a connection was established
|
|
352
397
|
# in environment.rb. This prevents us from concurrently
|
|
353
398
|
# accessing the same MySQL connection handle.
|
|
354
|
-
if defined?(::ActiveRecord::Base)
|
|
355
|
-
::ActiveRecord::Base.
|
|
399
|
+
if defined?(::ActiveRecord::Base)
|
|
400
|
+
if ::ActiveRecord::Base.respond_to?(:clear_all_connections!)
|
|
401
|
+
::ActiveRecord::Base.clear_all_connections!
|
|
402
|
+
elsif ::ActiveRecord::Base.respond_to?(:clear_active_connections!)
|
|
403
|
+
::ActiveRecord::Base.clear_active_connections!
|
|
404
|
+
elsif ::ActiveRecord::Base.respond_to?(:connected?) &&
|
|
405
|
+
::ActiveRecord::Base.connected?
|
|
406
|
+
::ActiveRecord::Base.establish_connection
|
|
407
|
+
end
|
|
356
408
|
end
|
|
357
409
|
|
|
358
410
|
reader.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
|
@@ -32,6 +32,7 @@ require 'etc'
|
|
|
32
32
|
require 'fcntl'
|
|
33
33
|
require 'tempfile'
|
|
34
34
|
require 'stringio'
|
|
35
|
+
require 'phusion_passenger/packaging'
|
|
35
36
|
require 'phusion_passenger/exceptions'
|
|
36
37
|
if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
|
|
37
38
|
require 'phusion_passenger/native_support'
|
|
@@ -163,6 +164,59 @@ protected
|
|
|
163
164
|
end
|
|
164
165
|
end
|
|
165
166
|
|
|
167
|
+
def setup_bundler_support
|
|
168
|
+
# Rack::ApplicationSpawner depends on the 'rack' library, but the app
|
|
169
|
+
# might want us to use a bundled version instead of a
|
|
170
|
+
# gem/apt-get/yum/whatever-installed version. Therefore we must setup
|
|
171
|
+
# the correct load paths before requiring 'rack'.
|
|
172
|
+
#
|
|
173
|
+
# The most popular tool for bundling dependencies is Bundler. Bundler
|
|
174
|
+
# works as follows:
|
|
175
|
+
# - If the bundle is locked then a file .bundle/environment.rb exists
|
|
176
|
+
# which will setup the load paths.
|
|
177
|
+
# - If the bundle is not locked then the load paths must be set up by
|
|
178
|
+
# calling Bundler.setup.
|
|
179
|
+
# - Rails 3's boot.rb automatically loads .bundle/environment.rb or
|
|
180
|
+
# calls Bundler.setup if that's not available.
|
|
181
|
+
# - Other Rack apps might not have a boot.rb but we still want to setup
|
|
182
|
+
# Bundler.
|
|
183
|
+
#
|
|
184
|
+
# So the strategy is as follows:
|
|
185
|
+
|
|
186
|
+
# If the Bundler lock environment file exists then load that. If it
|
|
187
|
+
# exists then there's a 99.9% chance that loading it is the correct
|
|
188
|
+
# thing to do.
|
|
189
|
+
if File.exist?('.bundle/environment.rb')
|
|
190
|
+
require File.expand_path('.bundle/environment')
|
|
191
|
+
|
|
192
|
+
# If the Bundler environment file doesn't exist then there are two
|
|
193
|
+
# possibilities:
|
|
194
|
+
# 1. Bundler is not used, in which case we don't have to do anything.
|
|
195
|
+
# 2. Bundler *is* used, but the gems are not locked and we're supposed
|
|
196
|
+
# to call Bundler.setup.
|
|
197
|
+
#
|
|
198
|
+
# The existence of Gemfile indicates whether (2) is true:
|
|
199
|
+
elsif File.exist?('Gemfile')
|
|
200
|
+
# In case of Rails 3, config/boot.rb already calls Bundler.setup.
|
|
201
|
+
# However older versions of Rails don't so loading boot.rb might
|
|
202
|
+
# not be the correct thing to do. To be on the safe side we
|
|
203
|
+
# call Bundler.setup ourselves; if this isn't the correct thing
|
|
204
|
+
# to do after all then there's always the load_path_setup_file
|
|
205
|
+
# option.
|
|
206
|
+
require 'rubygems'
|
|
207
|
+
require 'bundler'
|
|
208
|
+
Bundler.setup
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Bundler might remove Phusion Passenger from the load path in its zealous
|
|
212
|
+
# attempt to un-require RubyGems, so here we put Phusion Passenger back
|
|
213
|
+
# into the load path.
|
|
214
|
+
if $LOAD_PATH.first != LIBDIR
|
|
215
|
+
$LOAD_PATH.unshift(LIBDIR)
|
|
216
|
+
$LOAD_PATH.uniq!
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
166
220
|
# Fork a new process and run the given block inside the child process, just like
|
|
167
221
|
# fork(). Unlike fork(), this method is safe, i.e. there's no way for the child
|
|
168
222
|
# process to escape the block. Any uncaught exceptions in the child process will
|
|
@@ -371,15 +425,7 @@ protected
|
|
|
371
425
|
if uid == 0
|
|
372
426
|
return false
|
|
373
427
|
else
|
|
374
|
-
|
|
375
|
-
# all kinds of stupid reasons. So we ignore any errors
|
|
376
|
-
# raised by initgroups.
|
|
377
|
-
begin
|
|
378
|
-
Process.groups = Process.initgroups(username, gid)
|
|
379
|
-
rescue
|
|
380
|
-
end
|
|
381
|
-
Process::Sys.setgid(gid)
|
|
382
|
-
Process::Sys.setuid(uid)
|
|
428
|
+
NativeSupport.switch_user(username, uid, gid)
|
|
383
429
|
ENV['HOME'] = pw.dir
|
|
384
430
|
return true
|
|
385
431
|
end
|
|
@@ -538,8 +584,8 @@ class IO
|
|
|
538
584
|
# This only works if this IO channel is a Unix socket.
|
|
539
585
|
#
|
|
540
586
|
# Raises SystemCallError if something went wrong.
|
|
541
|
-
def recv_io
|
|
542
|
-
return
|
|
587
|
+
def recv_io(klass = IO)
|
|
588
|
+
return klass.for_fd(PhusionPassenger::NativeSupport.recv_fd(self.fileno))
|
|
543
589
|
end
|
|
544
590
|
end
|
|
545
591
|
|
|
@@ -559,7 +605,6 @@ module Signal
|
|
|
559
605
|
result = Signal.list
|
|
560
606
|
result.delete("ALRM")
|
|
561
607
|
result.delete("VTALRM")
|
|
562
|
-
return result
|
|
563
608
|
when "jruby"
|
|
564
609
|
result = Signal.list
|
|
565
610
|
result.delete("QUIT")
|
|
@@ -567,12 +612,21 @@ module Signal
|
|
|
567
612
|
result.delete("FPE")
|
|
568
613
|
result.delete("KILL")
|
|
569
614
|
result.delete("SEGV")
|
|
570
|
-
result.delete("STOP")
|
|
571
615
|
result.delete("USR1")
|
|
572
|
-
return result
|
|
573
616
|
else
|
|
574
|
-
|
|
617
|
+
result = Signal.list
|
|
575
618
|
end
|
|
619
|
+
|
|
620
|
+
# Don't touch SIGCHLD no matter what! On OS X waitpid() will
|
|
621
|
+
# malfunction if SIGCHLD doesn't have a correct handler.
|
|
622
|
+
result.delete("CLD")
|
|
623
|
+
result.delete("CHLD")
|
|
624
|
+
|
|
625
|
+
# Other stuff that we don't want to trap no matter which
|
|
626
|
+
# Ruby engine.
|
|
627
|
+
result.delete("STOP")
|
|
628
|
+
|
|
629
|
+
return result
|
|
576
630
|
end
|
|
577
631
|
end
|
|
578
632
|
|
|
@@ -582,7 +636,7 @@ end
|
|
|
582
636
|
if RUBY_PLATFORM =~ /freebsd/ || RUBY_PLATFORM =~ /openbsd/ || (RUBY_PLATFORM =~ /darwin/ && RUBY_PLATFORM !~ /universal/)
|
|
583
637
|
require 'socket'
|
|
584
638
|
UNIXSocket.class_eval do
|
|
585
|
-
def recv_io
|
|
639
|
+
def recv_io(klass = IO)
|
|
586
640
|
super
|
|
587
641
|
end
|
|
588
642
|
|