passenger 3.9.2.beta → 4.0.0.rc4
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/.travis.yml +3 -0
- data/NEWS +77 -7
- data/README.md +3 -11
- data/bin/passenger-install-apache2-module +24 -20
- data/bin/passenger-install-nginx-module +25 -23
- data/build/agents.rb +11 -0
- data/build/apache2.rb +9 -5
- data/build/basics.rb +37 -30
- data/build/common_library.rb +4 -1
- data/build/cplusplus_support.rb +5 -5
- data/build/cxx_tests.rb +28 -8
- data/build/integration_tests.rb +6 -3
- data/build/nginx.rb +3 -3
- data/build/packaging.rb +95 -57
- data/build/ruby_extension.rb +34 -21
- data/build/ruby_tests.rb +4 -2
- data/build/test_basics.rb +1 -1
- data/dev/run_travis.sh +36 -1
- data/doc/Users guide Apache.html +425 -308
- data/doc/Users guide Apache.idmap.txt +78 -70
- data/doc/Users guide Apache.index.sqlite3 +0 -0
- data/doc/Users guide Apache.txt +33 -92
- data/doc/Users guide Nginx.html +519 -220
- data/doc/Users guide Nginx.idmap.txt +78 -60
- data/doc/Users guide Nginx.txt +115 -26
- data/doc/Users guide Standalone.html +8 -2
- data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +1 -7
- data/doc/users_guide_snippets/installation.txt +167 -22
- data/doc/users_guide_snippets/rackup_specifications.txt +4 -0
- data/doc/users_guide_snippets/since_version.txt +1 -0
- data/doc/users_guide_snippets/support_information.txt +3 -7
- data/doc/users_guide_snippets/tips.txt +0 -24
- data/ext/apache2/Configuration.cpp +11 -33
- data/ext/apache2/Configuration.hpp +3 -18
- data/ext/apache2/DirectoryMapper.h +20 -70
- data/ext/apache2/Hooks.cpp +2 -2
- data/ext/common/AgentsStarter.cpp +0 -2
- data/ext/common/AgentsStarter.h +0 -1
- data/ext/common/AgentsStarter.hpp +1 -3
- data/ext/common/ApplicationPool2/AppTypes.cpp +74 -0
- data/ext/common/ApplicationPool2/AppTypes.h +202 -0
- data/ext/common/ApplicationPool2/Common.h +12 -10
- data/ext/common/ApplicationPool2/DirectSpawner.h +256 -0
- data/ext/common/ApplicationPool2/DummySpawner.h +90 -0
- data/ext/common/ApplicationPool2/Group.h +311 -94
- data/ext/common/ApplicationPool2/Implementation.cpp +405 -145
- data/ext/common/ApplicationPool2/Options.h +24 -26
- data/ext/common/ApplicationPool2/PipeWatcher.h +20 -13
- data/ext/common/ApplicationPool2/Pool.h +326 -183
- data/ext/common/ApplicationPool2/Process.h +205 -55
- data/ext/common/ApplicationPool2/README.md +1 -1
- data/ext/common/ApplicationPool2/Session.h +21 -10
- data/ext/common/ApplicationPool2/SmartSpawner.h +801 -0
- data/ext/common/ApplicationPool2/Spawner.h +141 -1149
- data/ext/common/ApplicationPool2/SpawnerFactory.h +132 -0
- data/ext/common/ApplicationPool2/SuperGroup.h +146 -223
- data/ext/common/Constants.h +4 -2
- data/ext/common/Exceptions.h +23 -1
- data/ext/common/Logging.cpp +17 -6
- data/ext/common/Logging.h +37 -7
- data/ext/common/ResourceLocator.h +1 -1
- data/ext/common/Utils.cpp +49 -1
- data/ext/common/Utils.h +13 -4
- data/ext/common/{AnsiColorConstants.h → Utils/AnsiColorConstants.h} +0 -0
- data/ext/common/{BCrypt.cpp → Utils/BCrypt.cpp} +0 -0
- data/ext/common/{BCrypt.h → Utils/BCrypt.h} +0 -0
- data/ext/common/{Blowfish.c → Utils/Blowfish.c} +0 -0
- data/ext/common/{Blowfish.h → Utils/Blowfish.h} +0 -0
- data/ext/common/Utils/CachedFileStat.hpp +27 -25
- data/ext/common/Utils/Curl.h +184 -0
- data/ext/common/{HttpConstants.h → Utils/HttpConstants.h} +3 -0
- data/ext/common/Utils/IOUtils.cpp +6 -2
- data/ext/common/{IniFile.h → Utils/IniFile.h} +0 -0
- data/ext/common/Utils/LargeFiles.cpp +30 -0
- data/ext/common/Utils/LargeFiles.h +40 -0
- data/ext/common/Utils/StrIntUtils.cpp +72 -8
- data/ext/common/Utils/StrIntUtils.h +24 -2
- data/ext/common/Utils/StringMap.h +12 -2
- data/ext/common/Utils/VariantMap.h +51 -2
- data/ext/common/Utils/jsoncpp.cpp +1 -1
- data/ext/common/agents/Base.cpp +147 -11
- data/ext/common/agents/HelperAgent/AgentOptions.h +14 -6
- data/ext/common/agents/HelperAgent/Main.cpp +79 -19
- data/ext/common/agents/HelperAgent/RequestHandler.h +36 -16
- data/ext/common/agents/LoggingAgent/LoggingServer.h +3 -5
- data/ext/common/agents/LoggingAgent/Main.cpp +2 -4
- data/ext/common/agents/LoggingAgent/RemoteSender.h +18 -24
- data/ext/common/agents/SpawnPreparer.cpp +7 -0
- data/ext/common/agents/Watchdog/Main.cpp +96 -38
- data/ext/nginx/Configuration.c +26 -22
- data/ext/nginx/Configuration.h +4 -2
- data/ext/nginx/ContentHandler.c +23 -52
- data/ext/nginx/ContentHandler.h +5 -11
- data/ext/nginx/config +10 -3
- data/ext/nginx/ngx_http_passenger_module.c +21 -6
- data/ext/nginx/ngx_http_passenger_module.h +4 -1
- data/ext/oxt/dynamic_thread_group.hpp +9 -1
- data/ext/oxt/system_calls.cpp +2 -2
- data/ext/ruby/extconf.rb +2 -1
- data/helper-scripts/backtrace-sanitizer.rb +2 -0
- data/helper-scripts/wsgi-loader.py +54 -21
- data/lib/phusion_passenger.rb +5 -3
- data/lib/phusion_passenger/abstract_installer.rb +18 -41
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +2 -2
- data/lib/phusion_passenger/admin_tools/server_instance.rb +2 -2
- data/lib/phusion_passenger/common_library.rb +23 -3
- data/lib/phusion_passenger/debug_logging.rb +10 -3
- data/lib/phusion_passenger/packaging.rb +1 -0
- data/lib/phusion_passenger/platform_info.rb +113 -115
- data/lib/phusion_passenger/platform_info/compiler.rb +224 -134
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +143 -0
- data/lib/phusion_passenger/platform_info/depcheck.rb +371 -0
- data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +124 -0
- data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +97 -0
- data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +39 -0
- data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +118 -0
- data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +137 -0
- data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +15 -0
- data/lib/phusion_passenger/platform_info/operating_system.rb +6 -5
- data/lib/phusion_passenger/platform_info/ruby.rb +45 -34
- data/lib/phusion_passenger/request_handler.rb +35 -22
- data/lib/phusion_passenger/request_handler/thread_handler.rb +5 -6
- data/lib/phusion_passenger/ruby_core_enhancements.rb +7 -1
- data/lib/phusion_passenger/standalone/runtime_installer.rb +43 -34
- data/lib/phusion_passenger/utils/robust_interruption.rb +34 -18
- data/passenger.gemspec +25 -0
- data/resources/templates/standalone/config.erb +3 -1
- data/test/config.json.travis +2 -2
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +37 -5
- data/test/cxx/ApplicationPool2/PoolTest.cpp +143 -50
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +8 -0
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +28 -17
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +31 -26
- data/test/cxx/RequestHandlerTest.cpp +17 -1
- data/test/cxx/UtilsTest.cpp +84 -10
- data/test/integration_tests/apache2_tests.rb +49 -163
- data/test/integration_tests/hello_world_wsgi_spec.rb +2 -2
- data/test/integration_tests/mycook_spec.rb +1 -1
- data/test/integration_tests/nginx_tests.rb +37 -19
- data/test/ruby/request_handler_spec.rb +1 -0
- data/test/ruby/spec_helper.rb +52 -1
- data/test/stub/nginx/nginx.conf.erb +2 -0
- data/test/stub/rack/start.rb +5 -0
- data/test/stub/rails3.0/Gemfile.lock +30 -30
- data/test/stub/rails3.1/Gemfile +1 -1
- data/test/stub/rails3.1/Gemfile.lock +3 -3
- data/test/stub/rails3.2/Gemfile +1 -1
- data/test/stub/rails3.2/Gemfile.lock +4 -4
- data/test/stub/rails_apps/2.3/mycook/app/controllers/welcome_controller.rb +1 -1
- data/test/stub/rails_apps/2.3/mycook/app/helpers/recipes_helper.rb +2 -0
- data/test/stub/rails_apps/2.3/mycook/app/helpers/test_helper.rb +2 -0
- data/test/stub/rails_apps/2.3/mycook/app/helpers/uploads_helper.rb +2 -0
- data/test/stub/rails_apps/2.3/mycook/app/helpers/welcome_helper.rb +2 -0
- data/test/support/nginx_controller.rb +2 -1
- metadata +160 -156
- data/build/gempackagetask.rb +0 -99
- data/build/packagetask.rb +0 -186
- data/ext/common/StringListCreator.h +0 -83
- data/lib/phusion_passenger/dependencies.rb +0 -657
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010
|
3
|
+
* Copyright (c) 2010-2013 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -235,7 +235,7 @@ private:
|
|
235
235
|
this_thread::disable_syscall_interruption dsi;
|
236
236
|
requestSocket = createUnixServer(getRequestSocketFilename().c_str());
|
237
237
|
|
238
|
-
int ret;
|
238
|
+
int ret, e;
|
239
239
|
do {
|
240
240
|
ret = chmod(getRequestSocketFilename().c_str(), S_ISVTX |
|
241
241
|
S_IRUSR | S_IWUSR | S_IXUSR |
|
@@ -244,6 +244,44 @@ private:
|
|
244
244
|
} while (ret == -1 && errno == EINTR);
|
245
245
|
|
246
246
|
setNonBlocking(requestSocket);
|
247
|
+
|
248
|
+
if (!options.requestSocketLink.empty()) {
|
249
|
+
struct stat buf;
|
250
|
+
|
251
|
+
// If this is a symlink then we'll want to check the file the symlink
|
252
|
+
// points to, so we use stat() instead of lstat().
|
253
|
+
ret = syscalls::stat(options.requestSocketLink.c_str(), &buf);
|
254
|
+
if (ret == 0 || (ret == -1 && errno == ENOENT)) {
|
255
|
+
if (ret == -1 || buf.st_mode & S_IFSOCK) {
|
256
|
+
if (syscalls::unlink(options.requestSocketLink.c_str()) == -1) {
|
257
|
+
e = errno;
|
258
|
+
throw FileSystemException("Cannot delete existing socket file '" +
|
259
|
+
options.requestSocketLink + "'", e, options.requestSocketLink);
|
260
|
+
}
|
261
|
+
} else {
|
262
|
+
throw RuntimeException("File '" + options.requestSocketLink +
|
263
|
+
"' already exists and is not a Unix domain socket");
|
264
|
+
}
|
265
|
+
} else if (ret == -1 && errno != ENOENT) {
|
266
|
+
e = errno;
|
267
|
+
throw FileSystemException("Cannot stat() file '" + options.requestSocketLink + "'",
|
268
|
+
e,
|
269
|
+
options.requestSocketLink);
|
270
|
+
}
|
271
|
+
|
272
|
+
do {
|
273
|
+
ret = symlink(getRequestSocketFilename().c_str(),
|
274
|
+
options.requestSocketLink.c_str());
|
275
|
+
} while (ret == -1 && errno == EINTR);
|
276
|
+
if (ret == -1) {
|
277
|
+
e = errno;
|
278
|
+
throw FileSystemException("Cannot create a symlink '" +
|
279
|
+
options.requestSocketLink +
|
280
|
+
"' to '" + getRequestSocketFilename() + "'",
|
281
|
+
e,
|
282
|
+
options.requestSocketLink);
|
283
|
+
}
|
284
|
+
}
|
247
285
|
}
|
248
286
|
|
249
287
|
/**
|
@@ -287,14 +325,6 @@ private:
|
|
287
325
|
}
|
288
326
|
}
|
289
327
|
|
290
|
-
void resetWorkerThreadInactivityTimers() {
|
291
|
-
requestHandler->resetInactivityTimer();
|
292
|
-
}
|
293
|
-
|
294
|
-
unsigned long long minWorkerThreadInactivityTime() const {
|
295
|
-
return requestHandler->inactivityTime();
|
296
|
-
}
|
297
|
-
|
298
328
|
void onSigquit(ev::sig &signal, int revents) {
|
299
329
|
requestHandler->inspect(cerr);
|
300
330
|
cerr.flush();
|
@@ -314,14 +344,27 @@ private:
|
|
314
344
|
|
315
345
|
static void dumpDiagnosticsOnCrash(void *userData) {
|
316
346
|
Server *self = (Server *) userData;
|
347
|
+
|
348
|
+
cerr << "### Request handler state\n";
|
317
349
|
self->requestHandler->inspect(cerr);
|
350
|
+
cerr << "\n";
|
318
351
|
cerr.flush();
|
352
|
+
|
353
|
+
cerr << "### Pool state (simple)\n";
|
319
354
|
// Do not lock, the crash may occur within the pool.
|
320
355
|
Pool::InspectOptions options;
|
321
356
|
options.verbose = true;
|
322
|
-
cerr <<
|
357
|
+
cerr << self->pool->inspect(options, false);
|
358
|
+
cerr << "\n";
|
323
359
|
cerr.flush();
|
324
|
-
|
360
|
+
|
361
|
+
cerr << "### Pool state (XML)\n";
|
362
|
+
cerr << self->pool->toXml(true, false);
|
363
|
+
cerr << "\n\n";
|
364
|
+
cerr.flush();
|
365
|
+
|
366
|
+
cerr << "### Backtraces\n";
|
367
|
+
cerr << oxt::thread::all_backtraces();
|
325
368
|
cerr.flush();
|
326
369
|
}
|
327
370
|
|
@@ -349,15 +392,24 @@ public:
|
|
349
392
|
if (geteuid() == 0 && !options.userSwitching) {
|
350
393
|
lowerPrivilege(options.defaultUser, options.defaultGroup);
|
351
394
|
}
|
395
|
+
|
396
|
+
UPDATE_TRACE_POINT();
|
397
|
+
randomGenerator = make_shared<RandomGenerator>();
|
398
|
+
// Check whether /dev/urandom is actually random.
|
399
|
+
// https://code.google.com/p/phusion-passenger/issues/detail?id=516
|
400
|
+
if (randomGenerator->generateByteString(16) == randomGenerator->generateByteString(16)) {
|
401
|
+
throw RuntimeException("Your random number device, /dev/urandom, appears to be broken. "
|
402
|
+
"It doesn't seem to be returning random data. Please fix this.");
|
403
|
+
}
|
352
404
|
|
353
405
|
UPDATE_TRACE_POINT();
|
354
406
|
loggerFactory = make_shared<UnionStation::LoggerFactory>(options.loggingAgentAddress,
|
355
407
|
"logging", options.loggingAgentPassword);
|
356
|
-
randomGenerator = make_shared<RandomGenerator>();
|
357
408
|
spawnerFactory = make_shared<SpawnerFactory>(poolLoop.safe,
|
358
|
-
resourceLocator, generation, randomGenerator);
|
409
|
+
resourceLocator, generation, make_shared<SpawnerConfig>(randomGenerator));
|
359
410
|
pool = make_shared<Pool>(poolLoop.safe.get(), spawnerFactory, loggerFactory,
|
360
411
|
randomGenerator);
|
412
|
+
pool->initialize();
|
361
413
|
pool->setMax(options.maxPoolSize);
|
362
414
|
//pool->setMaxPerApp(maxInstancesPerApp);
|
363
415
|
pool->setMaxIdleTime(options.poolIdleTime * 1000000);
|
@@ -402,11 +454,17 @@ public:
|
|
402
454
|
}
|
403
455
|
|
404
456
|
messageServer.reset();
|
457
|
+
P_DEBUG("Destroying application pool...");
|
405
458
|
pool->destroy();
|
459
|
+
uninstallDiagnosticsDumper();
|
406
460
|
pool.reset();
|
407
|
-
requestHandler.reset();
|
408
461
|
poolLoop.stop();
|
409
462
|
requestLoop.stop();
|
463
|
+
requestHandler.reset();
|
464
|
+
|
465
|
+
if (!options.requestSocketLink.empty()) {
|
466
|
+
syscalls::unlink(options.requestSocketLink.c_str());
|
467
|
+
}
|
410
468
|
|
411
469
|
P_TRACE(2, "All threads have been shut down.");
|
412
470
|
}
|
@@ -443,7 +501,6 @@ public:
|
|
443
501
|
uninstallDiagnosticsDumper();
|
444
502
|
throw SystemException("select() failed", e);
|
445
503
|
}
|
446
|
-
uninstallDiagnosticsDumper();
|
447
504
|
|
448
505
|
if (FD_ISSET(feedbackFd, &fds)) {
|
449
506
|
/* If the watchdog has been killed then we'll kill all descendant
|
@@ -459,12 +516,15 @@ public:
|
|
459
516
|
_exit(2); // In case killpg() fails.
|
460
517
|
} else {
|
461
518
|
/* We received an exit command. We want to exit 5 seconds after
|
462
|
-
* all
|
519
|
+
* all clients have disconnected have become inactive.
|
463
520
|
*/
|
464
|
-
|
465
|
-
|
521
|
+
P_DEBUG("Received command to exit gracefully. "
|
522
|
+
"Waiting until 5 seconds after all clients have disconnected...");
|
523
|
+
while (requestHandler->inactivityTime() < 5000) {
|
466
524
|
syscalls::usleep(250000);
|
467
525
|
}
|
526
|
+
P_DEBUG("It's now 5 seconds after all clients have disconnected. "
|
527
|
+
"Proceeding with graceful exit.");
|
468
528
|
}
|
469
529
|
}
|
470
530
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011
|
3
|
+
* Copyright (c) 2011-2013 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -98,12 +98,12 @@
|
|
98
98
|
#include <EventedBufferedInput.h>
|
99
99
|
#include <MessageReadersWriters.h>
|
100
100
|
#include <Constants.h>
|
101
|
-
#include <HttpConstants.h>
|
102
101
|
#include <UnionStation.h>
|
103
102
|
#include <ApplicationPool2/Pool.h>
|
104
103
|
#include <Utils/StrIntUtils.h>
|
105
104
|
#include <Utils/IOUtils.h>
|
106
105
|
#include <Utils/HttpHeaderBufferer.h>
|
106
|
+
#include <Utils/HttpConstants.h>
|
107
107
|
#include <Utils/Template.h>
|
108
108
|
#include <Utils/Timer.h>
|
109
109
|
#include <Utils/Dechunker.h>
|
@@ -795,10 +795,15 @@ private:
|
|
795
795
|
string::size_type begin = headerData.find(' ');
|
796
796
|
string::size_type end = headerData.find("\r\n");
|
797
797
|
if (begin != string::npos && end != string::npos) {
|
798
|
-
StaticString
|
799
|
-
|
800
|
-
|
801
|
-
|
798
|
+
StaticString statusValue(headerData.data() + begin, end - begin);
|
799
|
+
char header[statusValue.size() + 20];
|
800
|
+
char *pos = header;
|
801
|
+
const char *end = header + statusValue.size() + 20;
|
802
|
+
|
803
|
+
pos = appendData(pos, end, "Status: ");
|
804
|
+
pos = appendData(pos, end, statusValue);
|
805
|
+
pos = appendData(pos, end, "\r\n");
|
806
|
+
headerData.append(header);
|
802
807
|
return true;
|
803
808
|
} else {
|
804
809
|
disconnectWithError(client, "application sent malformed response: the HTTP status line is invalid.");
|
@@ -925,6 +930,21 @@ private:
|
|
925
930
|
headerData.append("X-Powered-By: Phusion Passenger\r\n");
|
926
931
|
}
|
927
932
|
|
933
|
+
// Add Date header. https://code.google.com/p/phusion-passenger/issues/detail?id=485
|
934
|
+
if (lookupHeader(headerData, "Date", "date").empty()) {
|
935
|
+
char dateStr[60];
|
936
|
+
char *pos = dateStr;
|
937
|
+
const char *end = dateStr + sizeof(dateStr) - 1;
|
938
|
+
time_t the_time = time(NULL);
|
939
|
+
struct tm the_tm;
|
940
|
+
|
941
|
+
pos = appendData(pos, end, "Date: ");
|
942
|
+
localtime_r(&the_time, &the_tm);
|
943
|
+
pos += strftime(pos, end - pos, "%a, %d %b %G %H:%M:%S %Z", &the_tm);
|
944
|
+
pos = appendData(pos, end, "\r\n");
|
945
|
+
headerData.append(dateStr, pos - dateStr);
|
946
|
+
}
|
947
|
+
|
928
948
|
// Detect out of band work request
|
929
949
|
Header oobw = lookupHeader(headerData, "X-Passenger-Request-OOB-Work", "x-passenger-request-oob-work");
|
930
950
|
if (!oobw.empty()) {
|
@@ -1064,8 +1084,9 @@ private:
|
|
1064
1084
|
RH_TRACE(client, 3, "Waiting until the client socket is writable again.");
|
1065
1085
|
client->clientOutputWatcher.start();
|
1066
1086
|
consumed(0, true);
|
1067
|
-
} else if (e == EPIPE) {
|
1087
|
+
} else if (e == EPIPE || e == ECONNRESET) {
|
1068
1088
|
// If the client closed the connection then disconnect quietly.
|
1089
|
+
RH_TRACE(client, 3, "Client stopped reading prematurely");
|
1069
1090
|
if (client->useUnionStation()) {
|
1070
1091
|
client->logMessage("Disconnecting: client stopped reading prematurely");
|
1071
1092
|
}
|
@@ -1384,7 +1405,7 @@ private:
|
|
1384
1405
|
|
1385
1406
|
void checkConnectPassword(const ClientPtr &client, const char *data, unsigned int len) {
|
1386
1407
|
RH_TRACE(client, 3, "Given connect password: \"" << cEscapeString(StaticString(data, len)) << "\"");
|
1387
|
-
if (StaticString(data, len)
|
1408
|
+
if (constantTimeCompare(StaticString(data, len), options.requestSocketPassword)) {
|
1388
1409
|
RH_TRACE(client, 3, "Connect password is correct; reading header");
|
1389
1410
|
client->state = Client::READING_HEADER;
|
1390
1411
|
client->freeBufferedConnectPassword();
|
@@ -1527,6 +1548,7 @@ private:
|
|
1527
1548
|
fillPoolOption(client, options.appType, "PASSENGER_APP_TYPE");
|
1528
1549
|
fillPoolOption(client, options.environment, "PASSENGER_ENV");
|
1529
1550
|
fillPoolOption(client, options.ruby, "PASSENGER_RUBY");
|
1551
|
+
fillPoolOption(client, options.python, "PASSENGER_PYTHON");
|
1530
1552
|
fillPoolOption(client, options.user, "PASSENGER_USER");
|
1531
1553
|
fillPoolOption(client, options.group, "PASSENGER_GROUP");
|
1532
1554
|
fillPoolOption(client, options.minProcesses, "PASSENGER_MIN_INSTANCES");
|
@@ -1745,7 +1767,7 @@ private:
|
|
1745
1767
|
client->endScopeLog(&client->scopeLogs.getFromPool, false);
|
1746
1768
|
shared_ptr<SpawnException> e2 = dynamic_pointer_cast<SpawnException>(e);
|
1747
1769
|
if (e2 != NULL) {
|
1748
|
-
if (e2->getErrorPage().empty()) {
|
1770
|
+
if (strip(e2->getErrorPage()).empty()) {
|
1749
1771
|
RH_WARN(client, "Cannot checkout session. " << e2->what());
|
1750
1772
|
writeErrorResponse(client, e2->what());
|
1751
1773
|
} else {
|
@@ -1938,6 +1960,7 @@ private:
|
|
1938
1960
|
1, client->appOutputBuffer);
|
1939
1961
|
if (ret == -1 && errno != EAGAIN) {
|
1940
1962
|
disconnectWithAppSocketWriteError(client, errno);
|
1963
|
+
// TODO: what about other errors?
|
1941
1964
|
} else if (!client->appOutputBuffer.empty()) {
|
1942
1965
|
client->state = Client::SENDING_HEADER_TO_APP;
|
1943
1966
|
client->appOutputWatcher.start();
|
@@ -1952,9 +1975,10 @@ private:
|
|
1952
1975
|
|
1953
1976
|
ssize_t ret = gatheredWrite(client->session->fd(), NULL, 0, client->appOutputBuffer);
|
1954
1977
|
if (ret == -1) {
|
1955
|
-
if (errno != EAGAIN && errno != EPIPE) {
|
1978
|
+
if (errno != EAGAIN && errno != EPIPE && errno != ECONNRESET) {
|
1956
1979
|
disconnectWithAppSocketWriteError(client, errno);
|
1957
1980
|
}
|
1981
|
+
// TODO: what about other errors?
|
1958
1982
|
} else if (client->appOutputBuffer.empty()) {
|
1959
1983
|
client->appOutputWatcher.stop();
|
1960
1984
|
sendBodyToApp(client);
|
@@ -2009,7 +2033,7 @@ private:
|
|
2009
2033
|
RH_TRACE(client, 3, "Waiting until the application socket is writable again.");
|
2010
2034
|
client->clientInput->stop();
|
2011
2035
|
client->appOutputWatcher.start();
|
2012
|
-
} else if (e == EPIPE) {
|
2036
|
+
} else if (e == EPIPE || e == ECONNRESET) {
|
2013
2037
|
// Client will be disconnected after response forwarding is done.
|
2014
2038
|
client->clientInput->stop();
|
2015
2039
|
syscalls::shutdown(client->fd, SHUT_RD);
|
@@ -2073,7 +2097,7 @@ private:
|
|
2073
2097
|
RH_TRACE(client, 3, "Waiting until the application socket is writable again.");
|
2074
2098
|
client->appOutputWatcher.start();
|
2075
2099
|
consumed(0, true);
|
2076
|
-
} else if (e == EPIPE) {
|
2100
|
+
} else if (e == EPIPE || e == ECONNRESET) {
|
2077
2101
|
// Client will be disconnected after response forwarding is done.
|
2078
2102
|
syscalls::shutdown(client->fd, SHUT_RD);
|
2079
2103
|
consumed(0, true);
|
@@ -2136,10 +2160,6 @@ public:
|
|
2136
2160
|
}
|
2137
2161
|
}
|
2138
2162
|
|
2139
|
-
void resetInactivityTimer() {
|
2140
|
-
libev->run(boost::bind(&Timer::start, &inactivityTimer));
|
2141
|
-
}
|
2142
|
-
|
2143
2163
|
unsigned long long inactivityTime() const {
|
2144
2164
|
unsigned long long result;
|
2145
2165
|
libev->run(boost::bind(&RequestHandler::getInactivityTime, this, &result));
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010-
|
3
|
+
* Copyright (c) 2010-2013 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -1084,14 +1084,12 @@ public:
|
|
1084
1084
|
const string &unionStationGatewayAddress = DEFAULT_UNION_STATION_GATEWAY_ADDRESS,
|
1085
1085
|
unsigned short unionStationGatewayPort = DEFAULT_UNION_STATION_GATEWAY_PORT,
|
1086
1086
|
const string &unionStationGatewayCert = "",
|
1087
|
-
const string &unionStationProxyAddress = ""
|
1088
|
-
const string &unionStationProxyPort = "")
|
1087
|
+
const string &unionStationProxyAddress = "")
|
1089
1088
|
: EventedMessageServer(loop, fd, accountsDatabase),
|
1090
1089
|
remoteSender(unionStationGatewayAddress,
|
1091
1090
|
unionStationGatewayPort,
|
1092
1091
|
unionStationGatewayCert,
|
1093
|
-
unionStationProxyAddress,
|
1094
|
-
unionStationProxyPort),
|
1092
|
+
unionStationProxyAddress),
|
1095
1093
|
garbageCollectionTimer(loop),
|
1096
1094
|
sinkFlushingTimer(loop),
|
1097
1095
|
exitTimer(loop)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010-
|
3
|
+
* Copyright (c) 2010-2013 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -166,7 +166,6 @@ main(int argc, char *argv[]) {
|
|
166
166
|
false, DEFAULT_UNION_STATION_GATEWAY_PORT);
|
167
167
|
string unionStationGatewayCert = options.get("union_station_gateway_cert", false);
|
168
168
|
string unionStationProxyAddress = options.get("union_station_proxy_address", false);
|
169
|
-
string unionStationProxyType = options.get("union_station_proxy_type", false);
|
170
169
|
|
171
170
|
curl_global_init(CURL_GLOBAL_ALL);
|
172
171
|
|
@@ -246,8 +245,7 @@ main(int argc, char *argv[]) {
|
|
246
245
|
unionStationGatewayAddress,
|
247
246
|
unionStationGatewayPort,
|
248
247
|
unionStationGatewayCert,
|
249
|
-
unionStationProxyAddress
|
250
|
-
unionStationProxyType);
|
248
|
+
unionStationProxyAddress);
|
251
249
|
loggingServer = &server;
|
252
250
|
|
253
251
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010 Phusion
|
3
|
+
* Copyright (c) 2010-2013 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -43,6 +43,7 @@
|
|
43
43
|
#include <Utils/SystemTime.h>
|
44
44
|
#include <Utils/ScopeGuard.h>
|
45
45
|
#include <Utils/Base64.h>
|
46
|
+
#include <Utils/Curl.h>
|
46
47
|
|
47
48
|
namespace Passenger {
|
48
49
|
|
@@ -72,8 +73,7 @@ private:
|
|
72
73
|
string ip;
|
73
74
|
unsigned short port;
|
74
75
|
string certificate;
|
75
|
-
|
76
|
-
string proxyType;
|
76
|
+
const CurlProxyInfo *proxyInfo;
|
77
77
|
|
78
78
|
CURL *curl;
|
79
79
|
struct curl_slist *headers;
|
@@ -105,16 +105,6 @@ private:
|
|
105
105
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
106
106
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlDataReceived);
|
107
107
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
|
108
|
-
if (!proxyAddress.empty()) {
|
109
|
-
curl_easy_setopt(curl, CURLOPT_PROXY, proxyAddress.c_str());
|
110
|
-
if (proxyType.empty() || proxyType == "http") {
|
111
|
-
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
112
|
-
} else if (proxyType == "socks5") {
|
113
|
-
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
114
|
-
} else {
|
115
|
-
throw RuntimeException("Only 'http' and 'socks5' proxies are supported.");
|
116
|
-
}
|
117
|
-
}
|
118
108
|
if (certificate.empty()) {
|
119
109
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
120
110
|
} else {
|
@@ -126,6 +116,7 @@ private:
|
|
126
116
|
* certificate then it doesn't matter.
|
127
117
|
*/
|
128
118
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
119
|
+
setCurlProxy(curl, *proxyInfo);
|
129
120
|
responseBody.clear();
|
130
121
|
}
|
131
122
|
|
@@ -142,13 +133,12 @@ private:
|
|
142
133
|
|
143
134
|
public:
|
144
135
|
Server(const string &ip, const string &hostName, unsigned short port, const string &cert,
|
145
|
-
const
|
136
|
+
const CurlProxyInfo *proxyInfo)
|
146
137
|
{
|
147
138
|
this->ip = ip;
|
148
139
|
this->port = port;
|
149
140
|
certificate = cert;
|
150
|
-
this->
|
151
|
-
this->proxyType = proxyType;
|
141
|
+
this->proxyInfo = proxyInfo;
|
152
142
|
|
153
143
|
hostHeader = "Host: " + hostName;
|
154
144
|
headers = NULL;
|
@@ -247,7 +237,7 @@ private:
|
|
247
237
|
CURLcode code = curl_easy_perform(curl);
|
248
238
|
curl_formfree(post);
|
249
239
|
|
250
|
-
if (code ==
|
240
|
+
if (code == CURLE_OK) {
|
251
241
|
guard.clear();
|
252
242
|
// TODO: check response
|
253
243
|
return true;
|
@@ -264,8 +254,7 @@ private:
|
|
264
254
|
string gatewayAddress;
|
265
255
|
unsigned short gatewayPort;
|
266
256
|
string certificate;
|
267
|
-
|
268
|
-
string proxyType;
|
257
|
+
CurlProxyInfo proxyInfo;
|
269
258
|
BlockingQueue<Item> queue;
|
270
259
|
oxt::thread *thr;
|
271
260
|
|
@@ -320,7 +309,7 @@ private:
|
|
320
309
|
servers.clear();
|
321
310
|
for (it = ips.begin(); it != ips.end(); it++) {
|
322
311
|
ServerPtr server = make_shared<Server>(*it, gatewayAddress, gatewayPort,
|
323
|
-
certificate,
|
312
|
+
certificate, &proxyInfo);
|
324
313
|
if (server->ping()) {
|
325
314
|
servers.push_back(server);
|
326
315
|
} else {
|
@@ -441,18 +430,23 @@ private:
|
|
441
430
|
|
442
431
|
public:
|
443
432
|
RemoteSender(const string &gatewayAddress, unsigned short gatewayPort, const string &certificate,
|
444
|
-
const string &proxyAddress
|
433
|
+
const string &proxyAddress)
|
445
434
|
: queue(1024)
|
446
435
|
{
|
436
|
+
TRACE_POINT();
|
447
437
|
this->gatewayAddress = gatewayAddress;
|
448
438
|
this->gatewayPort = gatewayPort;
|
449
439
|
this->certificate = certificate;
|
450
|
-
|
451
|
-
|
440
|
+
try {
|
441
|
+
this->proxyInfo = prepareCurlProxy(proxyAddress);
|
442
|
+
} catch (const ArgumentException &e) {
|
443
|
+
throw RuntimeException("Invalid Union Station proxy address \"" +
|
444
|
+
proxyAddress + "\": " + e.what());
|
445
|
+
}
|
452
446
|
thr = new oxt::thread(
|
453
447
|
boost::bind(&RemoteSender::threadMain, this),
|
454
448
|
"RemoteSender thread",
|
455
|
-
1024 *
|
449
|
+
1024 * 512
|
456
450
|
);
|
457
451
|
}
|
458
452
|
|