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.

Files changed (159) hide show
  1. data/.travis.yml +3 -0
  2. data/NEWS +77 -7
  3. data/README.md +3 -11
  4. data/bin/passenger-install-apache2-module +24 -20
  5. data/bin/passenger-install-nginx-module +25 -23
  6. data/build/agents.rb +11 -0
  7. data/build/apache2.rb +9 -5
  8. data/build/basics.rb +37 -30
  9. data/build/common_library.rb +4 -1
  10. data/build/cplusplus_support.rb +5 -5
  11. data/build/cxx_tests.rb +28 -8
  12. data/build/integration_tests.rb +6 -3
  13. data/build/nginx.rb +3 -3
  14. data/build/packaging.rb +95 -57
  15. data/build/ruby_extension.rb +34 -21
  16. data/build/ruby_tests.rb +4 -2
  17. data/build/test_basics.rb +1 -1
  18. data/dev/run_travis.sh +36 -1
  19. data/doc/Users guide Apache.html +425 -308
  20. data/doc/Users guide Apache.idmap.txt +78 -70
  21. data/doc/Users guide Apache.index.sqlite3 +0 -0
  22. data/doc/Users guide Apache.txt +33 -92
  23. data/doc/Users guide Nginx.html +519 -220
  24. data/doc/Users guide Nginx.idmap.txt +78 -60
  25. data/doc/Users guide Nginx.txt +115 -26
  26. data/doc/Users guide Standalone.html +8 -2
  27. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +1 -7
  28. data/doc/users_guide_snippets/installation.txt +167 -22
  29. data/doc/users_guide_snippets/rackup_specifications.txt +4 -0
  30. data/doc/users_guide_snippets/since_version.txt +1 -0
  31. data/doc/users_guide_snippets/support_information.txt +3 -7
  32. data/doc/users_guide_snippets/tips.txt +0 -24
  33. data/ext/apache2/Configuration.cpp +11 -33
  34. data/ext/apache2/Configuration.hpp +3 -18
  35. data/ext/apache2/DirectoryMapper.h +20 -70
  36. data/ext/apache2/Hooks.cpp +2 -2
  37. data/ext/common/AgentsStarter.cpp +0 -2
  38. data/ext/common/AgentsStarter.h +0 -1
  39. data/ext/common/AgentsStarter.hpp +1 -3
  40. data/ext/common/ApplicationPool2/AppTypes.cpp +74 -0
  41. data/ext/common/ApplicationPool2/AppTypes.h +202 -0
  42. data/ext/common/ApplicationPool2/Common.h +12 -10
  43. data/ext/common/ApplicationPool2/DirectSpawner.h +256 -0
  44. data/ext/common/ApplicationPool2/DummySpawner.h +90 -0
  45. data/ext/common/ApplicationPool2/Group.h +311 -94
  46. data/ext/common/ApplicationPool2/Implementation.cpp +405 -145
  47. data/ext/common/ApplicationPool2/Options.h +24 -26
  48. data/ext/common/ApplicationPool2/PipeWatcher.h +20 -13
  49. data/ext/common/ApplicationPool2/Pool.h +326 -183
  50. data/ext/common/ApplicationPool2/Process.h +205 -55
  51. data/ext/common/ApplicationPool2/README.md +1 -1
  52. data/ext/common/ApplicationPool2/Session.h +21 -10
  53. data/ext/common/ApplicationPool2/SmartSpawner.h +801 -0
  54. data/ext/common/ApplicationPool2/Spawner.h +141 -1149
  55. data/ext/common/ApplicationPool2/SpawnerFactory.h +132 -0
  56. data/ext/common/ApplicationPool2/SuperGroup.h +146 -223
  57. data/ext/common/Constants.h +4 -2
  58. data/ext/common/Exceptions.h +23 -1
  59. data/ext/common/Logging.cpp +17 -6
  60. data/ext/common/Logging.h +37 -7
  61. data/ext/common/ResourceLocator.h +1 -1
  62. data/ext/common/Utils.cpp +49 -1
  63. data/ext/common/Utils.h +13 -4
  64. data/ext/common/{AnsiColorConstants.h → Utils/AnsiColorConstants.h} +0 -0
  65. data/ext/common/{BCrypt.cpp → Utils/BCrypt.cpp} +0 -0
  66. data/ext/common/{BCrypt.h → Utils/BCrypt.h} +0 -0
  67. data/ext/common/{Blowfish.c → Utils/Blowfish.c} +0 -0
  68. data/ext/common/{Blowfish.h → Utils/Blowfish.h} +0 -0
  69. data/ext/common/Utils/CachedFileStat.hpp +27 -25
  70. data/ext/common/Utils/Curl.h +184 -0
  71. data/ext/common/{HttpConstants.h → Utils/HttpConstants.h} +3 -0
  72. data/ext/common/Utils/IOUtils.cpp +6 -2
  73. data/ext/common/{IniFile.h → Utils/IniFile.h} +0 -0
  74. data/ext/common/Utils/LargeFiles.cpp +30 -0
  75. data/ext/common/Utils/LargeFiles.h +40 -0
  76. data/ext/common/Utils/StrIntUtils.cpp +72 -8
  77. data/ext/common/Utils/StrIntUtils.h +24 -2
  78. data/ext/common/Utils/StringMap.h +12 -2
  79. data/ext/common/Utils/VariantMap.h +51 -2
  80. data/ext/common/Utils/jsoncpp.cpp +1 -1
  81. data/ext/common/agents/Base.cpp +147 -11
  82. data/ext/common/agents/HelperAgent/AgentOptions.h +14 -6
  83. data/ext/common/agents/HelperAgent/Main.cpp +79 -19
  84. data/ext/common/agents/HelperAgent/RequestHandler.h +36 -16
  85. data/ext/common/agents/LoggingAgent/LoggingServer.h +3 -5
  86. data/ext/common/agents/LoggingAgent/Main.cpp +2 -4
  87. data/ext/common/agents/LoggingAgent/RemoteSender.h +18 -24
  88. data/ext/common/agents/SpawnPreparer.cpp +7 -0
  89. data/ext/common/agents/Watchdog/Main.cpp +96 -38
  90. data/ext/nginx/Configuration.c +26 -22
  91. data/ext/nginx/Configuration.h +4 -2
  92. data/ext/nginx/ContentHandler.c +23 -52
  93. data/ext/nginx/ContentHandler.h +5 -11
  94. data/ext/nginx/config +10 -3
  95. data/ext/nginx/ngx_http_passenger_module.c +21 -6
  96. data/ext/nginx/ngx_http_passenger_module.h +4 -1
  97. data/ext/oxt/dynamic_thread_group.hpp +9 -1
  98. data/ext/oxt/system_calls.cpp +2 -2
  99. data/ext/ruby/extconf.rb +2 -1
  100. data/helper-scripts/backtrace-sanitizer.rb +2 -0
  101. data/helper-scripts/wsgi-loader.py +54 -21
  102. data/lib/phusion_passenger.rb +5 -3
  103. data/lib/phusion_passenger/abstract_installer.rb +18 -41
  104. data/lib/phusion_passenger/admin_tools/memory_stats.rb +2 -2
  105. data/lib/phusion_passenger/admin_tools/server_instance.rb +2 -2
  106. data/lib/phusion_passenger/common_library.rb +23 -3
  107. data/lib/phusion_passenger/debug_logging.rb +10 -3
  108. data/lib/phusion_passenger/packaging.rb +1 -0
  109. data/lib/phusion_passenger/platform_info.rb +113 -115
  110. data/lib/phusion_passenger/platform_info/compiler.rb +224 -134
  111. data/lib/phusion_passenger/platform_info/cxx_portability.rb +143 -0
  112. data/lib/phusion_passenger/platform_info/depcheck.rb +371 -0
  113. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +124 -0
  114. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +97 -0
  115. data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +39 -0
  116. data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +118 -0
  117. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +137 -0
  118. data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +15 -0
  119. data/lib/phusion_passenger/platform_info/operating_system.rb +6 -5
  120. data/lib/phusion_passenger/platform_info/ruby.rb +45 -34
  121. data/lib/phusion_passenger/request_handler.rb +35 -22
  122. data/lib/phusion_passenger/request_handler/thread_handler.rb +5 -6
  123. data/lib/phusion_passenger/ruby_core_enhancements.rb +7 -1
  124. data/lib/phusion_passenger/standalone/runtime_installer.rb +43 -34
  125. data/lib/phusion_passenger/utils/robust_interruption.rb +34 -18
  126. data/passenger.gemspec +25 -0
  127. data/resources/templates/standalone/config.erb +3 -1
  128. data/test/config.json.travis +2 -2
  129. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +37 -5
  130. data/test/cxx/ApplicationPool2/PoolTest.cpp +143 -50
  131. data/test/cxx/ApplicationPool2/ProcessTest.cpp +8 -0
  132. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +28 -17
  133. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +31 -26
  134. data/test/cxx/RequestHandlerTest.cpp +17 -1
  135. data/test/cxx/UtilsTest.cpp +84 -10
  136. data/test/integration_tests/apache2_tests.rb +49 -163
  137. data/test/integration_tests/hello_world_wsgi_spec.rb +2 -2
  138. data/test/integration_tests/mycook_spec.rb +1 -1
  139. data/test/integration_tests/nginx_tests.rb +37 -19
  140. data/test/ruby/request_handler_spec.rb +1 -0
  141. data/test/ruby/spec_helper.rb +52 -1
  142. data/test/stub/nginx/nginx.conf.erb +2 -0
  143. data/test/stub/rack/start.rb +5 -0
  144. data/test/stub/rails3.0/Gemfile.lock +30 -30
  145. data/test/stub/rails3.1/Gemfile +1 -1
  146. data/test/stub/rails3.1/Gemfile.lock +3 -3
  147. data/test/stub/rails3.2/Gemfile +1 -1
  148. data/test/stub/rails3.2/Gemfile.lock +4 -4
  149. data/test/stub/rails_apps/2.3/mycook/app/controllers/welcome_controller.rb +1 -1
  150. data/test/stub/rails_apps/2.3/mycook/app/helpers/recipes_helper.rb +2 -0
  151. data/test/stub/rails_apps/2.3/mycook/app/helpers/test_helper.rb +2 -0
  152. data/test/stub/rails_apps/2.3/mycook/app/helpers/uploads_helper.rb +2 -0
  153. data/test/stub/rails_apps/2.3/mycook/app/helpers/welcome_helper.rb +2 -0
  154. data/test/support/nginx_controller.rb +2 -1
  155. metadata +160 -156
  156. data/build/gempackagetask.rb +0 -99
  157. data/build/packagetask.rb +0 -186
  158. data/ext/common/StringListCreator.h +0 -83
  159. data/lib/phusion_passenger/dependencies.rb +0 -657
