colouringcode-passenger 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|