passenger 2.2.2 → 2.2.3
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/DEVELOPERS.TXT +13 -3
- data/Rakefile +42 -33
- data/bin/passenger-install-apache2-module +1 -2
- data/bin/passenger-install-nginx-module +7 -19
- data/bin/passenger-status +64 -15
- data/bin/passenger-stress-test +2 -2
- data/doc/ApplicationPool algorithm.txt +26 -22
- data/doc/Users guide Apache.html +374 -149
- data/doc/Users guide Apache.txt +318 -51
- data/doc/Users guide Nginx.html +13 -13
- data/doc/Users guide Nginx.txt +7 -2
- data/doc/cxxapi/Bucket_8h-source.html +62 -25
- data/doc/cxxapi/Configuration_8h-source.html +343 -326
- data/doc/cxxapi/DirectoryMapper_8h-source.html +12 -12
- data/doc/cxxapi/Hooks_8h-source.html +1 -1
- data/doc/cxxapi/annotated.html +1 -1
- data/doc/cxxapi/classHooks-members.html +1 -1
- data/doc/cxxapi/classHooks.html +1 -1
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +2 -2
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +9 -9
- data/doc/cxxapi/classes.html +1 -1
- data/doc/cxxapi/definitions_8h-source.html +1 -1
- data/doc/cxxapi/files.html +1 -1
- data/doc/cxxapi/functions.html +2 -2
- data/doc/cxxapi/functions_func.html +2 -2
- data/doc/cxxapi/graph_legend.html +1 -1
- data/doc/cxxapi/group__Configuration.html +1 -1
- data/doc/cxxapi/group__Core.html +1 -1
- data/doc/cxxapi/group__Hooks.html +1 -1
- data/doc/cxxapi/group__Support.html +1 -1
- data/doc/cxxapi/main.html +1 -1
- data/doc/cxxapi/modules.html +1 -1
- data/doc/rdoc/classes/ConditionVariable.html +194 -0
- data/doc/rdoc/classes/Exception.html +120 -0
- data/doc/rdoc/classes/GC.html +113 -0
- data/doc/rdoc/classes/IO.html +169 -0
- data/doc/rdoc/classes/PhusionPassenger.html +238 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +153 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +517 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +719 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +97 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +96 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +97 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +96 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +317 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
- data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +154 -0
- data/doc/rdoc/classes/PhusionPassenger/Application.html +283 -0
- data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +172 -0
- data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +145 -0
- data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +175 -0
- data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +141 -0
- data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
- data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +489 -0
- data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +350 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +188 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +194 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +442 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +436 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +155 -0
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +402 -0
- data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +125 -0
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +805 -0
- data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +140 -0
- data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
- data/doc/rdoc/classes/PlatformInfo.html +831 -0
- data/doc/rdoc/classes/RakeExtensions.html +197 -0
- data/doc/rdoc/classes/Signal.html +131 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/DEVELOPERS_TXT.html +255 -0
- data/doc/rdoc/files/README.html +157 -0
- data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +92 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +129 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +131 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +130 -0
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +130 -0
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +127 -0
- data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +134 -0
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +127 -0
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +133 -0
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +127 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +143 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +145 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +127 -0
- data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +161 -0
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +175 -0
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +129 -0
- data/doc/rdoc/files/misc/rake/extensions_rb.html +130 -0
- data/doc/rdoc/fr_class_index.html +90 -0
- data/doc/rdoc/fr_file_index.html +76 -0
- data/doc/rdoc/fr_method_index.html +200 -0
- data/doc/rdoc/index.html +26 -0
- data/doc/rdoc/rdoc-style.css +187 -0
- data/doc/users_guide_snippets/rackup_specifications.txt +2 -8
- data/ext/apache2/Bucket.cpp +71 -38
- data/ext/apache2/Bucket.h +53 -16
- data/ext/apache2/Configuration.cpp +15 -0
- data/ext/apache2/Configuration.h +19 -2
- data/ext/apache2/DirectoryMapper.h +10 -10
- data/ext/apache2/Hooks.cpp +334 -74
- data/ext/boost/mpl/apply.hpp +5 -1
- data/ext/boost/mpl/apply_wrap.hpp +5 -2
- data/ext/boost/mpl/aux_/full_lambda.hpp +5 -1
- data/ext/boost/mpl/bind.hpp +5 -1
- data/ext/common/Application.h +11 -31
- data/ext/common/ApplicationPool.h +2 -1
- data/ext/common/ApplicationPoolServer.h +61 -20
- data/ext/common/ApplicationPoolServerExecutable.cpp +132 -4
- data/ext/common/ApplicationPoolStatusReporter.h +189 -65
- data/ext/common/Base64.cpp +143 -0
- data/ext/common/Base64.h +57 -0
- data/ext/common/CachedFileStat.cpp +25 -82
- data/ext/common/CachedFileStat.h +11 -125
- data/ext/common/CachedFileStat.hpp +243 -0
- data/ext/common/Exceptions.h +13 -0
- data/ext/common/FileChangeChecker.h +209 -0
- data/ext/common/Logging.h +3 -2
- data/ext/common/MessageChannel.h +10 -10
- data/ext/common/PoolOptions.h +72 -5
- data/ext/common/SpawnManager.h +11 -8
- data/ext/common/StandardApplicationPool.h +38 -39
- data/ext/common/StaticString.h +1 -0
- data/ext/common/StringListCreator.h +83 -0
- data/ext/common/SystemTime.h +3 -2
- data/ext/common/Timer.h +88 -0
- data/ext/common/Utils.cpp +161 -42
- data/ext/common/Utils.h +62 -31
- data/ext/common/Version.h +1 -1
- data/ext/nginx/Configuration.c +0 -4
- data/ext/nginx/ContentHandler.c +8 -6
- data/ext/nginx/HelperServer.cpp +45 -55
- data/ext/nginx/HttpStatusExtractor.h +4 -0
- data/ext/nginx/StaticContentHandler.c +25 -5
- data/ext/nginx/config +3 -0
- data/ext/nginx/ngx_http_passenger_module.c +72 -17
- data/ext/nginx/ngx_http_passenger_module.h +2 -2
- data/lib/phusion_passenger/abstract_request_handler.rb +15 -7
- data/lib/phusion_passenger/abstract_server.rb +16 -2
- data/lib/phusion_passenger/admin_tools/control_process.rb +36 -25
- data/lib/phusion_passenger/constants.rb +1 -1
- data/lib/phusion_passenger/dependencies.rb +10 -0
- data/lib/phusion_passenger/platform_info.rb +1 -1
- data/lib/phusion_passenger/rack/application_spawner.rb +21 -2
- data/lib/phusion_passenger/rack/request_handler.rb +10 -0
- data/lib/phusion_passenger/railz/application_spawner.rb +38 -2
- data/lib/phusion_passenger/railz/framework_spawner.rb +26 -28
- data/lib/phusion_passenger/railz/request_handler.rb +5 -1
- data/lib/phusion_passenger/spawn_manager.rb +6 -2
- data/lib/phusion_passenger/utils.rb +79 -27
- data/misc/rake/cplusplus.rb +5 -5
- data/test/ApplicationPoolServerTest.cpp +42 -0
- data/test/ApplicationPoolTest.cpp +255 -267
- data/test/Base64Test.cpp +48 -0
- data/test/CachedFileStatTest.cpp +243 -103
- data/test/FileChangeCheckerTest.cpp +331 -0
- data/test/PoolOptionsTest.cpp +80 -0
- data/test/UtilsTest.cpp +5 -17
- data/test/integration_tests/apache2_tests.rb +15 -4
- data/test/integration_tests/mycook_spec.rb +3 -4
- data/test/oxt/syscall_interruption_test.cpp +2 -14
- data/test/ruby/abstract_server_collection_spec.rb +1 -1
- data/test/ruby/abstract_server_spec.rb +35 -1
- data/test/ruby/rack/application_spawner_spec.rb +23 -6
- data/test/ruby/rails/application_spawner_spec.rb +6 -6
- data/test/ruby/rails/framework_spawner_spec.rb +6 -5
- data/test/ruby/rails/minimal_spawner_spec.rb +19 -0
- data/test/ruby/rails/spawner_error_handling_spec.rb +62 -7
- data/test/ruby/spawn_manager_spec.rb +10 -7
- data/test/ruby/spawn_server_spec.rb +1 -1
- data/test/ruby/utils_spec.rb +193 -20
- data/test/ruby/wsgi/application_spawner_spec.rb +3 -1
- data/test/stub/apache2/httpd.conf.erb +3 -0
- data/test/stub/rack/config.ru +1 -1
- data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +8 -0
- data/test/support/Support.cpp +84 -0
- data/test/support/Support.h +66 -8
- data/test/support/config.rb +14 -2
- data/test/support/test_helper.rb +5 -0
- data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +123 -116
- data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +17 -12
- data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +34 -43
- data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/mock.rb +4 -17
- data/vendor/rack-1.0.0-git/lib/rack/request.rb +3 -9
- data/vendor/rack-1.0.0-git/lib/rack/rewindable_input.rb +2 -0
- data/vendor/rack-1.0.0-git/lib/rack/utils.rb +38 -12
- metadata +231 -186
- data/ext/common/FileChecker.h +0 -112
- data/test/FileCheckerTest.cpp +0 -79
- data/test/stub/minimal-railsapp/README +0 -3
- data/test/stub/minimal-railsapp/config/application.rb +0 -0
- data/test/stub/minimal-railsapp/config/environment.rb +0 -3
- data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -10
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -7
- data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -17
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -8
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -1
- data/test/stub/railsapp/app/controllers/application.rb +0 -12
- data/test/stub/railsapp/app/controllers/bar_controller.rb +0 -5
- data/test/stub/railsapp/app/controllers/bar_controller_1.txt +0 -5
- data/test/stub/railsapp/app/controllers/bar_controller_2.txt +0 -5
- data/test/stub/railsapp/app/controllers/foo_controller.rb +0 -9
- data/test/stub/railsapp/app/helpers/application_helper.rb +0 -3
- data/test/stub/railsapp/config/boot.rb +0 -108
- data/test/stub/railsapp/config/database.yml +0 -19
- data/test/stub/railsapp/config/environment.rb +0 -59
- data/test/stub/railsapp/config/environments/development.rb +0 -18
- data/test/stub/railsapp/config/environments/production.rb +0 -19
- data/test/stub/railsapp/config/initializers/inflections.rb +0 -10
- data/test/stub/railsapp/config/initializers/mime_types.rb +0 -5
- data/test/stub/railsapp/config/routes.rb +0 -35
- data/test/stub/railsapp/public/useless.txt +0 -1
- data/test/stub/railsapp2/app/controllers/application.rb +0 -12
- data/test/stub/railsapp2/app/controllers/foo_controller.rb +0 -5
- data/test/stub/railsapp2/app/helpers/application_helper.rb +0 -3
- data/test/stub/railsapp2/config/boot.rb +0 -108
- data/test/stub/railsapp2/config/database.yml +0 -19
- data/test/stub/railsapp2/config/environment.rb +0 -59
- data/test/stub/railsapp2/config/environments/development.rb +0 -18
- data/test/stub/railsapp2/config/environments/production.rb +0 -19
- data/test/stub/railsapp2/config/initializers/inflections.rb +0 -10
- data/test/stub/railsapp2/config/initializers/mime_types.rb +0 -5
- data/test/stub/railsapp2/config/routes.rb +0 -35
- data/test/stub/railsapp2/public/useless.txt +0 -1
data/ext/common/SystemTime.h
CHANGED
@@ -49,7 +49,7 @@ public:
|
|
49
49
|
* Returns the time since the Epoch, measured in seconds. Or, if a time
|
50
50
|
* was forced, then the forced time is returned instead.
|
51
51
|
*
|
52
|
-
* @throws
|
52
|
+
* @throws TimeRetrievalException Something went wrong while retrieving the time.
|
53
53
|
* @throws boost::thread_interrupted
|
54
54
|
*/
|
55
55
|
static time_t get() {
|
@@ -58,7 +58,8 @@ public:
|
|
58
58
|
} else {
|
59
59
|
time_t ret = syscalls::time(NULL);
|
60
60
|
if (ret == -1) {
|
61
|
-
throw
|
61
|
+
throw TimeRetrievalException(
|
62
|
+
"Unable to retrieve the system time",
|
62
63
|
errno);
|
63
64
|
}
|
64
65
|
return ret;
|
data/ext/common/Timer.h
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - http://www.modrails.com/
|
3
|
+
* Copyright (c) 2008, 2009 Phusion
|
4
|
+
*
|
5
|
+
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
12
|
+
* furnished to do so, subject to the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
15
|
+
* all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
* THE SOFTWARE.
|
24
|
+
*/
|
25
|
+
#ifndef _PASSENGER_TIMER_H_
|
26
|
+
#define _PASSENGER_TIMER_H_
|
27
|
+
|
28
|
+
#include <sys/time.h>
|
29
|
+
|
30
|
+
namespace Passenger {
|
31
|
+
|
32
|
+
/**
|
33
|
+
* A Timer which one can use to check how much time has elapsed since the timer started.
|
34
|
+
* This timer support microseconds-resolution, but the exact resolution depends on the OS
|
35
|
+
* and the hardware.
|
36
|
+
*
|
37
|
+
* @code
|
38
|
+
* Timer timer;
|
39
|
+
* sleep(10);
|
40
|
+
* timer.elapsed(); // => about 10000 (msec)
|
41
|
+
* @endcode
|
42
|
+
*/
|
43
|
+
class Timer {
|
44
|
+
private:
|
45
|
+
struct timeval startTime;
|
46
|
+
public:
|
47
|
+
/**
|
48
|
+
* Creates a new Timer object.
|
49
|
+
*
|
50
|
+
* @param startNow Whether the timer should be started immediately.
|
51
|
+
*/
|
52
|
+
Timer(bool startNow = true) {
|
53
|
+
if (startNow) {
|
54
|
+
start();
|
55
|
+
} else {
|
56
|
+
startTime.tv_sec = 0;
|
57
|
+
startTime.tv_usec = 0;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Start the timer. If the timer was already started, then this will
|
63
|
+
* restart the timer.
|
64
|
+
*/
|
65
|
+
void start() {
|
66
|
+
gettimeofday(&startTime, NULL);
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Checks how much time has elapsed since the timer was last started.
|
71
|
+
*
|
72
|
+
* @pre The timer must have been started.
|
73
|
+
* @return The elapsed time, in miliseconds.
|
74
|
+
*/
|
75
|
+
unsigned long long elapsed() const {
|
76
|
+
struct timeval t;
|
77
|
+
unsigned long long now, beginning;
|
78
|
+
|
79
|
+
gettimeofday(&t, NULL);
|
80
|
+
now = (unsigned long long) t.tv_sec * 1000 + t.tv_usec / 1000;
|
81
|
+
beginning = (unsigned long long) startTime.tv_sec * 1000 + startTime.tv_usec / 1000;
|
82
|
+
return now - beginning;
|
83
|
+
}
|
84
|
+
};
|
85
|
+
|
86
|
+
} // namespace Passenger
|
87
|
+
|
88
|
+
#endif /* _PASSENGER_TIMER_H_ */
|
data/ext/common/Utils.cpp
CHANGED
@@ -23,10 +23,16 @@
|
|
23
23
|
* THE SOFTWARE.
|
24
24
|
*/
|
25
25
|
|
26
|
+
#include <oxt/system_calls.hpp>
|
27
|
+
|
28
|
+
#include <sys/socket.h>
|
29
|
+
#include <sys/types.h>
|
30
|
+
#include <sys/un.h>
|
26
31
|
#include <cassert>
|
27
32
|
#include <libgen.h>
|
28
33
|
#include <pwd.h>
|
29
|
-
#include "CachedFileStat.
|
34
|
+
#include "CachedFileStat.hpp"
|
35
|
+
#include "Exceptions.h"
|
30
36
|
#include "Utils.h"
|
31
37
|
|
32
38
|
#define SPAWN_SERVER_SCRIPT_NAME "passenger-spawn-server"
|
@@ -58,17 +64,17 @@ split(const string &str, char sep, vector<string> &output) {
|
|
58
64
|
}
|
59
65
|
|
60
66
|
bool
|
61
|
-
fileExists(const char *filename,
|
62
|
-
return getFileType(filename,
|
67
|
+
fileExists(const char *filename, CachedFileStat *cstat, unsigned int throttleRate) {
|
68
|
+
return getFileType(filename, cstat, throttleRate) == FT_REGULAR;
|
63
69
|
}
|
64
70
|
|
65
71
|
FileType
|
66
|
-
getFileType(const char *filename,
|
72
|
+
getFileType(const char *filename, CachedFileStat *cstat, unsigned int throttleRate) {
|
67
73
|
struct stat buf;
|
68
74
|
int ret;
|
69
75
|
|
70
|
-
if (
|
71
|
-
ret =
|
76
|
+
if (cstat != NULL) {
|
77
|
+
ret = cstat->stat(filename, &buf, throttleRate);
|
72
78
|
} else {
|
73
79
|
ret = stat(filename, &buf);
|
74
80
|
}
|
@@ -267,6 +273,29 @@ escapeForXml(const string &input) {
|
|
267
273
|
return result;
|
268
274
|
}
|
269
275
|
|
276
|
+
string
|
277
|
+
getProcessUsername() {
|
278
|
+
struct passwd pwd, *result;
|
279
|
+
char strings[1024];
|
280
|
+
int ret;
|
281
|
+
|
282
|
+
result = (struct passwd *) NULL;
|
283
|
+
do {
|
284
|
+
ret = getpwuid_r(getuid(), &pwd, strings, sizeof(strings), &result);
|
285
|
+
} while (ret == -1 && errno == EINTR);
|
286
|
+
if (ret == -1) {
|
287
|
+
result = (struct passwd *) NULL;
|
288
|
+
}
|
289
|
+
|
290
|
+
if (result == (struct passwd *) NULL) {
|
291
|
+
snprintf(strings, sizeof(strings), "UID %lld", (long long) getuid());
|
292
|
+
strings[sizeof(strings) - 1] = '\0';
|
293
|
+
return strings;
|
294
|
+
} else {
|
295
|
+
return result->pw_name;
|
296
|
+
}
|
297
|
+
}
|
298
|
+
|
270
299
|
void
|
271
300
|
determineLowestUserAndGroup(const string &user, uid_t &uid, gid_t &gid) {
|
272
301
|
struct passwd *ent;
|
@@ -407,36 +436,6 @@ createPassengerTempDir(const string &parentDir, bool userSwitching,
|
|
407
436
|
*/
|
408
437
|
makeDirTree(tmpDir + "/backends", "u=wxs,g=,o=");
|
409
438
|
}
|
410
|
-
|
411
|
-
if (geteuid() == 0) {
|
412
|
-
if (userSwitching) {
|
413
|
-
/* If user switching is possible and is on, then each backend
|
414
|
-
* process may be running as a different user. So make the var
|
415
|
-
* directory world-writable.
|
416
|
-
*
|
417
|
-
* The directory is not readable as a security precaution.
|
418
|
-
*/
|
419
|
-
makeDirTree(tmpDir + "/var", "u=wxs,g=wx,o=wx");
|
420
|
-
} else {
|
421
|
-
/* If user switching is off then all backend processes
|
422
|
-
* will be running as lowestUser, so make lowestUser the
|
423
|
-
* owner of the var directory. Only lowestUser may access
|
424
|
-
* the directory.
|
425
|
-
*
|
426
|
-
* The directory is not readble as a security precaution.
|
427
|
-
*/
|
428
|
-
makeDirTree(tmpDir + "/var", "u=wxs,g=,o=", lowestUid, lowestGid);
|
429
|
-
}
|
430
|
-
} else {
|
431
|
-
/* If user switching is not possible then all backend processes will
|
432
|
-
* be running as the same user as the web server. So we'll make the
|
433
|
-
* var subdirectory only accessible by this user. Nobody else
|
434
|
-
* (except root) may access this subdirectory.
|
435
|
-
*
|
436
|
-
* The directory is not readble as a security precaution.
|
437
|
-
*/
|
438
|
-
makeDirTree(tmpDir + "/var", "u=wxs,g=,o=");
|
439
|
-
}
|
440
439
|
}
|
441
440
|
|
442
441
|
void
|
@@ -513,24 +512,144 @@ removeDirTree(const string &path) {
|
|
513
512
|
}
|
514
513
|
|
515
514
|
bool
|
516
|
-
verifyRailsDir(const string &dir,
|
515
|
+
verifyRailsDir(const string &dir, CachedFileStat *cstat, unsigned int throttleRate) {
|
517
516
|
string temp(dir);
|
518
517
|
temp.append("/config/environment.rb");
|
519
|
-
return fileExists(temp.c_str(),
|
518
|
+
return fileExists(temp.c_str(), cstat, throttleRate);
|
520
519
|
}
|
521
520
|
|
522
521
|
bool
|
523
|
-
verifyRackDir(const string &dir,
|
522
|
+
verifyRackDir(const string &dir, CachedFileStat *cstat, unsigned int throttleRate) {
|
524
523
|
string temp(dir);
|
525
524
|
temp.append("/config.ru");
|
526
|
-
return fileExists(temp.c_str(),
|
525
|
+
return fileExists(temp.c_str(), cstat, throttleRate);
|
527
526
|
}
|
528
527
|
|
529
528
|
bool
|
530
|
-
verifyWSGIDir(const string &dir,
|
529
|
+
verifyWSGIDir(const string &dir, CachedFileStat *cstat, unsigned int throttleRate) {
|
531
530
|
string temp(dir);
|
532
531
|
temp.append("/passenger_wsgi.py");
|
533
|
-
return fileExists(temp.c_str(),
|
532
|
+
return fileExists(temp.c_str(), cstat, throttleRate);
|
533
|
+
}
|
534
|
+
|
535
|
+
int
|
536
|
+
createUnixServer(const char *filename, unsigned int backlogSize, bool autoDelete) {
|
537
|
+
struct sockaddr_un addr;
|
538
|
+
int fd, ret;
|
539
|
+
|
540
|
+
if (strlen(filename) > sizeof(addr.sun_path) - 1) {
|
541
|
+
string message = "Cannot create Unix socket '";
|
542
|
+
message.append(filename);
|
543
|
+
message.append("': filename is too long.");
|
544
|
+
throw RuntimeException(message);
|
545
|
+
}
|
546
|
+
|
547
|
+
fd = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
|
548
|
+
if (fd == -1) {
|
549
|
+
throw SystemException("Cannot create a Unix socket file descriptor", errno);
|
550
|
+
}
|
551
|
+
|
552
|
+
addr.sun_family = AF_UNIX;
|
553
|
+
strncpy(addr.sun_path, filename, sizeof(addr.sun_path));
|
554
|
+
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
555
|
+
|
556
|
+
if (autoDelete) {
|
557
|
+
do {
|
558
|
+
ret = unlink(filename);
|
559
|
+
} while (ret == -1 && errno == EINTR);
|
560
|
+
}
|
561
|
+
|
562
|
+
try {
|
563
|
+
ret = syscalls::bind(fd, (const struct sockaddr *) &addr, sizeof(addr));
|
564
|
+
} catch (...) {
|
565
|
+
do {
|
566
|
+
ret = close(fd);
|
567
|
+
} while (ret == -1 && errno == EINTR);
|
568
|
+
throw;
|
569
|
+
}
|
570
|
+
if (ret == -1) {
|
571
|
+
int e = errno;
|
572
|
+
string message = "Cannot bind Unix socket '";
|
573
|
+
message.append(filename);
|
574
|
+
message.append("'");
|
575
|
+
do {
|
576
|
+
ret = close(fd);
|
577
|
+
} while (ret == -1 && errno == EINTR);
|
578
|
+
throw SystemException(message, e);
|
579
|
+
}
|
580
|
+
|
581
|
+
if (backlogSize == 0) {
|
582
|
+
#ifdef SOMAXCONN
|
583
|
+
backlogSize = SOMAXCONN;
|
584
|
+
#else
|
585
|
+
backlogSize = 128;
|
586
|
+
#endif
|
587
|
+
}
|
588
|
+
try {
|
589
|
+
ret = syscalls::listen(fd, backlogSize);
|
590
|
+
} catch (...) {
|
591
|
+
do {
|
592
|
+
ret = close(fd);
|
593
|
+
} while (ret == -1 && errno == EINTR);
|
594
|
+
throw;
|
595
|
+
}
|
596
|
+
if (ret == -1) {
|
597
|
+
int e = errno;
|
598
|
+
string message = "Cannot listen on Unix socket '";
|
599
|
+
message.append(filename);
|
600
|
+
message.append("'");
|
601
|
+
do {
|
602
|
+
ret = close(fd);
|
603
|
+
} while (ret == -1 && errno == EINTR);
|
604
|
+
throw SystemException(message, e);
|
605
|
+
}
|
606
|
+
|
607
|
+
return fd;
|
608
|
+
}
|
609
|
+
|
610
|
+
int
|
611
|
+
connectToUnixServer(const char *filename) {
|
612
|
+
int fd, ret;
|
613
|
+
struct sockaddr_un addr;
|
614
|
+
|
615
|
+
if (strlen(filename) > sizeof(addr.sun_path) - 1) {
|
616
|
+
string message = "Cannot connect to Unix socket '";
|
617
|
+
message.append(filename);
|
618
|
+
message.append("': filename is too long.");
|
619
|
+
throw RuntimeException(message);
|
620
|
+
}
|
621
|
+
|
622
|
+
do {
|
623
|
+
fd = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
|
624
|
+
} while (fd == -1 && errno == EINTR);
|
625
|
+
if (fd == -1) {
|
626
|
+
throw SystemException("Cannot create a Unix socket file descriptor", errno);
|
627
|
+
}
|
628
|
+
|
629
|
+
addr.sun_family = AF_UNIX;
|
630
|
+
strncpy(addr.sun_path, filename, sizeof(addr.sun_path));
|
631
|
+
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
632
|
+
|
633
|
+
try {
|
634
|
+
ret = syscalls::connect(fd, (const sockaddr *) &addr, sizeof(addr));
|
635
|
+
} catch (...) {
|
636
|
+
do {
|
637
|
+
ret = close(fd);
|
638
|
+
} while (ret == -1 && errno == EINTR);
|
639
|
+
throw;
|
640
|
+
}
|
641
|
+
if (ret == -1) {
|
642
|
+
int e = errno;
|
643
|
+
string message("Cannot connect to Unix socket '");
|
644
|
+
message.append(filename);
|
645
|
+
message.append("'");
|
646
|
+
do {
|
647
|
+
ret = close(fd);
|
648
|
+
} while (ret == -1 && errno == EINTR);
|
649
|
+
throw SystemException(message, e);
|
650
|
+
}
|
651
|
+
|
652
|
+
return fd;
|
534
653
|
}
|
535
654
|
|
536
655
|
} // namespace Passenger
|
data/ext/common/Utils.h
CHANGED
@@ -40,13 +40,13 @@
|
|
40
40
|
#include <unistd.h>
|
41
41
|
#include "Exceptions.h"
|
42
42
|
|
43
|
-
typedef struct CachedMultiFileStat CachedMultiFileStat;
|
44
|
-
|
45
43
|
namespace Passenger {
|
46
44
|
|
47
45
|
using namespace std;
|
48
46
|
using namespace boost;
|
49
47
|
|
48
|
+
typedef struct CachedFileStat CachedFileStat;
|
49
|
+
|
50
50
|
/** Enumeration which indicates what kind of file a file is. */
|
51
51
|
typedef enum {
|
52
52
|
/** The file doesn't exist. */
|
@@ -158,31 +158,34 @@ void split(const string &str, char sep, vector<string> &output);
|
|
158
158
|
* Check whether the specified file exists.
|
159
159
|
*
|
160
160
|
* @param filename The filename to check.
|
161
|
-
* @param
|
162
|
-
* @param throttleRate A throttle rate for
|
161
|
+
* @param cstat A CachedFileStat object, if you want to use cached statting.
|
162
|
+
* @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
|
163
163
|
* @return Whether the file exists.
|
164
164
|
* @throws FileSystemException Unable to check because of a filesystem error.
|
165
|
+
* @throws TimeRetrievalException
|
166
|
+
* @throws boost::thread_interrupted
|
165
167
|
* @ingroup Support
|
166
168
|
*/
|
167
|
-
bool fileExists(const char *filename,
|
169
|
+
bool fileExists(const char *filename, CachedFileStat *cstat = 0,
|
168
170
|
unsigned int throttleRate = 0);
|
169
171
|
|
170
172
|
/**
|
171
173
|
* Check whether 'filename' exists and what kind of file it is.
|
172
174
|
*
|
173
175
|
* @param filename The filename to check.
|
174
|
-
* @param mstat A
|
175
|
-
* @param throttleRate A throttle rate for
|
176
|
+
* @param mstat A CachedFileStat object, if you want to use cached statting.
|
177
|
+
* @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
|
176
178
|
* @return The file type.
|
177
179
|
* @throws FileSystemException Unable to check because of a filesystem error.
|
180
|
+
* @throws TimeRetrievalException
|
181
|
+
* @throws boost::thread_interrupted
|
178
182
|
* @ingroup Support
|
179
183
|
*/
|
180
|
-
FileType getFileType(const char *filename,
|
184
|
+
FileType getFileType(const char *filename, CachedFileStat *cstat = 0,
|
181
185
|
unsigned int throttleRate = 0);
|
182
186
|
|
183
187
|
/**
|
184
188
|
* Find the location of the Passenger spawn server script.
|
185
|
-
* If passengerRoot is given, t T
|
186
189
|
*
|
187
190
|
* @param passengerRoot The Passenger root folder. If NULL is given, then
|
188
191
|
* the spawn server is found by scanning $PATH. For security reasons,
|
@@ -246,6 +249,13 @@ string extractDirName(const string &path);
|
|
246
249
|
*/
|
247
250
|
string escapeForXml(const string &input);
|
248
251
|
|
252
|
+
/**
|
253
|
+
* Returns the username of the user that the current process is running as.
|
254
|
+
* If the user has no associated username, then the "UID xxxx" is returned,
|
255
|
+
* where xxxx is the current UID.
|
256
|
+
*/
|
257
|
+
string getProcessUsername();
|
258
|
+
|
249
259
|
/**
|
250
260
|
* Given a username that's supposed to be the "lowest user" in the user switching mechanism,
|
251
261
|
* checks whether this username exists. If so, this users's UID and GID will be stored into
|
@@ -308,8 +318,6 @@ void setPassengerTempDir(const string &dir);
|
|
308
318
|
* about a running Phusion Passenger instance.
|
309
319
|
* - backends - for storing Unix sockets created by backend processes.
|
310
320
|
* - master - for storing files such as the Passenger HelperServer socket.
|
311
|
-
* - var - for storing all other kinds of temp files that the backend processes
|
312
|
-
* create.
|
313
321
|
*
|
314
322
|
* If a (sub)directory already exists, then it will not result in an error.
|
315
323
|
*
|
@@ -359,7 +367,7 @@ void createPassengerTempDir(const string &parentDir, bool userSwitching,
|
|
359
367
|
* @throws SystemException Something went wrong.
|
360
368
|
* @throws FileSystemException Something went wrong.
|
361
369
|
*/
|
362
|
-
void makeDirTree(const string &path, const char *mode = "u=rwx,g=,o=", uid_t owner = -1, gid_t group = -1);
|
370
|
+
void makeDirTree(const string &path, const char *mode = "u=rwx,g=,o=", uid_t owner = (uid_t) -1, gid_t group = (gid_t) -1);
|
363
371
|
|
364
372
|
/**
|
365
373
|
* Remove an entire directory tree recursively.
|
@@ -372,38 +380,69 @@ void removeDirTree(const string &path);
|
|
372
380
|
* Check whether the specified directory is a valid Ruby on Rails
|
373
381
|
* application root directory.
|
374
382
|
*
|
375
|
-
* @param
|
376
|
-
* @param throttleRate A throttle rate for
|
383
|
+
* @param cstat A CachedFileStat object, if you want to use cached statting.
|
384
|
+
* @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
|
377
385
|
* @throws FileSystemException Unable to check because of a system error.
|
386
|
+
* @throws TimeRetrievalException
|
387
|
+
* @throws boost::thread_interrupted
|
378
388
|
* @ingroup Support
|
379
389
|
*/
|
380
|
-
bool verifyRailsDir(const string &dir,
|
390
|
+
bool verifyRailsDir(const string &dir, CachedFileStat *cstat = 0,
|
381
391
|
unsigned int throttleRate = 0);
|
382
392
|
|
383
393
|
/**
|
384
394
|
* Check whether the specified directory is a valid Rack application
|
385
395
|
* root directory.
|
386
396
|
*
|
387
|
-
* @param
|
388
|
-
* @param throttleRate A throttle rate for
|
397
|
+
* @param cstat A CachedFileStat object, if you want to use cached statting.
|
398
|
+
* @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
|
389
399
|
* @throws FileSystemException Unable to check because of a filesystem error.
|
400
|
+
* @throws TimeRetrievalException
|
401
|
+
* @throws boost::thread_interrupted
|
390
402
|
* @ingroup Support
|
391
403
|
*/
|
392
|
-
bool verifyRackDir(const string &dir,
|
404
|
+
bool verifyRackDir(const string &dir, CachedFileStat *cstat = 0,
|
393
405
|
unsigned int throttleRate = 0);
|
394
406
|
|
395
407
|
/**
|
396
408
|
* Check whether the specified directory is a valid WSGI application
|
397
409
|
* root directory.
|
398
410
|
*
|
399
|
-
* @param
|
400
|
-
* @param throttleRate A throttle rate for
|
411
|
+
* @param cstat A CachedFileStat object, if you want to use cached statting.
|
412
|
+
* @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
|
401
413
|
* @throws FileSystemException Unable to check because of a filesystem error.
|
414
|
+
* @throws TimeRetrievalException
|
415
|
+
* @throws boost::thread_interrupted
|
402
416
|
* @ingroup Support
|
403
417
|
*/
|
404
|
-
bool verifyWSGIDir(const string &dir,
|
418
|
+
bool verifyWSGIDir(const string &dir, CachedFileStat *cstat = 0,
|
405
419
|
unsigned int throttleRate = 0);
|
406
420
|
|
421
|
+
/**
|
422
|
+
* Create a new Unix server socket which is bounded to <tt>filename</tt>.
|
423
|
+
*
|
424
|
+
* @param filename The filename to bind the socket to.
|
425
|
+
* @param backlogSize The size of the socket's backlog. Specify 0 to use the
|
426
|
+
* platform's maximum allowed backlog size.
|
427
|
+
* @param autoDelete Whether <tt>filename</tt> should be deleted, if it already exists.
|
428
|
+
* @return The file descriptor of the newly created Unix server socket.
|
429
|
+
* @throws RuntimeException Something went wrong.
|
430
|
+
* @throws SystemException Something went wrong while creating the Unix server socket.
|
431
|
+
* @throws boost::thread_interrupted A system call has been interrupted.
|
432
|
+
*/
|
433
|
+
int createUnixServer(const char *filename, unsigned int backlogSize = 0, bool autoDelete = true);
|
434
|
+
|
435
|
+
/**
|
436
|
+
* Connect to a Unix server socket at <tt>filename</tt>.
|
437
|
+
*
|
438
|
+
* @param filename The filename of the socket to connect to.
|
439
|
+
* @return The file descriptor of the connected client socket.
|
440
|
+
* @throws RuntimeException Something went wrong.
|
441
|
+
* @throws SystemException Something went wrong while connecting to the Unix server.
|
442
|
+
* @throws boost::thread_interrupted A system call has been interrupted.
|
443
|
+
*/
|
444
|
+
int connectToUnixServer(const char *filename);
|
445
|
+
|
407
446
|
/**
|
408
447
|
* Represents a buffered upload file.
|
409
448
|
*
|
@@ -419,11 +458,11 @@ public:
|
|
419
458
|
*
|
420
459
|
* @throws SystemException Something went wrong.
|
421
460
|
*/
|
422
|
-
BufferedUpload(const char *identifier = "temp") {
|
461
|
+
BufferedUpload(const string &dir, const char *identifier = "temp") {
|
423
462
|
char templ[PATH_MAX];
|
424
463
|
int fd;
|
425
464
|
|
426
|
-
snprintf(templ, sizeof(templ), "%s/%s.XXXXXX",
|
465
|
+
snprintf(templ, sizeof(templ), "%s/%s.XXXXXX", dir.c_str(), identifier);
|
427
466
|
templ[sizeof(templ) - 1] = '\0';
|
428
467
|
fd = mkstemp(templ);
|
429
468
|
if (fd == -1) {
|
@@ -450,14 +489,6 @@ public:
|
|
450
489
|
~BufferedUpload() {
|
451
490
|
fclose(handle);
|
452
491
|
}
|
453
|
-
|
454
|
-
/**
|
455
|
-
* Returns the directory in which upload buffer files are stored.
|
456
|
-
* This is a subdirectory of the directory returned by getPassengerTempDir().
|
457
|
-
*/
|
458
|
-
static string getDir() {
|
459
|
-
return getPassengerTempDir() + "/webserver_private";
|
460
|
-
}
|
461
492
|
};
|
462
493
|
|
463
494
|
} // namespace Passenger
|