@@ -159,6 +159,13 @@ main(int argc, char *argv[]) {
159
159
  setGivenEnvVars(envvars);
160
160
  dumpInformation();
161
161
 
162
+ // Print a newline just in case whatever executed us printed data
163
+ // without a newline. Otherwise the next process's "!> I have control"
164
+ // command will not be properly recognized.
165
+ // https://code.google.com/p/phusion-passenger/issues/detail?id=842#c16
166
+ printf("\n");
167
+ fflush(stdout);
168
+
162
169
  execvp(executable, (char * const *) execArgs);
163
170
  int e = errno;
164
171
  fprintf(stderr, "*** ERROR ***: Cannot execute %s: %s (%d)\n",
@@ -26,6 +26,8 @@
26
26
  #include <oxt/system_calls.hpp>
27
27
  #include <boost/function.hpp>
28
28
  #include <boost/bind.hpp>
29
+ #include <boost/make_shared.hpp>
30
+ #include <boost/enable_shared_from_this.hpp>
29
31
  #include <string>
30
32
 
31
33
  #include <sys/select.h>
@@ -63,7 +65,6 @@ using namespace Passenger;
63
65
 
64
66
  /** The options that were passed to AgentsStarter. */
65
67
  static VariantMap agentsOptions;
66
- static unsigned int logLevel;
67
68
  static pid_t webServerPid;
68
69
  static string tempDir;
69
70
  static bool userSwitching;
@@ -72,10 +73,6 @@ static string defaultGroup;
72
73
  static uid_t webServerWorkerUid;
73
74
  static gid_t webServerWorkerGid;
74
75
  static string passengerRoot;
75
- static string rubyCommand;
76
- static unsigned int maxPoolSize;
77
- static unsigned int maxInstancesPerApp;
78
- static unsigned int poolIdleTime;
79
76
  static string serializedPrestartURLs;
80
77
 
81
78
  static string oldOomScore;
@@ -95,12 +92,12 @@ static void setOomScore(const StaticString &score);
95
92
  /**
96
93
  * Abstract base class for watching agent processes.
97
94
  */
98
- class AgentWatcher {
95
+ class AgentWatcher: public enable_shared_from_this<AgentWatcher> {
99
96
  private:
100
97
  /** The watcher thread. */
101
98
  oxt::thread *thr;
102
99
 
103
- void threadMain() {
100
+ void threadMain(shared_ptr<AgentWatcher> self) {
104
101
  try {
105
102
  pid_t pid, ret;
106
103
  int status, e;
@@ -510,12 +507,12 @@ public:
510
507
  throw RuntimeException("Already started watching.");
511
508
  }
512
509
 
513
- thr = new oxt::thread(boost::bind(&AgentWatcher::threadMain, this),
510
+ thr = new oxt::thread(boost::bind(&AgentWatcher::threadMain, this, shared_from_this()),
514
511
  name(), 256 * 1024);
515
512
  }
516
513
 
517
- static void stopWatching(vector<AgentWatcher *> &watchers) {
518
- vector<AgentWatcher *>::const_iterator it;
514
+ static void stopWatching(vector< shared_ptr<AgentWatcher> > &watchers) {
515
+ vector< shared_ptr<AgentWatcher> >::const_iterator it;
519
516
  oxt::thread *threads[watchers.size()];
520
517
  unsigned int i = 0;
521
518
 
@@ -524,6 +521,10 @@ public:
524
521
  }
525
522
 
526
523
  oxt::thread::interrupt_and_join_multiple(threads, watchers.size());
524
+ for (it = watchers.begin(); it != watchers.end(); it++, i++) {
525
+ delete (*it)->thr;
526
+ (*it)->thr = NULL;
527
+ }
527
528
  }
528
529
 
529
530
  /**
@@ -570,6 +571,8 @@ public:
570
571
  }
571
572
  };
572
573
 
574
+ typedef shared_ptr<AgentWatcher> AgentWatcherPtr;
575
+
573
576
 
574
577
  class HelperAgentWatcher: public AgentWatcher {
575
578
  protected:
@@ -880,7 +883,7 @@ setOomScoreNeverKill() {
880
883
  * an error.
881
884
  */
882
885
  static bool
883
- waitForStarterProcessOrWatchers(vector<AgentWatcher *> &watchers) {
886
+ waitForStarterProcessOrWatchers(vector<AgentWatcherPtr> &watchers) {
884
887
  fd_set fds;
885
888
  int max, ret;
886
889
  char x;
@@ -903,7 +906,7 @@ waitForStarterProcessOrWatchers(vector<AgentWatcher *> &watchers) {
903
906
  }
904
907
 
905
908
  if (FD_ISSET(errorEvent->fd(), &fds)) {
906
- vector<AgentWatcher *>::const_iterator it;
909
+ vector<AgentWatcherPtr>::const_iterator it;
907
910
  string message, backtrace, watcherName;
908
911
 
909
912
  for (it = watchers.begin(); it != watchers.end() && message.empty(); it++) {
@@ -926,7 +929,7 @@ waitForStarterProcessOrWatchers(vector<AgentWatcher *> &watchers) {
926
929
  }
927
930
 
928
931
  static void
929
- cleanupAgentsInBackground(vector<AgentWatcher *> &watchers) {
932
+ cleanupAgentsInBackground(vector<AgentWatcherPtr> &watchers) {
930
933
  this_thread::disable_interruption di;
931
934
  this_thread::disable_syscall_interruption dsi;
932
935
  pid_t pid;
@@ -935,13 +938,15 @@ cleanupAgentsInBackground(vector<AgentWatcher *> &watchers) {
935
938
  pid = fork();
936
939
  if (pid == 0) {
937
940
  // Child
938
- vector<AgentWatcher *>::const_iterator it;
941
+ vector<AgentWatcherPtr>::const_iterator it;
939
942
  Timer timer(false);
940
943
  fd_set fds, fds2;
941
944
  int max, agentProcessesDone;
942
945
  unsigned long long deadline = 30000; // miliseconds
943
946
 
944
- // Wait until all agent processes have exited.
947
+ // Wait until all agent processes have exited. The starter
948
+ // process is responsible for telling the individual agents
949
+ // to exit.
945
950
 
946
951
  max = 0;
947
952
  FD_ZERO(&fds);
@@ -1010,14 +1015,35 @@ cleanupAgentsInBackground(vector<AgentWatcher *> &watchers) {
1010
1015
  }
1011
1016
 
1012
1017
  static void
1013
- forceAllAgentsShutdown(vector<AgentWatcher *> &watchers) {
1014
- vector<AgentWatcher *>::iterator it;
1018
+ forceAllAgentsShutdown(vector<AgentWatcherPtr> &watchers) {
1019
+ vector<AgentWatcherPtr>::iterator it;
1015
1020
 
1016
1021
  for (it = watchers.begin(); it != watchers.end(); it++) {
1017
1022
  (*it)->forceShutdown();
1018
1023
  }
1019
1024
  }
1020
1025
 
1026
+ static string
1027
+ inferDefaultGroup(const string &defaultUser) {
1028
+ struct passwd *userEntry = getpwnam(defaultUser.c_str());
1029
+ if (userEntry == NULL) {
1030
+ throw ConfigurationException(
1031
+ string("The user that PassengerDefaultUser refers to, '") +
1032
+ defaultUser + "', does not exist.");
1033
+ }
1034
+
1035
+ struct group *groupEntry = getgrgid(userEntry->pw_gid);
1036
+ if (groupEntry == NULL) {
1037
+ throw ConfigurationException(
1038
+ string("The option PassengerDefaultUser is set to '" +
1039
+ defaultUser + "', but its primary group doesn't exist. "
1040
+ "In other words, your system's user account database "
1041
+ "is broken. Please fix it."));
1042
+ }
1043
+
1044
+ return groupEntry->gr_name;
1045
+ }
1046
+
1021
1047
  int
1022
1048
  main(int argc, char *argv[]) {
1023
1049
  /*
@@ -1040,33 +1066,52 @@ main(int argc, char *argv[]) {
1040
1066
  oldOomScore = setOomScoreNeverKill();
1041
1067
 
1042
1068
  agentsOptions = initializeAgent(argc, argv, "PassengerWatchdog");
1043
- logLevel = agentsOptions.getInt("log_level");
1044
- webServerPid = agentsOptions.getPid("web_server_pid");
1045
- tempDir = agentsOptions.get("temp_dir");
1046
- userSwitching = agentsOptions.getBool("user_switching");
1047
- defaultUser = agentsOptions.get("default_user");
1048
- defaultGroup = agentsOptions.get("default_group");
1049
- webServerWorkerUid = agentsOptions.getUid("web_server_worker_uid");
1050
- webServerWorkerGid = agentsOptions.getGid("web_server_worker_gid");
1051
- passengerRoot = agentsOptions.get("passenger_root");
1052
- rubyCommand = agentsOptions.get("ruby");
1053
- maxPoolSize = agentsOptions.getInt("max_pool_size");
1054
- maxInstancesPerApp = agentsOptions.getInt("max_instances_per_app");
1055
- poolIdleTime = agentsOptions.getInt("pool_idle_time");
1056
- serializedPrestartURLs = agentsOptions.get("prestart_urls");
1057
-
1069
+ agentsOptions
1070
+ .setDefaultInt ("log_level", DEFAULT_LOG_LEVEL)
1071
+ .setDefault ("temp_dir", getSystemTempDir())
1072
+
1073
+ .setDefaultBool("user_switching", true)
1074
+ .setDefault ("default_user", DEFAULT_WEB_APP_USER)
1075
+ .setDefaultUid ("web_server_worker_uid", getuid())
1076
+ .setDefaultGid ("web_server_worker_gid", getgid())
1077
+ .setDefault ("ruby", DEFAULT_RUBY)
1078
+ .setDefault ("python", DEFAULT_PYTHON)
1079
+ .setDefaultInt ("max_pool_size", DEFAULT_MAX_POOL_SIZE)
1080
+ .setDefaultInt ("max_instances_per_app", DEFAULT_MAX_INSTANCES_PER_APP)
1081
+ .setDefaultInt ("pool_idle_time", DEFAULT_POOL_IDLE_TIME);
1082
+
1058
1083
  P_DEBUG("Starting Watchdog...");
1059
1084
 
1060
1085
  try {
1086
+ TRACE_POINT();
1087
+ // Required options
1088
+ passengerRoot = agentsOptions.get("passenger_root");
1089
+ webServerPid = agentsOptions.getPid("web_server_pid");
1090
+
1091
+ // Optional options
1092
+ UPDATE_TRACE_POINT();
1093
+ tempDir = agentsOptions.get("temp_dir");
1094
+ userSwitching = agentsOptions.getBool("user_switching");
1095
+ defaultUser = agentsOptions.get("default_user");
1096
+ if (!agentsOptions.has("default_group")) {
1097
+ agentsOptions.set("default_group", inferDefaultGroup(defaultUser));
1098
+ }
1099
+ defaultGroup = agentsOptions.get("default_group");
1100
+ webServerWorkerUid = agentsOptions.getUid("web_server_worker_uid");
1101
+ webServerWorkerGid = agentsOptions.getGid("web_server_worker_gid");
1102
+
1103
+ UPDATE_TRACE_POINT();
1061
1104
  randomGenerator = new RandomGenerator();
1062
1105
  errorEvent = new EventFd();
1063
1106
 
1107
+ UPDATE_TRACE_POINT();
1064
1108
  serverInstanceDir.reset(new ServerInstanceDir(webServerPid, tempDir));
1065
1109
  generation = serverInstanceDir->newGeneration(userSwitching, defaultUser,
1066
1110
  defaultGroup, webServerWorkerUid, webServerWorkerGid);
1067
1111
  agentsOptions.set("server_instance_dir", serverInstanceDir->getPath());
1068
1112
  agentsOptions.setInt("generation_number", generation->getNumber());
1069
1113
 
1114
+ UPDATE_TRACE_POINT();
1070
1115
  ServerInstanceDirToucher serverInstanceDirToucher;
1071
1116
  ResourceLocator resourceLocator(passengerRoot);
1072
1117
  if (agentsOptions.get("analytics_server", false).empty()) {
@@ -1078,16 +1123,21 @@ main(int argc, char *argv[]) {
1078
1123
  loggingAgentAddress = agentsOptions.get("analytics_server");
1079
1124
  }
1080
1125
 
1081
- HelperAgentWatcher helperAgentWatcher(resourceLocator);
1082
- LoggingAgentWatcher loggingAgentWatcher(resourceLocator);
1126
+ UPDATE_TRACE_POINT();
1127
+ shared_ptr<HelperAgentWatcher> helperAgentWatcher =
1128
+ make_shared<HelperAgentWatcher>(resourceLocator);
1129
+ shared_ptr<LoggingAgentWatcher> loggingAgentWatcher =
1130
+ make_shared<LoggingAgentWatcher>(resourceLocator);
1083
1131
 
1084
- vector<AgentWatcher *> watchers;
1085
- vector<AgentWatcher *>::iterator it;
1086
- watchers.push_back(&helperAgentWatcher);
1132
+ UPDATE_TRACE_POINT();
1133
+ vector<AgentWatcherPtr> watchers;
1134
+ vector<AgentWatcherPtr>::iterator it;
1135
+ watchers.push_back(helperAgentWatcher);
1087
1136
  if (agentsOptions.get("analytics_server", false).empty()) {
1088
- watchers.push_back(&loggingAgentWatcher);
1137
+ watchers.push_back(loggingAgentWatcher);
1089
1138
  }
1090
1139
 
1140
+ UPDATE_TRACE_POINT();
1091
1141
  for (it = watchers.begin(); it != watchers.end(); it++) {
1092
1142
  try {
1093
1143
  (*it)->start();
@@ -1101,6 +1151,7 @@ main(int argc, char *argv[]) {
1101
1151
  }
1102
1152
  // Allow other exceptions to propagate and crash the watchdog.
1103
1153
  }
1154
+ UPDATE_TRACE_POINT();
1104
1155
  for (it = watchers.begin(); it != watchers.end(); it++) {
1105
1156
  try {
1106
1157
  (*it)->startWatching();
@@ -1115,21 +1166,25 @@ main(int argc, char *argv[]) {
1115
1166
  // Allow other exceptions to propagate and crash the watchdog.
1116
1167
  }
1117
1168
 
1169
+ UPDATE_TRACE_POINT();
1118
1170
  writeArrayMessage(FEEDBACK_FD,
1119
1171
  "Basic startup info",
1120
1172
  serverInstanceDir->getPath().c_str(),
1121
1173
  toString(generation->getNumber()).c_str(),
1122
1174
  NULL);
1123
1175
 
1176
+ UPDATE_TRACE_POINT();
1124
1177
  for (it = watchers.begin(); it != watchers.end(); it++) {
1125
1178
  (*it)->sendStartupInfo(FEEDBACK_FD);
1126
1179
  }
1127
1180
 
1181
+ UPDATE_TRACE_POINT();
1128
1182
  writeArrayMessage(FEEDBACK_FD, "All agents started", NULL);
1129
1183
  P_DEBUG("All Phusion Passenger agents started!");
1130
1184
 
1131
1185
  this_thread::disable_interruption di;
1132
1186
  this_thread::disable_syscall_interruption dsi;
1187
+ UPDATE_TRACE_POINT();
1133
1188
  bool exitGracefully = waitForStarterProcessOrWatchers(watchers);
1134
1189
  if (exitGracefully) {
1135
1190
  /* Fork a child process which cleans up all the agent processes in
@@ -1140,11 +1195,14 @@ main(int argc, char *argv[]) {
1140
1195
  } else {
1141
1196
  P_DEBUG("Web server did not exit gracefully, forcing shutdown of all agents...");
1142
1197
  }
1198
+ UPDATE_TRACE_POINT();
1143
1199
  AgentWatcher::stopWatching(watchers);
1144
1200
  if (exitGracefully) {
1201
+ UPDATE_TRACE_POINT();
1145
1202
  cleanupAgentsInBackground(watchers);
1146
1203
  return 0;
1147
1204
  } else {
1205
+ UPDATE_TRACE_POINT();
1148
1206
  forceAllAgentsShutdown(watchers);
1149
1207
  return 1;
1150
1208
  }
@@ -57,11 +57,6 @@ static ngx_path_init_t ngx_http_proxy_temp_path = {
57
57
  };
58
58
 
59
59
 
60
- static int
61
- ngx_str_equals(ngx_str_t *str, const char *value) {
62
- return ngx_memn2cmp(str->data, (u_char *) value, str->len, strlen(value)) == 0;
63
- }
64
-
65
60
  void *
66
61
  passenger_create_main_conf(ngx_conf_t *cf)
67
62
  {
@@ -95,8 +90,6 @@ passenger_create_main_conf(ngx_conf_t *cf)
95
90
  conf->union_station_gateway_cert.len = 0;
96
91
  conf->union_station_proxy_address.data = NULL;
97
92
  conf->union_station_proxy_address.len = 0;
98
- conf->union_station_proxy_type.data = NULL;
99
- conf->union_station_proxy_type.len = 0;
100
93
 
101
94
  conf->prestart_uris = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
102
95
  if (conf->prestart_uris == NULL) {
@@ -209,14 +202,6 @@ passenger_init_main_conf(ngx_conf_t *cf, void *conf_pointer)
209
202
  conf->union_station_proxy_address.data = (u_char *) "";
210
203
  }
211
204
 
212
- if (conf->union_station_proxy_type.len == 0) {
213
- conf->union_station_proxy_type.data = (u_char *) "";
214
-
215
- } else if (!ngx_str_equals(&conf->union_station_proxy_type, "http")
216
- && !ngx_str_equals(&conf->union_station_proxy_type, "socks5")) {
217
- return "union_station_proxy_type may only be 'http' or 'socks5'.";
218
- }
219
-
220
205
  return NGX_CONF_OK;
221
206
  }
222
207
 
@@ -253,6 +238,8 @@ passenger_create_loc_conf(ngx_conf_t *cf)
253
238
  conf->show_version_in_header = NGX_CONF_UNSET;
254
239
  conf->ruby.data = NULL;
255
240
  conf->ruby.len = 0;
241
+ conf->python.data = NULL;
242
+ conf->python.len = 0;
256
243
  conf->environment.data = NULL;
257
244
  conf->environment.len = 0;
258
245
  conf->spawn_method.data = NULL;
@@ -265,6 +252,8 @@ passenger_create_loc_conf(ngx_conf_t *cf)
265
252
  conf->group.len = 0;
266
253
  conf->app_group_name.data = NULL;
267
254
  conf->app_group_name.len = 0;
255
+ conf->app_root.data = NULL;
256
+ conf->app_root.len = 0;
268
257
  conf->app_rights.data = NULL;
269
258
  conf->app_rights.len = 0;
270
259
  conf->base_uris = NGX_CONF_UNSET_PTR;
@@ -365,12 +354,14 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
365
354
  ngx_conf_merge_value(conf->debugger, prev->debugger, 0);
366
355
  ngx_conf_merge_value(conf->show_version_in_header, prev->show_version_in_header, 1);
367
356
  ngx_conf_merge_str_value(conf->ruby, prev->ruby, NULL);
357
+ ngx_conf_merge_str_value(conf->python, prev->python, NULL);
368
358
  ngx_conf_merge_str_value(conf->environment, prev->environment, "production");
369
359
  ngx_conf_merge_str_value(conf->spawn_method, prev->spawn_method, "smart");
370
360
  ngx_conf_merge_str_value(conf->union_station_key, prev->union_station_key, NULL);
371
361
  ngx_conf_merge_str_value(conf->user, prev->user, "");
372
362
  ngx_conf_merge_str_value(conf->group, prev->group, "");
373
363
  ngx_conf_merge_str_value(conf->app_group_name, prev->app_group_name, NULL);
364
+ ngx_conf_merge_str_value(conf->app_root, prev->app_root, NULL);
374
365
  ngx_conf_merge_str_value(conf->app_rights, prev->app_rights, NULL);
375
366
  ngx_conf_merge_value(conf->min_instances, prev->min_instances, (ngx_int_t) -1);
376
367
  ngx_conf_merge_value(conf->max_requests, prev->max_requests, (ngx_int_t) -1);
@@ -1054,6 +1045,13 @@ const ngx_command_t passenger_commands[] = {
1054
1045
  offsetof(passenger_loc_conf_t, ruby),
1055
1046
  NULL },
1056
1047
 
1048
+ { ngx_string("passenger_python"),
1049
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
1050
+ ngx_conf_set_str_slot,
1051
+ NGX_HTTP_LOC_CONF_OFFSET,
1052
+ offsetof(passenger_loc_conf_t, python),
1053
+ NULL },
1054
+
1057
1055
  { ngx_string("passenger_log_level"),
1058
1056
  NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1059
1057
  ngx_conf_set_num_slot,
@@ -1068,6 +1066,13 @@ const ngx_command_t passenger_commands[] = {
1068
1066
  offsetof(passenger_main_conf_t, debug_log_file),
1069
1067
  NULL },
1070
1068
 
1069
+ { ngx_string("passenger_temp_dir"),
1070
+ NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1071
+ ngx_conf_set_str_slot,
1072
+ NGX_HTTP_MAIN_CONF_OFFSET,
1073
+ offsetof(passenger_main_conf_t, temp_dir),
1074
+ NULL },
1075
+
1071
1076
  { ngx_string("passenger_abort_on_startup_error"),
1072
1077
  NGX_HTTP_MAIN_CONF | NGX_CONF_FLAG,
1073
1078
  ngx_conf_set_flag_slot,
@@ -1165,6 +1170,12 @@ const ngx_command_t passenger_commands[] = {
1165
1170
  NGX_HTTP_LOC_CONF_OFFSET,
1166
1171
  offsetof(passenger_loc_conf_t, app_group_name),
1167
1172
  NULL },
1173
+ { ngx_string("passenger_app_root"),
1174
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_FLAG,
1175
+ ngx_conf_set_str_slot,
1176
+ NGX_HTTP_LOC_CONF_OFFSET,
1177
+ offsetof(passenger_loc_conf_t, app_root),
1178
+ NULL },
1168
1179
 
1169
1180
  { ngx_string("passenger_app_rights"),
1170
1181
  NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_FLAG,
@@ -1222,13 +1233,6 @@ const ngx_command_t passenger_commands[] = {
1222
1233
  offsetof(passenger_main_conf_t, union_station_proxy_address),
1223
1234
  NULL },
1224
1235
 
1225
- { ngx_string("union_station_proxy_type"),
1226
- NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1227
- ngx_conf_set_str_slot,
1228
- NGX_HTTP_MAIN_CONF_OFFSET,
1229
- offsetof(passenger_main_conf_t, union_station_proxy_type),
1230
- NULL },
1231
-
1232
1236
  { ngx_string("union_station_filter"),
1233
1237
  NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
1234
1238
  union_station_filter,
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Copyright (C) Igor Sysoev
3
3
  * Copyright (C) 2007 Manlio Perillo (manlio.perillo@gmail.com)
4
- * Copyright (C) 2010, 2011, 2012 Phusion
4
+ * Copyright (C) 2010-2013 Phusion
5
5
  *
6
6
  * Redistribution and use in source and binary forms, with or without
7
7
  * modification, are permitted provided that the following conditions
@@ -45,11 +45,13 @@ typedef struct {
45
45
  ngx_flag_t debugger;
46
46
  ngx_flag_t show_version_in_header;
47
47
  ngx_str_t ruby;
48
+ ngx_str_t python;
48
49
  ngx_str_t environment;
49
50
  ngx_str_t user;
50
51
  ngx_str_t group;
51
52
  ngx_str_t spawn_method;
52
53
  ngx_str_t app_group_name;
54
+ ngx_str_t app_root;
53
55
  ngx_str_t app_rights;
54
56
  ngx_int_t min_instances;
55
57
  ngx_int_t max_requests;
@@ -69,6 +71,7 @@ typedef struct {
69
71
  ngx_str_t root_dir;
70
72
  ngx_int_t log_level;
71
73
  ngx_str_t debug_log_file;
74
+ ngx_str_t temp_dir;
72
75
  ngx_flag_t abort_on_startup_error;
73
76
  ngx_uint_t max_pool_size;
74
77
  ngx_uint_t max_instances_per_app;
@@ -82,7 +85,6 @@ typedef struct {
82
85
  ngx_uint_t union_station_gateway_port;
83
86
  ngx_str_t union_station_gateway_cert;
84
87
  ngx_str_t union_station_proxy_address;
85
- ngx_str_t union_station_proxy_type;
86
88
  ngx_array_t *prestart_uris;
87
89
  } passenger_main_conf_t;
88
90