passenger 4.0.5 → 4.0.6
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.tar.gz.asc +7 -7
- data/.travis.yml +1 -2
- data/CONTRIBUTING.md +20 -5
- data/CONTRIBUTORS +67 -0
- data/LICENSE +1 -1
- data/NEWS +48 -0
- data/Rakefile +2 -2
- data/bin/passenger-config +18 -0
- data/bin/passenger-install-apache2-module +2 -0
- data/bin/passenger-install-nginx-module +11 -12
- data/bin/passenger-memory-stats +2 -0
- data/bin/passenger-status +152 -69
- data/build/agents.rb +1 -5
- data/build/basics.rb +26 -13
- data/build/cplusplus_support.rb +9 -0
- data/build/debian.rb +129 -0
- data/build/documentation.rb +6 -2
- data/build/integration_tests.rb +13 -2
- data/build/misc.rb +16 -0
- data/build/packaging.rb +67 -51
- data/build/preprocessor.rb +314 -0
- data/build/test_basics.rb +1 -0
- data/{debian → debian.template}/README.Debian +0 -0
- data/{debian → debian.template}/changelog +131 -0
- data/debian.template/compat +1 -0
- data/debian.template/control +71 -0
- data/debian.template/copyright +385 -0
- data/debian.template/libapache2-mod-passenger.install +3 -0
- data/{debian → debian.template}/libapache2-mod-passenger.postinst +0 -0
- data/{debian → debian.template}/libapache2-mod-passenger.prerm +0 -0
- data/debian.template/locations.ini +12 -0
- data/debian.template/passenger.conf +4 -0
- data/{debian → debian.template}/passenger.load +0 -0
- data/debian.template/patches/series +0 -0
- data/debian.template/repack.sh +42 -0
- data/debian.template/ruby-passenger-dev.install +3 -0
- data/debian.template/ruby-passenger-doc.install +2 -0
- data/debian.template/ruby-passenger.docs +4 -0
- data/debian.template/ruby-passenger.install +11 -0
- data/debian.template/ruby-passenger.manpages +4 -0
- data/debian.template/rules.template +35 -0
- data/debian.template/source/format +1 -0
- data/debian.template/watch +3 -0
- data/dev/run_travis.sh +46 -46
- data/doc/Architectural overview.html +2 -2
- data/doc/Packaging.html +27 -18
- data/doc/Packaging.txt.md +27 -18
- data/doc/Security of user switching support.html +2 -2
- data/doc/Users guide Apache.html +881 -95
- data/doc/Users guide Apache.idmap.txt +48 -6
- data/doc/Users guide Apache.txt +13 -1
- data/doc/Users guide Nginx.html +1063 -190
- data/doc/Users guide Nginx.idmap.txt +89 -45
- data/doc/Users guide Nginx.txt +45 -0
- data/doc/Users guide Standalone.html +7 -7
- data/doc/users_guide_snippets/alternative_for_flying_passenger.txt +1 -0
- data/doc/users_guide_snippets/environment_variables.txt +221 -0
- data/doc/users_guide_snippets/installation.txt +66 -17
- data/doc/users_guide_snippets/support_information.txt +3 -3
- data/doc/users_guide_snippets/tips.txt +352 -40
- data/ext/common/Account.h +4 -3
- data/ext/common/AccountsDatabase.h +6 -6
- data/ext/common/AgentsStarter.h +1 -13
- data/ext/common/ApplicationPool2/DirectSpawner.h +4 -4
- data/ext/common/ApplicationPool2/DummySpawner.h +1 -1
- data/ext/common/ApplicationPool2/Group.h +9 -4
- data/ext/common/ApplicationPool2/Implementation.cpp +6 -1
- data/ext/common/ApplicationPool2/Options.h +65 -37
- data/ext/common/ApplicationPool2/Pool.h +91 -41
- data/ext/common/ApplicationPool2/Process.h +6 -6
- data/ext/common/ApplicationPool2/SmartSpawner.h +14 -14
- data/ext/common/ApplicationPool2/Socket.h +1 -1
- data/ext/common/ApplicationPool2/Spawner.h +24 -16
- data/ext/common/ApplicationPool2/SpawnerFactory.h +9 -1
- data/ext/common/ApplicationPool2/SuperGroup.h +1 -1
- data/ext/common/Constants.h +1 -1
- data/ext/common/Logging.cpp +12 -7
- data/ext/common/MessageServer.h +7 -12
- data/ext/common/MultiLibeio.cpp +5 -5
- data/ext/common/ResourceLocator.h +2 -6
- data/ext/common/ServerInstanceDir.h +37 -10
- data/ext/common/UnionStation.h +10 -10
- data/ext/common/Utils.cpp +30 -4
- data/ext/common/Utils.h +7 -0
- data/ext/common/Utils/BlockingQueue.h +2 -2
- data/ext/common/Utils/Lock.h +2 -2
- data/ext/common/Utils/MessagePassing.h +2 -2
- data/ext/common/Utils/Timer.h +4 -4
- data/ext/common/agents/HelperAgent/AgentOptions.h +2 -0
- data/ext/common/agents/HelperAgent/Main.cpp +57 -16
- data/ext/common/agents/HelperAgent/RequestHandler.h +4 -1
- data/ext/common/agents/LoggingAgent/AdminController.h +91 -0
- data/ext/common/agents/LoggingAgent/LoggingServer.h +46 -29
- data/ext/common/agents/LoggingAgent/Main.cpp +43 -16
- data/ext/common/agents/LoggingAgent/RemoteSender.h +7 -7
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +11 -11
- data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +3 -1
- data/ext/common/agents/Watchdog/Main.cpp +62 -0
- data/ext/libeio/config.guess +206 -167
- data/ext/libeio/config.sub +142 -68
- data/ext/libev/config.guess +304 -290
- data/ext/libev/config.sub +198 -77
- data/ext/nginx/config +4 -0
- data/ext/nginx/ngx_http_passenger_module.c +1 -0
- data/ext/oxt/implementation.cpp +4 -4
- data/lib/phusion_passenger.rb +14 -5
- data/lib/phusion_passenger/abstract_installer.rb +41 -0
- data/lib/phusion_passenger/admin_tools/server_instance.rb +48 -39
- data/lib/phusion_passenger/message_client.rb +31 -7
- data/lib/phusion_passenger/native_support.rb +35 -12
- data/lib/phusion_passenger/packaging.rb +16 -2
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +6 -31
- data/lib/phusion_passenger/platform_info/operating_system.rb +1 -1
- data/lib/phusion_passenger/preloader_shared_helpers.rb +3 -1
- data/lib/phusion_passenger/request_handler.rb +1 -1
- data/lib/phusion_passenger/standalone/command.rb +6 -6
- data/lib/phusion_passenger/standalone/main.rb +23 -8
- data/lib/phusion_passenger/standalone/package_runtime_command.rb +9 -5
- data/lib/phusion_passenger/standalone/runtime_installer.rb +9 -10
- data/lib/phusion_passenger/standalone/start_command.rb +20 -4
- data/resources/templates/installer_common/freebsd9_broken_cxx_runtime.txt.erb +19 -0
- data/resources/templates/installer_common/low_amount_of_memory_warning.txt.erb +22 -0
- data/resources/templates/standalone/config.erb +3 -2
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +4 -4
- data/test/cxx/ApplicationPool2/PoolTest.cpp +1 -1
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +7 -7
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +9 -9
- data/test/cxx/EventedBufferedInputTest.cpp +17 -17
- data/test/cxx/RequestHandlerTest.cpp +5 -5
- data/test/cxx/ServerInstanceDirTest.cpp +3 -1
- data/test/cxx/TestSupport.h +4 -4
- data/test/cxx/UnionStationTest.cpp +3 -1
- data/test/cxx/UtilsTest.cpp +2 -0
- data/test/integration_tests/apache2_tests.rb +2 -2
- data/test/integration_tests/native_packaging_spec.rb +170 -0
- data/test/ruby/spec_helper.rb +0 -1
- data/test/stub/apache2/httpd.conf.erb +1 -1
- data/test/stub/nginx/nginx.conf.erb +1 -0
- data/test/support/apache2_controller.rb +1 -1
- data/test/support/placebo-preloader.rb +1 -1
- data/test/support/test_helper.rb +5 -2
- metadata +32 -26
- metadata.gz.asc +7 -7
- data/debian/compat +0 -1
- data/debian/control +0 -49
- data/debian/copyright +0 -20
- data/debian/libapache2-mod-passenger.install +0 -1
- data/debian/passenger-common.install +0 -4
- data/debian/passenger.conf +0 -4
- data/debian/prerm +0 -2
- data/debian/rules +0 -37
- data/debian/watch +0 -3
- data/dev/googlecode_upload.py +0 -265
- data/ext/common/agents/HelperAgent/BacktracesServer.h +0 -60
- data/resources/templates/nginx/not_available_when_natively_packaged.txt.erb +0 -8
- data/test/stub/rails3.1/app/assets/javascripts/application.js +0 -9
- data/test/stub/rails3.2/app/assets/javascripts/application.js +0 -15
- data/test/stub/rails_apps/2.3/mycook/public/javascripts/application.js +0 -2
- data/test/stub/rails_apps/2.3/mycook/public/javascripts/controls.js +0 -963
- data/test/stub/rails_apps/2.3/mycook/public/javascripts/dragdrop.js +0 -973
- data/test/stub/rails_apps/2.3/mycook/public/javascripts/effects.js +0 -1128
- data/test/stub/rails_apps/2.3/mycook/public/javascripts/prototype.js +0 -4320
@@ -384,25 +384,25 @@ public:
|
|
384
384
|
|
385
385
|
// Thread-safe.
|
386
386
|
bool isAlive() const {
|
387
|
-
lock_guard<boost::mutex> lock(lifetimeSyncher);
|
387
|
+
boost::lock_guard<boost::mutex> lock(lifetimeSyncher);
|
388
388
|
return lifeStatus == ALIVE;
|
389
389
|
}
|
390
390
|
|
391
391
|
// Thread-safe.
|
392
392
|
bool hasTriggeredShutdown() const {
|
393
|
-
lock_guard<boost::mutex> lock(lifetimeSyncher);
|
393
|
+
boost::lock_guard<boost::mutex> lock(lifetimeSyncher);
|
394
394
|
return lifeStatus == SHUTDOWN_TRIGGERED;
|
395
395
|
}
|
396
396
|
|
397
397
|
// Thread-safe.
|
398
398
|
bool isDead() const {
|
399
|
-
lock_guard<boost::mutex> lock(lifetimeSyncher);
|
399
|
+
boost::lock_guard<boost::mutex> lock(lifetimeSyncher);
|
400
400
|
return lifeStatus == DEAD;
|
401
401
|
}
|
402
402
|
|
403
403
|
// Thread-safe.
|
404
404
|
LifeStatus getLifeStatus() const {
|
405
|
-
lock_guard<boost::mutex> lock(lifetimeSyncher);
|
405
|
+
boost::lock_guard<boost::mutex> lock(lifetimeSyncher);
|
406
406
|
return lifeStatus;
|
407
407
|
}
|
408
408
|
|
@@ -413,7 +413,7 @@ public:
|
|
413
413
|
void triggerShutdown() {
|
414
414
|
assert(canTriggerShutdown());
|
415
415
|
{
|
416
|
-
lock_guard<boost::mutex> lock(lifetimeSyncher);
|
416
|
+
boost::lock_guard<boost::mutex> lock(lifetimeSyncher);
|
417
417
|
assert(lifeStatus == ALIVE);
|
418
418
|
lifeStatus = SHUTDOWN_TRIGGERED;
|
419
419
|
shutdownStartTime = SystemTime::get();
|
@@ -447,7 +447,7 @@ public:
|
|
447
447
|
}
|
448
448
|
}
|
449
449
|
|
450
|
-
lock_guard<boost::mutex> lock(lifetimeSyncher);
|
450
|
+
boost::lock_guard<boost::mutex> lock(lifetimeSyncher);
|
451
451
|
lifeStatus = DEAD;
|
452
452
|
}
|
453
453
|
|
@@ -110,9 +110,9 @@ private:
|
|
110
110
|
string agentsDir = resourceLocator.getAgentsDir();
|
111
111
|
vector<string> command;
|
112
112
|
|
113
|
-
if (options
|
114
|
-
command.push_back(
|
115
|
-
command.push_back(
|
113
|
+
if (shouldLoadShellEnvvars(options, preparation)) {
|
114
|
+
command.push_back(preparation.shell);
|
115
|
+
command.push_back(preparation.shell);
|
116
116
|
command.push_back("-lc");
|
117
117
|
command.push_back("exec \"$@\"");
|
118
118
|
command.push_back("SpawnPreparerShell");
|
@@ -279,7 +279,7 @@ private:
|
|
279
279
|
}
|
280
280
|
this->adminSocket = adminSocket.second;
|
281
281
|
{
|
282
|
-
lock_guard<boost::mutex> l(simpleFieldSyncher);
|
282
|
+
boost::lock_guard<boost::mutex> l(simpleFieldSyncher);
|
283
283
|
this->pid = pid;
|
284
284
|
}
|
285
285
|
|
@@ -324,7 +324,7 @@ private:
|
|
324
324
|
syscalls::unlink(filename.c_str());
|
325
325
|
}
|
326
326
|
{
|
327
|
-
lock_guard<boost::mutex> l(simpleFieldSyncher);
|
327
|
+
boost::lock_guard<boost::mutex> l(simpleFieldSyncher);
|
328
328
|
pid = -1;
|
329
329
|
}
|
330
330
|
socketAddress.clear();
|
@@ -342,7 +342,7 @@ private:
|
|
342
342
|
|
343
343
|
vector<string> args;
|
344
344
|
vector<string>::const_iterator it, end;
|
345
|
-
details.options->toVector(args, resourceLocator);
|
345
|
+
details.options->toVector(args, resourceLocator, Options::SPAWN_OPTIONS);
|
346
346
|
for (it = args.begin(); it != args.end(); it++) {
|
347
347
|
const string &key = *it;
|
348
348
|
it++;
|
@@ -615,7 +615,7 @@ private:
|
|
615
615
|
vector<string>::const_iterator it;
|
616
616
|
|
617
617
|
writeExact(fd, "spawn\n", &timeout);
|
618
|
-
options.toVector(args, resourceLocator);
|
618
|
+
options.toVector(args, resourceLocator, Options::SPAWN_OPTIONS);
|
619
619
|
for (it = args.begin(); it != args.end(); it++) {
|
620
620
|
const string &key = *it;
|
621
621
|
it++;
|
@@ -722,7 +722,7 @@ public:
|
|
722
722
|
}
|
723
723
|
|
724
724
|
virtual ~SmartSpawner() {
|
725
|
-
lock_guard<boost::mutex> l(syncher);
|
725
|
+
boost::lock_guard<boost::mutex> l(syncher);
|
726
726
|
stopPreloader();
|
727
727
|
}
|
728
728
|
|
@@ -735,11 +735,11 @@ public:
|
|
735
735
|
possiblyRaiseInternalError(options);
|
736
736
|
|
737
737
|
{
|
738
|
-
lock_guard<boost::mutex> l(simpleFieldSyncher);
|
738
|
+
boost::lock_guard<boost::mutex> l(simpleFieldSyncher);
|
739
739
|
m_lastUsed = SystemTime::getUsec();
|
740
740
|
}
|
741
741
|
UPDATE_TRACE_POINT();
|
742
|
-
lock_guard<boost::mutex> l(syncher);
|
742
|
+
boost::lock_guard<boost::mutex> l(syncher);
|
743
743
|
if (!preloaderStarted()) {
|
744
744
|
UPDATE_TRACE_POINT();
|
745
745
|
startPreloader();
|
@@ -779,20 +779,20 @@ public:
|
|
779
779
|
virtual void cleanup() {
|
780
780
|
TRACE_POINT();
|
781
781
|
{
|
782
|
-
lock_guard<boost::mutex> l(simpleFieldSyncher);
|
782
|
+
boost::lock_guard<boost::mutex> l(simpleFieldSyncher);
|
783
783
|
m_lastUsed = SystemTime::getUsec();
|
784
784
|
}
|
785
|
-
lock_guard<boost::mutex> lock(syncher);
|
785
|
+
boost::lock_guard<boost::mutex> lock(syncher);
|
786
786
|
stopPreloader();
|
787
787
|
}
|
788
788
|
|
789
789
|
virtual unsigned long long lastUsed() const {
|
790
|
-
lock_guard<boost::mutex> lock(simpleFieldSyncher);
|
790
|
+
boost::lock_guard<boost::mutex> lock(simpleFieldSyncher);
|
791
791
|
return m_lastUsed;
|
792
792
|
}
|
793
793
|
|
794
794
|
pid_t getPreloaderPid() const {
|
795
|
-
lock_guard<boost::mutex> lock(simpleFieldSyncher);
|
795
|
+
boost::lock_guard<boost::mutex> lock(simpleFieldSyncher);
|
796
796
|
return pid;
|
797
797
|
}
|
798
798
|
};
|
@@ -145,7 +145,7 @@ public:
|
|
145
145
|
* Failure to do so will result in a resource leak.
|
146
146
|
*/
|
147
147
|
Connection checkoutConnection() {
|
148
|
-
lock_guard<boost::mutex> l(connectionPoolLock);
|
148
|
+
boost::lock_guard<boost::mutex> l(connectionPoolLock);
|
149
149
|
|
150
150
|
if (!idleConnections.empty()) {
|
151
151
|
Connection connection = idleConnections.back();
|
@@ -143,7 +143,7 @@ protected:
|
|
143
143
|
}
|
144
144
|
} else {
|
145
145
|
{
|
146
|
-
lock_guard<boost::mutex> l(dataSyncher);
|
146
|
+
boost::lock_guard<boost::mutex> l(dataSyncher);
|
147
147
|
data.append(buf, ret);
|
148
148
|
}
|
149
149
|
UPDATE_TRACE_POINT();
|
@@ -200,13 +200,13 @@ protected:
|
|
200
200
|
thr->interrupt_and_join();
|
201
201
|
delete thr;
|
202
202
|
thr = NULL;
|
203
|
-
lock_guard<boost::mutex> l(dataSyncher);
|
203
|
+
boost::lock_guard<boost::mutex> l(dataSyncher);
|
204
204
|
return data;
|
205
205
|
}
|
206
206
|
|
207
207
|
void appendToBuffer(const StaticString &dataToAdd) {
|
208
208
|
TRACE_POINT();
|
209
|
-
lock_guard<boost::mutex> l(dataSyncher);
|
209
|
+
boost::lock_guard<boost::mutex> l(dataSyncher);
|
210
210
|
data.append(dataToAdd.data(), dataToAdd.size());
|
211
211
|
}
|
212
212
|
};
|
@@ -222,19 +222,18 @@ protected:
|
|
222
222
|
string path;
|
223
223
|
|
224
224
|
DebugDir(uid_t uid, gid_t gid) {
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
path.append(pointerToIntString(this));
|
229
|
-
|
230
|
-
if (syscalls::mkdir(path.c_str(), 0700) == -1) {
|
225
|
+
char buf[PATH_MAX] = "/tmp/passenger.spawn-debug.XXXXXXXXXX";
|
226
|
+
const char *result = mkdtemp(buf);
|
227
|
+
if (result == NULL) {
|
231
228
|
int e = errno;
|
232
|
-
throw
|
233
|
-
|
229
|
+
throw SystemException("Cannot create a temporary directory "
|
230
|
+
"in the format of '/tmp/passenger-spawn-debug.XXX'", e);
|
231
|
+
} else {
|
232
|
+
path = result;
|
233
|
+
this_thread::disable_interruption di;
|
234
|
+
this_thread::disable_syscall_interruption dsi;
|
235
|
+
syscalls::chown(result, uid, gid);
|
234
236
|
}
|
235
|
-
this_thread::disable_interruption di;
|
236
|
-
this_thread::disable_syscall_interruption dsi;
|
237
|
-
syscalls::chown(path.c_str(), uid, gid);
|
238
237
|
}
|
239
238
|
|
240
239
|
~DebugDir() {
|
@@ -391,7 +390,7 @@ private:
|
|
391
390
|
|
392
391
|
vector<string> args;
|
393
392
|
vector<string>::const_iterator it, end;
|
394
|
-
details.options->toVector(args, resourceLocator);
|
393
|
+
details.options->toVector(args, resourceLocator, Options::SPAWN_OPTIONS);
|
395
394
|
for (it = args.begin(); it != args.end(); it++) {
|
396
395
|
const string &key = *it;
|
397
396
|
it++;
|
@@ -740,7 +739,7 @@ protected:
|
|
740
739
|
}
|
741
740
|
}
|
742
741
|
}
|
743
|
-
|
742
|
+
|
744
743
|
SpawnPreparationInfo prepareSpawn(const Options &options) const {
|
745
744
|
TRACE_POINT();
|
746
745
|
SpawnPreparationInfo info;
|
@@ -925,6 +924,15 @@ protected:
|
|
925
924
|
|
926
925
|
assert(info.appRootPathsInsideChroot.back() == info.appRootInsideChroot);
|
927
926
|
}
|
927
|
+
|
928
|
+
bool shouldLoadShellEnvvars(const Options &options, const SpawnPreparationInfo &preparation) const {
|
929
|
+
if (options.loadShellEnvvars) {
|
930
|
+
string shellName = extractBaseName(preparation.shell);
|
931
|
+
return shellName == "bash" || shellName == "zsh" || shellName == "ksh";
|
932
|
+
} else {
|
933
|
+
return false;
|
934
|
+
}
|
935
|
+
}
|
928
936
|
|
929
937
|
string serializeEnvvarsFromPoolOptions(const Options &options) const {
|
930
938
|
vector< pair<StaticString, StaticString> >::const_iterator it, end;
|
@@ -108,7 +108,7 @@ public:
|
|
108
108
|
* set debugging options on the spawner.
|
109
109
|
*/
|
110
110
|
DummySpawnerPtr getDummySpawner() {
|
111
|
-
lock_guard<boost::mutex> l(syncher);
|
111
|
+
boost::lock_guard<boost::mutex> l(syncher);
|
112
112
|
if (dummySpawner == NULL) {
|
113
113
|
dummySpawner = make_shared<DummySpawner>(resourceLocator, config);
|
114
114
|
}
|
@@ -121,6 +121,14 @@ public:
|
|
121
121
|
SpawnerConfigPtr getConfig() const {
|
122
122
|
return config;
|
123
123
|
}
|
124
|
+
|
125
|
+
RandomGeneratorPtr getRandomGenerator() const {
|
126
|
+
return randomGenerator;
|
127
|
+
}
|
128
|
+
|
129
|
+
const ResourceLocator &getResourceLocator() const {
|
130
|
+
return resourceLocator;
|
131
|
+
}
|
124
132
|
};
|
125
133
|
|
126
134
|
typedef shared_ptr<SpawnerFactory> SpawnerFactoryPtr;
|
@@ -251,7 +251,7 @@ private:
|
|
251
251
|
// This function is either called from the pool event loop or directly from
|
252
252
|
// the detachAllGroups post lock actions. In both cases getPool() is never NULL.
|
253
253
|
PoolPtr pool = self->getPool();
|
254
|
-
lock_guard<boost::mutex> lock(self->getPoolSyncher(pool));
|
254
|
+
boost::lock_guard<boost::mutex> lock(self->getPoolSyncher(pool));
|
255
255
|
|
256
256
|
vector<GroupPtr>::iterator it, end = self->detachedGroups.end();
|
257
257
|
for (it = self->detachedGroups.begin(); it != end; it++) {
|
data/ext/common/Constants.h
CHANGED
data/ext/common/Logging.cpp
CHANGED
@@ -28,6 +28,7 @@
|
|
28
28
|
#include <unistd.h>
|
29
29
|
#include <Logging.h>
|
30
30
|
#include <Utils/StrIntUtils.h>
|
31
|
+
#include <Utils/IOUtils.h>
|
31
32
|
|
32
33
|
namespace Passenger {
|
33
34
|
|
@@ -87,13 +88,17 @@ _prepareLogEntry(std::stringstream &sstream, const char *file, unsigned int line
|
|
87
88
|
|
88
89
|
void
|
89
90
|
_writeLogEntry(const std::string &str) {
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
try {
|
92
|
+
writeExact(_logOutput, str.data(), str.size());
|
93
|
+
} catch (const SystemException &) {
|
94
|
+
/* The most likely reason why this fails is when the user has setup
|
95
|
+
* Apache to log to a pipe (e.g. to a log rotation script). Upon
|
96
|
+
* restarting the web server, the process that reads from the pipe
|
97
|
+
* shuts down, so we can't write to it anymore. That's why we
|
98
|
+
* just ignore write errors. It doesn't make sense to abort for
|
99
|
+
* something like this.
|
100
|
+
*/
|
101
|
+
}
|
97
102
|
}
|
98
103
|
|
99
104
|
} // namespace Passenger
|
data/ext/common/MessageServer.h
CHANGED
@@ -127,7 +127,7 @@ using namespace oxt;
|
|
127
127
|
* };
|
128
128
|
*
|
129
129
|
* MessageServer::ClientContextPtr newClient(MessageServer::CommonClientContext &commonContext) {
|
130
|
-
* return
|
130
|
+
* return make_shared<MyContext>();
|
131
131
|
* }
|
132
132
|
*
|
133
133
|
* bool processMessage(MessageServer::CommonClientContext &commonContext,
|
@@ -157,13 +157,7 @@ using namespace oxt;
|
|
157
157
|
*/
|
158
158
|
class MessageServer {
|
159
159
|
public:
|
160
|
-
static const unsigned int CLIENT_THREAD_STACK_SIZE =
|
161
|
-
#ifdef __FreeBSD__
|
162
|
-
// localtime() on FreeBSD needs some more stack space.
|
163
|
-
1024 * 96;
|
164
|
-
#else
|
165
|
-
1024 * 64;
|
166
|
-
#endif
|
160
|
+
static const unsigned int CLIENT_THREAD_STACK_SIZE = 1024 * 128;
|
167
161
|
|
168
162
|
/** Interface for client context objects. */
|
169
163
|
class ClientContext {
|
@@ -186,9 +180,10 @@ public:
|
|
186
180
|
AccountPtr account;
|
187
181
|
|
188
182
|
|
189
|
-
CommonClientContext(FileDescriptor &
|
190
|
-
: fd(
|
191
|
-
|
183
|
+
CommonClientContext(FileDescriptor &_fd, AccountPtr &_account)
|
184
|
+
: fd(_fd),
|
185
|
+
account(_account)
|
186
|
+
{ }
|
192
187
|
|
193
188
|
/** Returns a string representation for this client context. */
|
194
189
|
string name() {
|
@@ -196,7 +191,7 @@ public:
|
|
196
191
|
}
|
197
192
|
|
198
193
|
/**
|
199
|
-
* Checks whether this client has all of the rights in
|
194
|
+
* Checks whether this client has all of the rights in `rights`. The
|
200
195
|
* client will be notified about the result of this check, by sending it a
|
201
196
|
* message.
|
202
197
|
*
|
data/ext/common/MultiLibeio.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011 Phusion
|
3
|
+
* Copyright (c) 2011-2013 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -89,7 +89,7 @@ threadMain() {
|
|
89
89
|
|
90
90
|
static void
|
91
91
|
wantPoll() {
|
92
|
-
lock_guard<boost::mutex> l(syncher);
|
92
|
+
boost::lock_guard<boost::mutex> l(syncher);
|
93
93
|
shouldPoll = true;
|
94
94
|
cond.notify_one();
|
95
95
|
}
|
@@ -97,7 +97,7 @@ wantPoll() {
|
|
97
97
|
static int
|
98
98
|
dispatch(eio_req *req) {
|
99
99
|
auto_ptr<Data> data((Data *) req->data);
|
100
|
-
assert(data->libev != NULL);
|
100
|
+
assert(data->libev != NULL);
|
101
101
|
data->libev->runLater(boost::bind(data->callback, *req));
|
102
102
|
return 0;
|
103
103
|
}
|
@@ -113,13 +113,13 @@ executeWrapper(eio_req *req) {
|
|
113
113
|
|
114
114
|
static void
|
115
115
|
lockedPread(int fd, void *buf, size_t length, off_t offset, eio_req *req) {
|
116
|
-
lock_guard<boost::mutex> l(preadWriteLock);
|
116
|
+
boost::lock_guard<boost::mutex> l(preadWriteLock);
|
117
117
|
req->result = pread(fd, buf, length, offset);
|
118
118
|
}
|
119
119
|
|
120
120
|
static void
|
121
121
|
lockedPwrite(int fd, void *buf, size_t length, off_t offset, eio_req *req) {
|
122
|
-
lock_guard<boost::mutex> l(preadWriteLock);
|
122
|
+
boost::lock_guard<boost::mutex> l(preadWriteLock);
|
123
123
|
req->result = pwrite(fd, buf, length, offset);
|
124
124
|
}
|
125
125
|
#endif
|
@@ -70,11 +70,11 @@ public:
|
|
70
70
|
helperScriptsDir = getOption(file, options, "helper_scripts");
|
71
71
|
resourcesDir = getOption(file, options, "resources");
|
72
72
|
docDir = getOption(file, options, "doc");
|
73
|
-
rubyLibDir = getOption(file, options, "
|
73
|
+
rubyLibDir = getOption(file, options, "rubylibdir");
|
74
74
|
} else {
|
75
75
|
string root = rootOrFile;
|
76
76
|
binDir = root + "/bin";
|
77
|
-
agentsDir = root + "/agents";
|
77
|
+
agentsDir = root + "/buildout/agents";
|
78
78
|
helperScriptsDir = root + "/helper-scripts";
|
79
79
|
resourcesDir = root + "/resources";
|
80
80
|
docDir = root + "/doc";
|
@@ -94,10 +94,6 @@ public:
|
|
94
94
|
return helperScriptsDir;
|
95
95
|
}
|
96
96
|
|
97
|
-
string getSpawnServerFilename() const {
|
98
|
-
return getHelperScriptsDir() + "/passenger-spawn-server";
|
99
|
-
}
|
100
|
-
|
101
97
|
string getResourcesDir() const {
|
102
98
|
return resourcesDir;
|
103
99
|
}
|
@@ -30,6 +30,7 @@
|
|
30
30
|
#include <oxt/backtrace.hpp>
|
31
31
|
|
32
32
|
#include <sys/types.h>
|
33
|
+
#include <sys/stat.h>
|
33
34
|
#include <dirent.h>
|
34
35
|
#include <unistd.h>
|
35
36
|
#include <pwd.h>
|
@@ -92,7 +93,7 @@ public:
|
|
92
93
|
* anybody except the owner. The individual files and subdirectories
|
93
94
|
* decide for themselves whether they're readable by anybody.
|
94
95
|
*/
|
95
|
-
makeDirTree(path, "u=
|
96
|
+
makeDirTree(path, "u=rwx,g=x,o=x");
|
96
97
|
|
97
98
|
/* Write structure version file. */
|
98
99
|
string structureVersionFile = path + "/structure_version.txt";
|
@@ -107,10 +108,10 @@ public:
|
|
107
108
|
* directory.
|
108
109
|
*/
|
109
110
|
if (runningAsRoot) {
|
110
|
-
makeDirTree(path + "/buffered_uploads", "u=
|
111
|
+
makeDirTree(path + "/buffered_uploads", "u=rwx,g=,o=",
|
111
112
|
webServerWorkerUid, webServerWorkerGid);
|
112
113
|
} else {
|
113
|
-
makeDirTree(path + "/buffered_uploads", "u=
|
114
|
+
makeDirTree(path + "/buffered_uploads", "u=rwx,g=,o=");
|
114
115
|
}
|
115
116
|
|
116
117
|
/* The web server must be able to directly connect to a backend. */
|
@@ -121,7 +122,7 @@ public:
|
|
121
122
|
* However we don't want everybody to be able to know the
|
122
123
|
* sockets' filenames, so the directory is not readable.
|
123
124
|
*/
|
124
|
-
makeDirTree(path + "/backends", "u=
|
125
|
+
makeDirTree(path + "/backends", "u=rwx,g=wx,o=wx,+t");
|
125
126
|
} else {
|
126
127
|
/* All backend processes are running as defaultUser/defaultGroup,
|
127
128
|
* so make defaultUser/defaultGroup the owner and group of the
|
@@ -131,13 +132,13 @@ public:
|
|
131
132
|
* nobody should be able to know the sockets' filenames without
|
132
133
|
* having access to the application pool.
|
133
134
|
*/
|
134
|
-
makeDirTree(path + "/backends", "u=
|
135
|
+
makeDirTree(path + "/backends", "u=rwx,g=x,o=x", defaultUid, defaultGid);
|
135
136
|
}
|
136
137
|
} else {
|
137
138
|
/* All backend processes are running as the same user as the web server,
|
138
139
|
* so only allow access for this user.
|
139
140
|
*/
|
140
|
-
makeDirTree(path + "/backends", "u=
|
141
|
+
makeDirTree(path + "/backends", "u=rwx,g=,o=");
|
141
142
|
}
|
142
143
|
|
143
144
|
/* The helper server (containing the application pool) must be able to access
|
@@ -148,16 +149,16 @@ public:
|
|
148
149
|
/* Both the helper server and the spawn server are
|
149
150
|
* running as root.
|
150
151
|
*/
|
151
|
-
makeDirTree(path + "/spawn-server", "u=
|
152
|
+
makeDirTree(path + "/spawn-server", "u=rwx,g=,o=");
|
152
153
|
} else {
|
153
154
|
/* Both the helper server and the spawn server are
|
154
155
|
* running as defaultUser/defaultGroup.
|
155
156
|
*/
|
156
|
-
makeDirTree(path + "/spawn-server", "u=
|
157
|
+
makeDirTree(path + "/spawn-server", "u=rwx,g=,o=",
|
157
158
|
defaultUid, defaultGid);
|
158
159
|
}
|
159
160
|
} else {
|
160
|
-
makeDirTree(path + "/spawn-server", "u=
|
161
|
+
makeDirTree(path + "/spawn-server", "u=rwx,g=,o=");
|
161
162
|
}
|
162
163
|
|
163
164
|
owner = true;
|
@@ -214,7 +215,33 @@ private:
|
|
214
215
|
* rights though, because we want admin tools to be able to list the available
|
215
216
|
* generations no matter what user they're running as.
|
216
217
|
*/
|
217
|
-
|
218
|
+
if (owner) {
|
219
|
+
switch (getFileType(path)) {
|
220
|
+
case FT_NONEXISTANT:
|
221
|
+
createDirectory(path);
|
222
|
+
break;
|
223
|
+
case FT_DIRECTORY:
|
224
|
+
removeDirTree(path);
|
225
|
+
createDirectory(path);
|
226
|
+
break;
|
227
|
+
default:
|
228
|
+
throw RuntimeException("'" + path + "' already exists, and is not a directory");
|
229
|
+
}
|
230
|
+
} else if (getFileType(path) != FT_DIRECTORY) {
|
231
|
+
throw RuntimeException("Server instance directory '" + path +
|
232
|
+
"' does not exist");
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
void createDirectory(const string &path) const {
|
237
|
+
// We do not use makeDirTree() here. If an attacker creates a directory
|
238
|
+
// just before we do, then we want to abort because we want the directory
|
239
|
+
// to have specific permissions.
|
240
|
+
if (mkdir(path.c_str(), parseModeString("u=rwx,g=rx,o=rx")) == -1) {
|
241
|
+
int e = errno;
|
242
|
+
throw FileSystemException("Cannot create server instance directory '" +
|
243
|
+
path + "'", e, path);
|
244
|
+
}
|
218
245
|
}
|
219
246
|
|
220
247
|
bool isDirectory(const string &dir, struct dirent *entry) const {
|