passenger 4.0.0.rc4 → 4.0.0.rc6
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 +12 -0
- data/.travis.yml +4 -4
- data/NEWS +46 -0
- data/bin/passenger-config +31 -1
- data/bin/passenger-install-apache2-module +1 -1
- data/bin/passenger-install-nginx-module +1 -0
- data/build/common_library.rb +4 -0
- data/build/cplusplus_support.rb +27 -6
- data/build/cxx_tests.rb +1 -1
- data/build/misc.rb +28 -6
- data/build/packaging.rb +72 -65
- data/build/test_basics.rb +1 -1
- data/dev/googlecode_upload.py +265 -0
- data/dev/run_travis.sh +9 -0
- data/doc/Users guide Apache.html +376 -193
- data/doc/Users guide Apache.idmap.txt +80 -62
- data/doc/Users guide Apache.txt +61 -35
- data/doc/Users guide Nginx.html +278 -83
- data/doc/Users guide Nginx.idmap.txt +26 -10
- data/doc/Users guide Nginx.txt +59 -31
- data/doc/Users guide Standalone.html +1 -1
- data/doc/users_guide_snippets/installation.txt +121 -11
- data/doc/users_guide_snippets/rvm_helper_tool.txt +56 -0
- data/ext/apache2/Bucket.cpp +1 -1
- data/ext/apache2/Configuration.cpp +7 -1
- data/ext/apache2/Configuration.hpp +4 -0
- data/ext/apache2/Hooks.cpp +2 -2
- data/ext/common/AgentsStarter.cpp +2 -2
- data/ext/common/AgentsStarter.h +1 -1
- data/ext/common/AgentsStarter.hpp +2 -2
- data/ext/common/ApplicationPool2/DirectSpawner.h +4 -8
- data/ext/common/ApplicationPool2/Group.h +17 -11
- data/ext/common/ApplicationPool2/Implementation.cpp +39 -11
- data/ext/common/ApplicationPool2/Pool.h +23 -4
- data/ext/common/ApplicationPool2/Process.h +30 -11
- data/ext/common/ApplicationPool2/SmartSpawner.h +3 -1
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedBufferedInput.h +4 -0
- data/ext/common/Utils.cpp +21 -3
- data/ext/common/Utils.h +8 -1
- data/ext/common/Utils/HttpHeaderBufferer.h +1 -1
- data/ext/common/Utils/IOUtils.cpp +5 -4
- data/ext/common/Utils/IOUtils.h +32 -14
- data/ext/common/Utils/MessagePassing.h +2 -2
- data/ext/common/Utils/ProcessMetricsCollector.h +47 -15
- data/ext/common/Utils/ScopeGuard.h +20 -3
- data/ext/common/Utils/StrIntUtils.h +14 -5
- data/ext/common/agents/Base.cpp +161 -50
- data/ext/common/agents/HelperAgent/AgentOptions.h +2 -2
- data/ext/common/agents/HelperAgent/Main.cpp +1 -0
- data/ext/common/agents/HelperAgent/RequestHandler.h +166 -52
- data/ext/common/agents/LoggingAgent/Main.cpp +1 -1
- data/ext/common/agents/Watchdog/Main.cpp +2 -2
- data/ext/nginx/Configuration.c +31 -4
- data/ext/nginx/Configuration.h +1 -0
- data/ext/nginx/ContentHandler.c +148 -34
- data/ext/nginx/ngx_http_passenger_module.c +4 -1
- data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
- data/ext/oxt/macros.hpp +30 -8
- data/lib/phusion_passenger.rb +2 -2
- data/lib/phusion_passenger/classic_rails/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/native_support.rb +19 -1
- data/lib/phusion_passenger/platform_info/compiler.rb +6 -0
- data/lib/phusion_passenger/platform_info/ruby.rb +54 -5
- data/lib/phusion_passenger/preloader_shared_helpers.rb +8 -1
- data/lib/phusion_passenger/rack/out_of_band_gc.rb +3 -1
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +32 -5
- data/lib/phusion_passenger/request_handler/thread_handler.rb +28 -8
- data/lib/phusion_passenger/ruby_core_enhancements.rb +9 -1
- data/lib/phusion_passenger/standalone/runtime_installer.rb +1 -0
- data/lib/phusion_passenger/utils/unseekable_socket.rb +50 -5
- data/passenger.gemspec +1 -1
- data/resources/templates/apache2/config_snippets.txt.erb +1 -1
- data/test/cxx/ApplicationPool2/PoolTest.cpp +4 -9
- data/test/cxx/RequestHandlerTest.cpp +5 -5
- data/test/ruby/classic_rails/loader_spec.rb +1 -1
- data/test/ruby/classic_rails/preloader_spec.rb +1 -1
- data/test/ruby/request_handler_spec.rb +207 -1
- data/test/ruby/shared/loader_sharedspec.rb +1 -0
- data/test/ruby/spec_helper.rb +11 -1
- data/test/stub/apache2/httpd.conf.erb +1 -1
- metadata +5 -3
- metadata.gz.asc +12 -0
@@ -42,7 +42,7 @@ struct AgentOptions {
|
|
42
42
|
string defaultUser;
|
43
43
|
string defaultGroup;
|
44
44
|
string passengerRoot;
|
45
|
-
string
|
45
|
+
string defaultRubyCommand;
|
46
46
|
unsigned int generationNumber;
|
47
47
|
unsigned int maxPoolSize;
|
48
48
|
unsigned int maxInstancesPerApp;
|
@@ -62,7 +62,7 @@ struct AgentOptions {
|
|
62
62
|
passengerRoot = options.get("passenger_root");
|
63
63
|
tempDir = options.get("temp_dir");
|
64
64
|
userSwitching = options.getBool("user_switching");
|
65
|
-
|
65
|
+
defaultRubyCommand = options.get("default_ruby");
|
66
66
|
defaultUser = options.get("default_user");
|
67
67
|
defaultGroup = options.get("default_group");
|
68
68
|
maxPoolSize = options.getInt("max_pool_size");
|
@@ -535,6 +535,15 @@ typedef shared_ptr<Client> ClientPtr;
|
|
535
535
|
|
536
536
|
|
537
537
|
class RequestHandler {
|
538
|
+
public:
|
539
|
+
enum BenchmarkPoint {
|
540
|
+
BP_NONE,
|
541
|
+
BP_AFTER_ACCEPT,
|
542
|
+
BP_AFTER_CHECK_CONNECT_PASSWORD,
|
543
|
+
BP_AFTER_PARSING_HEADER,
|
544
|
+
BP_BEFORE_CHECKOUT_SESSION
|
545
|
+
};
|
546
|
+
|
538
547
|
private:
|
539
548
|
friend class Client;
|
540
549
|
typedef UnionStation::LoggerFactory LoggerFactory;
|
@@ -597,6 +606,17 @@ private:
|
|
597
606
|
disconnect(client);
|
598
607
|
}
|
599
608
|
|
609
|
+
template<typename Number>
|
610
|
+
static Number clamp(Number n, Number min, Number max) {
|
611
|
+
if (n < min) {
|
612
|
+
return min;
|
613
|
+
} else if (n > max) {
|
614
|
+
return max;
|
615
|
+
} else {
|
616
|
+
return n;
|
617
|
+
}
|
618
|
+
}
|
619
|
+
|
600
620
|
// GDB helper function, implemented in .cpp file to prevent inlining.
|
601
621
|
Client *getClientPointer(const ClientPtr &client);
|
602
622
|
|
@@ -613,7 +633,7 @@ private:
|
|
613
633
|
}
|
614
634
|
}
|
615
635
|
|
616
|
-
static long long
|
636
|
+
static long long getULongLongOption(const ClientPtr &client, const StaticString &name, long long defaultValue = -1) {
|
617
637
|
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
618
638
|
if (it != client->scgiParser.end()) {
|
619
639
|
long long result = stringToULL(it->second);
|
@@ -628,6 +648,31 @@ private:
|
|
628
648
|
}
|
629
649
|
}
|
630
650
|
|
651
|
+
void writeSimpleResponse(const ClientPtr &client, const StaticString &data) {
|
652
|
+
char header[256];
|
653
|
+
char *pos = header;
|
654
|
+
const char *end = header + sizeof(header) - 1;
|
655
|
+
|
656
|
+
if (getBoolOption(client, "PASSENGER_STATUS_LINE", true)) {
|
657
|
+
pos = appendData(pos, end, "HTTP/1.1 200 OK\r\n");
|
658
|
+
}
|
659
|
+
pos += snprintf(pos, end - pos,
|
660
|
+
"Status: 200 OK\r\n"
|
661
|
+
"Content-Length: %lu\r\n"
|
662
|
+
"Content-Type: text/html; charset=UTF-8\r\n"
|
663
|
+
"Cache-Control: no-cache, no-store, must-revalidate\r\n"
|
664
|
+
"\r\n",
|
665
|
+
(unsigned long) data.size());
|
666
|
+
|
667
|
+
client->clientOutputPipe->write(header, pos - header);
|
668
|
+
client->clientOutputPipe->write(data.data(), data.size());
|
669
|
+
client->clientOutputPipe->end();
|
670
|
+
|
671
|
+
if (client->useUnionStation()) {
|
672
|
+
client->logMessage("Status: 200 OK");
|
673
|
+
}
|
674
|
+
}
|
675
|
+
|
631
676
|
void writeErrorResponse(const ClientPtr &client, const StaticString &message, const SpawnException *e = NULL) {
|
632
677
|
assert(client->state < Client::FORWARDING_BODY_TO_APP);
|
633
678
|
client->state = Client::WRITING_SIMPLE_RESPONSE;
|
@@ -636,44 +681,56 @@ private:
|
|
636
681
|
string data;
|
637
682
|
|
638
683
|
if (getBoolOption(client, "PASSENGER_FRIENDLY_ERROR_PAGES", true)) {
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
(
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
684
|
+
try {
|
685
|
+
string cssFile = templatesDir + "/error_layout.css";
|
686
|
+
string errorLayoutFile = templatesDir + "/error_layout.html.template";
|
687
|
+
string generalErrorFile =
|
688
|
+
(e != NULL && e->isHTML())
|
689
|
+
? templatesDir + "/general_error_with_html.html.template"
|
690
|
+
: templatesDir + "/general_error.html.template";
|
691
|
+
string css = readAll(cssFile);
|
692
|
+
StringMap<StaticString> params;
|
693
|
+
|
694
|
+
params.set("CSS", css);
|
695
|
+
params.set("APP_ROOT", client->options.appRoot);
|
696
|
+
params.set("RUBY", client->options.ruby);
|
697
|
+
params.set("ENVIRONMENT", client->options.environment);
|
698
|
+
params.set("MESSAGE", message);
|
699
|
+
params.set("IS_RUBY_APP",
|
700
|
+
(client->options.appType == "classic-rails" || client->options.appType == "rack")
|
701
|
+
? "true" : "false");
|
702
|
+
if (e != NULL) {
|
703
|
+
params.set("TITLE", "Web application could not be started");
|
704
|
+
// Store all SpawnException annotations into 'params',
|
705
|
+
// but convert its name to uppercase.
|
706
|
+
const map<string, string> &annotations = e->getAnnotations();
|
707
|
+
map<string, string>::const_iterator it, end = annotations.end();
|
708
|
+
for (it = annotations.begin(); it != end; it++) {
|
709
|
+
string name = it->first;
|
710
|
+
for (string::size_type i = 0; i < name.size(); i++) {
|
711
|
+
name[i] = toupper(name[i]);
|
712
|
+
}
|
713
|
+
params.set(name, it->second);
|
666
714
|
}
|
667
|
-
|
715
|
+
} else {
|
716
|
+
params.set("TITLE", "Internal server error");
|
668
717
|
}
|
669
|
-
|
670
|
-
params.set("
|
718
|
+
string content = Template::apply(readAll(generalErrorFile), params);
|
719
|
+
params.set("CONTENT", content);
|
720
|
+
data = Template::apply(readAll(errorLayoutFile), params);
|
721
|
+
} catch (const SystemException &e2) {
|
722
|
+
P_ERROR("Cannot render an error page: " << e2.what() << "\n" <<
|
723
|
+
e2.backtrace());
|
724
|
+
data = message;
|
671
725
|
}
|
672
|
-
string content = Template::apply(readAll(generalErrorFile), params);
|
673
|
-
params.set("CONTENT", content);
|
674
|
-
data = Template::apply(readAll(errorLayoutFile), params);
|
675
726
|
} else {
|
676
|
-
|
727
|
+
try {
|
728
|
+
data = readAll(templatesDir + "/undisclosed_error.html.template");
|
729
|
+
} catch (const SystemException &e2) {
|
730
|
+
P_ERROR("Cannot render an error page: " << e2.what() << "\n" <<
|
731
|
+
e2.backtrace());
|
732
|
+
data = "Internal Server Error";
|
733
|
+
}
|
677
734
|
}
|
678
735
|
|
679
736
|
stringstream str;
|
@@ -686,7 +743,7 @@ private:
|
|
686
743
|
str << "Cache-Control: no-cache, no-store, must-revalidate\r\n";
|
687
744
|
str << "\r\n";
|
688
745
|
|
689
|
-
const string
|
746
|
+
const string header = str.str();
|
690
747
|
client->clientOutputPipe->write(header.data(), header.size());
|
691
748
|
client->clientOutputPipe->write(data.data(), data.size());
|
692
749
|
client->clientOutputPipe->end();
|
@@ -697,6 +754,24 @@ private:
|
|
697
754
|
}
|
698
755
|
}
|
699
756
|
|
757
|
+
static BenchmarkPoint getDefaultBenchmarkPoint() {
|
758
|
+
const char *val = getenv("PASSENGER_REQUEST_HANDLER_BENCHMARK_POINT");
|
759
|
+
if (val == NULL || *val == '\0') {
|
760
|
+
return BP_NONE;
|
761
|
+
} else if (strcmp(val, "after_accept") == 0) {
|
762
|
+
return BP_AFTER_ACCEPT;
|
763
|
+
} else if (strcmp(val, "after_check_connect_password") == 0) {
|
764
|
+
return BP_AFTER_CHECK_CONNECT_PASSWORD;
|
765
|
+
} else if (strcmp(val, "after_parsing_header") == 0) {
|
766
|
+
return BP_AFTER_PARSING_HEADER;
|
767
|
+
} else if (strcmp(val, "before_checkout_session") == 0) {
|
768
|
+
return BP_BEFORE_CHECKOUT_SESSION;
|
769
|
+
} else {
|
770
|
+
P_WARN("Invalid RequestHandler benchmark point requested: " << val);
|
771
|
+
return BP_NONE;
|
772
|
+
}
|
773
|
+
}
|
774
|
+
|
700
775
|
|
701
776
|
/*****************************************************
|
702
777
|
* COMPONENT: appInput -> clientOutputPipe plumbing
|
@@ -792,10 +867,16 @@ private:
|
|
792
867
|
}
|
793
868
|
|
794
869
|
bool addStatusHeaderFromStatusLine(const ClientPtr &client, string &headerData) {
|
795
|
-
string::size_type begin
|
796
|
-
|
870
|
+
string::size_type begin, end;
|
871
|
+
|
872
|
+
begin = headerData.find(' ');
|
873
|
+
if (begin != string::npos) {
|
874
|
+
end = headerData.find("\r\n", begin + 1);
|
875
|
+
} else {
|
876
|
+
end = string::npos;
|
877
|
+
}
|
797
878
|
if (begin != string::npos && end != string::npos) {
|
798
|
-
StaticString statusValue(headerData.data() + begin, end - begin);
|
879
|
+
StaticString statusValue(headerData.data() + begin + 1, end - begin);
|
799
880
|
char header[statusValue.size() + 20];
|
800
881
|
char *pos = header;
|
801
882
|
const char *end = header + statusValue.size() + 20;
|
@@ -803,7 +884,7 @@ private:
|
|
803
884
|
pos = appendData(pos, end, "Status: ");
|
804
885
|
pos = appendData(pos, end, statusValue);
|
805
886
|
pos = appendData(pos, end, "\r\n");
|
806
|
-
headerData.append(header);
|
887
|
+
headerData.append(StaticString(header, pos - header));
|
807
888
|
return true;
|
808
889
|
} else {
|
809
890
|
disconnectWithError(client, "application sent malformed response: the HTTP status line is invalid.");
|
@@ -870,7 +951,7 @@ private:
|
|
870
951
|
const StaticString &origHeaderData)
|
871
952
|
{
|
872
953
|
string headerData;
|
873
|
-
headerData.reserve(origHeaderData.size() +
|
954
|
+
headerData.reserve(origHeaderData.size() + 150);
|
874
955
|
// Strip trailing CRLF.
|
875
956
|
headerData.append(origHeaderData.data(), origHeaderData.size() - 2);
|
876
957
|
|
@@ -1181,8 +1262,10 @@ private:
|
|
1181
1262
|
void onAcceptable(ev::io &io, int revents) {
|
1182
1263
|
bool endReached = false;
|
1183
1264
|
unsigned int count = 0;
|
1265
|
+
unsigned int maxAcceptTries = clamp<unsigned int>(clients.size(), 1, 10);
|
1266
|
+
ClientPtr acceptedClients[10];
|
1184
1267
|
|
1185
|
-
while (!endReached && count <
|
1268
|
+
while (!endReached && count < maxAcceptTries) {
|
1186
1269
|
FileDescriptor fd = acceptNonBlockingSocket(requestSocket);
|
1187
1270
|
if (fd == -1) {
|
1188
1271
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
@@ -1191,20 +1274,34 @@ private:
|
|
1191
1274
|
int e = errno;
|
1192
1275
|
P_ERROR("Cannot accept client: " << strerror(e) <<
|
1193
1276
|
" (errno=" << e << "). " <<
|
1194
|
-
"Pausing listening on server socket for 3 seconds."
|
1277
|
+
"Pausing listening on server socket for 3 seconds. " <<
|
1278
|
+
"Current client count: " << clients.size());
|
1195
1279
|
requestSocketWatcher.stop();
|
1196
1280
|
resumeSocketWatcherTimer.start();
|
1197
1281
|
endReached = true;
|
1198
1282
|
}
|
1283
|
+
} else if (benchmarkPoint == BP_AFTER_ACCEPT) {
|
1284
|
+
writeExact(fd,
|
1285
|
+
"HTTP/1.1 200 OK\r\n"
|
1286
|
+
"Status: 200 OK\r\n"
|
1287
|
+
"Content-Type: text/html\r\n"
|
1288
|
+
"Connection: close\r\n"
|
1289
|
+
"\r\n"
|
1290
|
+
"Benchmark point: after_accept\n");
|
1199
1291
|
} else {
|
1200
1292
|
ClientPtr client = make_shared<Client>();
|
1201
1293
|
client->associate(this, fd);
|
1202
1294
|
clients.insert(make_pair<int, ClientPtr>(fd, client));
|
1295
|
+
acceptedClients[count] = client;
|
1203
1296
|
count++;
|
1204
1297
|
RH_DEBUG(client, "New client accepted; new client count = " << clients.size());
|
1205
1298
|
}
|
1206
1299
|
}
|
1207
1300
|
|
1301
|
+
for (unsigned int i = 0; i < count; i++) {
|
1302
|
+
acceptedClients[i]->clientInput->readNow();
|
1303
|
+
}
|
1304
|
+
|
1208
1305
|
if (OXT_LIKELY(!clients.empty())) {
|
1209
1306
|
inactivityTimer.stop();
|
1210
1307
|
}
|
@@ -1286,6 +1383,7 @@ private:
|
|
1286
1383
|
if (errnoCode == ECONNRESET) {
|
1287
1384
|
// We might as well treat ECONNRESET like an EOF.
|
1288
1385
|
// http://stackoverflow.com/questions/2974021/what-does-econnreset-mean-in-the-context-of-an-af-local-socket
|
1386
|
+
RH_TRACE(client, 3, "Client socket ECONNRESET error; treating it as EOF");
|
1289
1387
|
onClientEof(client);
|
1290
1388
|
} else {
|
1291
1389
|
stringstream message;
|
@@ -1410,6 +1508,10 @@ private:
|
|
1410
1508
|
client->state = Client::READING_HEADER;
|
1411
1509
|
client->freeBufferedConnectPassword();
|
1412
1510
|
client->timeoutTimer.stop();
|
1511
|
+
|
1512
|
+
if (benchmarkPoint == BP_AFTER_CHECK_CONNECT_PASSWORD) {
|
1513
|
+
writeSimpleResponse(client, "Benchmark point: after_check_connect_password\n");
|
1514
|
+
}
|
1413
1515
|
} else {
|
1414
1516
|
disconnectWithError(client, "wrong connect password");
|
1415
1517
|
}
|
@@ -1623,6 +1725,11 @@ private:
|
|
1623
1725
|
return consumed;
|
1624
1726
|
}
|
1625
1727
|
|
1728
|
+
if (benchmarkPoint == BP_AFTER_PARSING_HEADER) {
|
1729
|
+
writeSimpleResponse(client, "Benchmark point: after_parsing_header\n");
|
1730
|
+
return consumed;
|
1731
|
+
}
|
1732
|
+
|
1626
1733
|
bool modified = modifyClientHeaders(client);
|
1627
1734
|
/* TODO: in case the headers are not modified, we only need to rebuild the header data
|
1628
1735
|
* right now because the scgiParser buffer is invalidated as soon as onClientData exits.
|
@@ -1630,7 +1737,7 @@ private:
|
|
1630
1737
|
* onClientData exits.
|
1631
1738
|
*/
|
1632
1739
|
parser.rebuildData(modified);
|
1633
|
-
client->contentLength =
|
1740
|
+
client->contentLength = getULongLongOption(client, "CONTENT_LENGTH");
|
1634
1741
|
fillPoolOptions(client);
|
1635
1742
|
if (!client->connected()) {
|
1636
1743
|
return consumed;
|
@@ -1735,13 +1842,17 @@ private:
|
|
1735
1842
|
}
|
1736
1843
|
|
1737
1844
|
void checkoutSession(const ClientPtr &client) {
|
1738
|
-
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
client->
|
1845
|
+
if (benchmarkPoint != BP_BEFORE_CHECKOUT_SESSION) {
|
1846
|
+
RH_TRACE(client, 2, "Checking out session: appRoot=" << client->options.appRoot);
|
1847
|
+
client->state = Client::CHECKING_OUT_SESSION;
|
1848
|
+
client->beginScopeLog(&client->scopeLogs.getFromPool, "get from pool");
|
1849
|
+
pool->asyncGet(client->options, boost::bind(&RequestHandler::sessionCheckedOut,
|
1850
|
+
this, client, _1, _2));
|
1851
|
+
if (!client->sessionCheckedOut) {
|
1852
|
+
client->backgroundOperations++;
|
1853
|
+
}
|
1854
|
+
} else {
|
1855
|
+
writeSimpleResponse(client, "Benchmark point: before_checkout_session\n");
|
1745
1856
|
}
|
1746
1857
|
}
|
1747
1858
|
|
@@ -2125,6 +2236,8 @@ public:
|
|
2125
2236
|
// For unit testing purposes.
|
2126
2237
|
unsigned int connectPasswordTimeout; // milliseconds
|
2127
2238
|
|
2239
|
+
BenchmarkPoint benchmarkPoint;
|
2240
|
+
|
2128
2241
|
RequestHandler(const SafeLibevPtr &_libev,
|
2129
2242
|
const FileDescriptor &_requestSocket,
|
2130
2243
|
const PoolPtr &_pool,
|
@@ -2133,7 +2246,8 @@ public:
|
|
2133
2246
|
requestSocket(_requestSocket),
|
2134
2247
|
pool(_pool),
|
2135
2248
|
options(_options),
|
2136
|
-
resourceLocator(_options.passengerRoot)
|
2249
|
+
resourceLocator(_options.passengerRoot),
|
2250
|
+
benchmarkPoint(getDefaultBenchmarkPoint())
|
2137
2251
|
{
|
2138
2252
|
accept4Available = true;
|
2139
2253
|
connectPasswordTimeout = 15000;
|
@@ -269,7 +269,7 @@ main(int argc, char *argv[]) {
|
|
269
269
|
|
270
270
|
/********** Initialized! Enter main loop... **********/
|
271
271
|
|
272
|
-
P_WARN("
|
272
|
+
P_WARN("PassengerLoggingAgent online, listening at " << socketAddress);
|
273
273
|
ev_run(eventLoop, 0);
|
274
274
|
P_DEBUG("Logging agent exiting with code " << exitCode << ".");
|
275
275
|
return exitCode;
|
@@ -1074,8 +1074,8 @@ main(int argc, char *argv[]) {
|
|
1074
1074
|
.setDefault ("default_user", DEFAULT_WEB_APP_USER)
|
1075
1075
|
.setDefaultUid ("web_server_worker_uid", getuid())
|
1076
1076
|
.setDefaultGid ("web_server_worker_gid", getgid())
|
1077
|
-
.setDefault ("
|
1078
|
-
.setDefault ("
|
1077
|
+
.setDefault ("default_ruby", DEFAULT_RUBY)
|
1078
|
+
.setDefault ("default_python", DEFAULT_PYTHON)
|
1079
1079
|
.setDefaultInt ("max_pool_size", DEFAULT_MAX_POOL_SIZE)
|
1080
1080
|
.setDefaultInt ("max_instances_per_app", DEFAULT_MAX_INSTANCES_PER_APP)
|
1081
1081
|
.setDefaultInt ("pool_idle_time", DEFAULT_POOL_IDLE_TIME);
|
data/ext/nginx/Configuration.c
CHANGED
@@ -67,7 +67,9 @@ passenger_create_main_conf(ngx_conf_t *cf)
|
|
67
67
|
return NGX_CONF_ERROR;
|
68
68
|
}
|
69
69
|
|
70
|
-
conf->
|
70
|
+
conf->default_ruby.data = NULL;
|
71
|
+
conf->default_ruby.len = 0;
|
72
|
+
conf->log_level = (ngx_int_t) NGX_CONF_UNSET;
|
71
73
|
conf->debug_log_file.data = NULL;
|
72
74
|
conf->debug_log_file.len = 0;
|
73
75
|
conf->abort_on_startup_error = NGX_CONF_UNSET;
|
@@ -110,6 +112,11 @@ passenger_init_main_conf(ngx_conf_t *cf, void *conf_pointer)
|
|
110
112
|
conf = &passenger_main_conf;
|
111
113
|
*conf = *((passenger_main_conf_t *) conf_pointer);
|
112
114
|
|
115
|
+
if (conf->default_ruby.len == 0) {
|
116
|
+
conf->default_ruby.data = (u_char *) DEFAULT_RUBY;
|
117
|
+
conf->default_ruby.len = strlen(DEFAULT_RUBY);
|
118
|
+
}
|
119
|
+
|
113
120
|
if (conf->log_level == (ngx_int_t) NGX_CONF_UNSET) {
|
114
121
|
conf->log_level = DEFAULT_LOG_LEVEL;
|
115
122
|
}
|
@@ -272,6 +279,8 @@ passenger_create_loc_conf(ngx_conf_t *cf)
|
|
272
279
|
conf->upstream_config.buffering = NGX_CONF_UNSET;
|
273
280
|
conf->upstream_config.ignore_client_abort = NGX_CONF_UNSET;
|
274
281
|
|
282
|
+
conf->upstream_config.local = NGX_CONF_UNSET_PTR;
|
283
|
+
|
275
284
|
conf->upstream_config.connect_timeout = NGX_CONF_UNSET_MSEC;
|
276
285
|
conf->upstream_config.send_timeout = NGX_CONF_UNSET_MSEC;
|
277
286
|
conf->upstream_config.read_timeout = NGX_CONF_UNSET_MSEC;
|
@@ -292,6 +301,10 @@ passenger_create_loc_conf(ngx_conf_t *cf)
|
|
292
301
|
conf->upstream_config.cache_bypass = NGX_CONF_UNSET_PTR;
|
293
302
|
conf->upstream_config.no_cache = NGX_CONF_UNSET_PTR;
|
294
303
|
conf->upstream_config.cache_valid = NGX_CONF_UNSET_PTR;
|
304
|
+
#if NGINX_VERSION_NUM >= 1002000
|
305
|
+
conf->upstream_config.cache_lock = NGX_CONF_UNSET;
|
306
|
+
conf->upstream_config.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
|
307
|
+
#endif
|
295
308
|
#endif
|
296
309
|
|
297
310
|
conf->upstream_config.intercept_errors = NGX_CONF_UNSET;
|
@@ -420,10 +433,13 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
420
433
|
prev->upstream_config.store_access, 0600);
|
421
434
|
|
422
435
|
ngx_conf_merge_value(conf->upstream_config.buffering,
|
423
|
-
|
436
|
+
prev->upstream_config.buffering, 0);
|
424
437
|
|
425
438
|
ngx_conf_merge_value(conf->upstream_config.ignore_client_abort,
|
426
|
-
|
439
|
+
prev->upstream_config.ignore_client_abort, 0);
|
440
|
+
|
441
|
+
ngx_conf_merge_ptr_value(conf->upstream_config.local,
|
442
|
+
prev->upstream_config.local, NULL);
|
427
443
|
|
428
444
|
ngx_conf_merge_msec_value(conf->upstream_config.connect_timeout,
|
429
445
|
prev->upstream_config.connect_timeout, 12000000);
|
@@ -583,6 +599,10 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
583
599
|
| NGX_HTTP_UPSTREAM_FT_OFF;
|
584
600
|
}
|
585
601
|
|
602
|
+
if (conf->upstream_config.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
|
603
|
+
conf->upstream_config.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
|
604
|
+
}
|
605
|
+
|
586
606
|
if (conf->upstream_config.cache_methods == 0) {
|
587
607
|
conf->upstream_config.cache_methods = prev->upstream_config.cache_methods;
|
588
608
|
}
|
@@ -1039,7 +1059,14 @@ const ngx_command_t passenger_commands[] = {
|
|
1039
1059
|
NULL },
|
1040
1060
|
|
1041
1061
|
{ ngx_string("passenger_ruby"),
|
1042
|
-
NGX_HTTP_MAIN_CONF |
|
1062
|
+
NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
|
1063
|
+
ngx_conf_set_str_slot,
|
1064
|
+
NGX_HTTP_MAIN_CONF_OFFSET,
|
1065
|
+
offsetof(passenger_main_conf_t, default_ruby),
|
1066
|
+
NULL },
|
1067
|
+
|
1068
|
+
{ ngx_string("passenger_ruby"),
|
1069
|
+
NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
|
1043
1070
|
ngx_conf_set_str_slot,
|
1044
1071
|
NGX_HTTP_LOC_CONF_OFFSET,
|
1045
1072
|
offsetof(passenger_loc_conf_t, ruby),
|