passenger 5.0.21 → 5.0.22

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 (203) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/CHANGELOG +38 -2
  5. data/CONTRIBUTORS +3 -0
  6. data/README.md +5 -1
  7. data/bin/passenger-status +2 -7
  8. data/build/agent.rb +2 -0
  9. data/build/cxx_dependency_map.rb +1464 -162
  10. data/build/node_tests.rb +1 -1
  11. data/build/packaging.rb +1 -1
  12. data/dev/ci/run_travis.sh +1 -1
  13. data/dev/vagrant/provision.sh +1 -1
  14. data/npm-shrinkwrap.json +635 -125
  15. data/package.json +1 -1
  16. data/resources/templates/standalone/config.erb +33 -161
  17. data/resources/templates/standalone/global.erb +15 -0
  18. data/resources/templates/standalone/http.erb +40 -0
  19. data/resources/templates/standalone/mass_deployment_default_server.erb +11 -0
  20. data/resources/templates/standalone/rails_asset_pipeline.erb +22 -0
  21. data/resources/templates/standalone/server.erb +58 -0
  22. data/src/agent/Core/ApiServer.h +37 -32
  23. data/src/agent/Core/ApplicationPool/BasicGroupInfo.h +1 -1
  24. data/src/agent/Core/ApplicationPool/BasicProcessInfo.h +6 -0
  25. data/src/agent/Core/ApplicationPool/Common.h +1 -1
  26. data/src/agent/Core/ApplicationPool/Group/OutOfBandWork.cpp +1 -1
  27. data/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp +4 -0
  28. data/src/agent/Core/ApplicationPool/Implementation.cpp +2 -2
  29. data/src/agent/Core/ApplicationPool/Options.h +18 -1
  30. data/src/agent/Core/ApplicationPool/Pool.h +1 -1
  31. data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +6 -6
  32. data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +3 -3
  33. data/src/agent/Core/ApplicationPool/Pool/InitializationAndShutdown.cpp +1 -1
  34. data/src/agent/Core/ApplicationPool/Pool/Miscellaneous.cpp +6 -0
  35. data/src/agent/Core/ApplicationPool/Process.h +6 -1
  36. data/src/agent/Core/ApplicationPool/Socket.h +9 -12
  37. data/src/agent/Core/Controller.h +422 -0
  38. data/src/agent/Core/{RequestHandler → Controller}/AppResponse.h +2 -0
  39. data/src/agent/Core/{RequestHandler → Controller}/BufferBody.cpp +27 -5
  40. data/src/agent/Core/{RequestHandler → Controller}/CheckoutSession.cpp +61 -31
  41. data/src/agent/Core/{RequestHandler → Controller}/Client.h +5 -2
  42. data/src/agent/Core/{RequestHandler → Controller}/ForwardResponse.cpp +93 -42
  43. data/src/agent/Core/{RequestHandler → Controller}/Hooks.cpp +107 -60
  44. data/src/agent/Core/Controller/Implementation.cpp +38 -0
  45. data/src/agent/Core/{RequestHandler → Controller}/InitRequest.cpp +134 -80
  46. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +165 -0
  47. data/src/agent/Core/{RequestHandler/Utils.cpp → Controller/InternalUtils.cpp} +49 -32
  48. data/src/agent/Core/Controller/Miscellaneous.cpp +116 -0
  49. data/src/agent/Core/{RequestHandler → Controller}/Request.h +6 -4
  50. data/src/agent/Core/{RequestHandler → Controller}/SendRequest.cpp +205 -130
  51. data/src/agent/Core/Controller/StateInspectionAndConfiguration.cpp +161 -0
  52. data/src/agent/Core/{RequestHandler → Controller}/TurboCaching.h +3 -0
  53. data/src/agent/Core/CoreMain.cpp +62 -51
  54. data/src/agent/Core/OptionParser.h +24 -0
  55. data/src/agent/Core/ResponseCache.h +5 -5
  56. data/src/agent/Core/SpawningKit/Config.h +2 -2
  57. data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -1
  58. data/src/agent/Core/UnionStation/{Core.h → Context.h} +14 -18
  59. data/src/agent/Core/UnionStation/StopwatchLog.h +3 -2
  60. data/src/agent/Core/UnionStation/Transaction.h +7 -7
  61. data/src/agent/Shared/ApiServerUtils.h +9 -1
  62. data/src/agent/UstRouter/ApiServer.h +5 -2
  63. data/src/agent/UstRouter/Controller.h +27 -9
  64. data/src/agent/UstRouter/UstRouterMain.cpp +1 -0
  65. data/src/agent/Watchdog/ApiServer.h +5 -2
  66. data/src/apache2_module/ConfigurationCommands.cpp +7 -0
  67. data/src/apache2_module/ConfigurationFields.hpp +2 -0
  68. data/src/apache2_module/ConfigurationSetters.cpp +24 -0
  69. data/src/apache2_module/CreateDirConfig.cpp +1 -0
  70. data/src/apache2_module/Hooks.cpp +6 -5
  71. data/src/apache2_module/MergeDirConfig.cpp +7 -0
  72. data/src/apache2_module/SetHeaders.cpp +5 -0
  73. data/src/cxx_supportlib/Constants.h +5 -3
  74. data/src/cxx_supportlib/SafeLibev.h +2 -1
  75. data/src/cxx_supportlib/UnionStationFilterSupport.h +2 -1
  76. data/src/cxx_supportlib/Utils/ReleaseableScopedPointer.h +70 -0
  77. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/regex_raw_buffer.cpp +6 -6
  78. data/src/helper-scripts/node-loader.js +59 -0
  79. data/src/nginx_module/CacheLocationConfig.c +48 -0
  80. data/src/nginx_module/ConfigurationCommands.c +20 -0
  81. data/src/nginx_module/ConfigurationFields.h +4 -0
  82. data/src/nginx_module/CreateLocationConfig.c +8 -0
  83. data/src/nginx_module/MergeLocationConfig.c +12 -0
  84. data/src/nodejs_supportlib/phusion_passenger/log_express.js +106 -0
  85. data/src/nodejs_supportlib/phusion_passenger/log_mongodb.js +203 -0
  86. data/src/nodejs_supportlib/phusion_passenger/ustreporter.js +227 -0
  87. data/src/nodejs_supportlib/phusion_passenger/ustrouter_connector.js +446 -0
  88. data/src/nodejs_supportlib/vendor-copy/codify/codify.js +44 -0
  89. data/src/nodejs_supportlib/vendor-copy/codify/package.json +29 -0
  90. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/context.js +200 -0
  91. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/glue.js +488 -0
  92. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/index.js +407 -0
  93. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/node_modules/shimmer/index.js +90 -0
  94. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/node_modules/shimmer/package.json +40 -0
  95. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/package.json +54 -0
  96. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/listener.js +160 -0
  97. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/node_modules/shimmer/index.js +90 -0
  98. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/node_modules/shimmer/package.json +40 -0
  99. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/package.json +46 -0
  100. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/package.json +56 -0
  101. data/src/nodejs_supportlib/vendor-copy/network-byte-order/lib/index.js +102 -0
  102. data/src/nodejs_supportlib/vendor-copy/network-byte-order/package.json +51 -0
  103. data/src/nodejs_supportlib/vendor-copy/winston/LICENSE +19 -0
  104. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston.js +165 -0
  105. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/common.js +483 -0
  106. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config.js +62 -0
  107. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/cli-config.js +35 -0
  108. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/npm-config.js +27 -0
  109. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/syslog-config.js +31 -0
  110. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/container.js +127 -0
  111. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/exception.js +56 -0
  112. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/logger.js +701 -0
  113. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports.js +34 -0
  114. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/console.js +128 -0
  115. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/daily-rotate-file.js +601 -0
  116. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/file.js +675 -0
  117. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/http.js +232 -0
  118. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/memory.js +89 -0
  119. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/transport.js +135 -0
  120. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/webhook.js +146 -0
  121. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/LICENSE +19 -0
  122. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/lib/async.js +1283 -0
  123. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/package.json +66 -0
  124. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/support/sync-package-managers.js +53 -0
  125. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/MIT-LICENSE.txt +23 -0
  126. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/colors.js +176 -0
  127. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/custom/trap.js +45 -0
  128. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/custom/zalgo.js +104 -0
  129. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/extendStringPrototype.js +118 -0
  130. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/index.js +12 -0
  131. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/america.js +12 -0
  132. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/rainbow.js +13 -0
  133. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/random.js +8 -0
  134. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/zebra.js +5 -0
  135. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/styles.js +77 -0
  136. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/system/supports-colors.js +61 -0
  137. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/package.json +35 -0
  138. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/safe.js +9 -0
  139. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/themes/generic-logging.js +12 -0
  140. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/cycle/cycle.js +170 -0
  141. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/cycle/package.json +30 -0
  142. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/LICENSE +20 -0
  143. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/lib/eyes.js +236 -0
  144. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/package.json +42 -0
  145. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/LICENSE.md +11 -0
  146. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/isstream.js +27 -0
  147. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/package.json +42 -0
  148. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/LICENSE +19 -0
  149. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/lib/pkginfo.js +136 -0
  150. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/package.json +56 -0
  151. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/License +19 -0
  152. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/lib/stack-trace.js +111 -0
  153. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/package.json +33 -0
  154. data/src/nodejs_supportlib/vendor-copy/winston/package.json +87 -0
  155. data/src/ruby_supportlib/phusion_passenger.rb +3 -4
  156. data/src/ruby_supportlib/phusion_passenger/admin_tools/instance.rb +19 -2
  157. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +8 -0
  158. data/src/ruby_supportlib/phusion_passenger/config/list_instances_command.rb +2 -6
  159. data/src/ruby_supportlib/phusion_passenger/config/reopen_logs_command.rb +13 -0
  160. data/src/ruby_supportlib/phusion_passenger/config/restart_app_command.rb +3 -0
  161. data/src/ruby_supportlib/phusion_passenger/config/utils.rb +9 -7
  162. data/src/ruby_supportlib/phusion_passenger/config/validate_install_command.rb +8 -1
  163. data/src/ruby_supportlib/phusion_passenger/constants.rb +3 -1
  164. data/src/ruby_supportlib/phusion_passenger/native_support.rb +20 -4
  165. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +8 -0
  166. data/src/ruby_supportlib/phusion_passenger/packaging.rb +1 -0
  167. data/src/ruby_supportlib/phusion_passenger/platform_info/apache_detector.rb +1 -1
  168. data/src/ruby_supportlib/phusion_passenger/platform_info/operating_system.rb +11 -4
  169. data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
  170. data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +647 -0
  171. data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +229 -15
  172. data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +35 -323
  173. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +36 -12
  174. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/nginx_engine.rb +123 -14
  175. data/src/ruby_supportlib/phusion_passenger/standalone/status_command.rb +32 -17
  176. data/src/ruby_supportlib/phusion_passenger/standalone/stop_command.rb +32 -21
  177. data/src/ruby_supportlib/phusion_passenger/standalone/version_command.rb +5 -5
  178. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README.md +2 -2
  179. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Rakefile +5 -1
  180. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +68 -24
  181. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +9 -1
  182. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +9 -7
  183. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +3 -2
  184. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/basics.rb +8 -5
  185. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +395 -0
  186. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +10 -7
  187. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +14 -0
  188. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version_data.rb +2 -2
  189. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml +4 -2
  190. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.example +2 -2
  191. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis +2 -2
  192. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis-with-sudo +16 -0
  193. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile +1 -1
  194. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile.lock +2 -2
  195. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/README.md +1 -1
  196. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails.rb +44 -17
  197. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_support_cache_subscriber.rb +16 -7
  198. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/version_data.rb +2 -2
  199. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/union_station_hooks_rails.gemspec +1 -1
  200. metadata +99 -16
  201. metadata.gz.asc +7 -7
  202. data/resources/oss-binaries.phusionpassenger.com.crt +0 -248
  203. data/src/agent/Core/RequestHandler.h +0 -471
@@ -46,7 +46,7 @@ class Group;
46
46
  *
47
47
  * Since Process and Session sometimes need to look up this basic group
48
48
  * information, this struct also serves to ensure that Process and Session do
49
- * not have a direct dependency on Group, but on GroupImmutableInfo instead.
49
+ * not have a direct dependency on Group, but on BasicGroupInfo instead.
50
50
  */
51
51
  class BasicGroupInfo {
52
52
  public:
@@ -92,6 +92,12 @@ public:
92
92
  : process(_process),
93
93
  groupInfo(_groupInfo),
94
94
  pid(getJsonIntField(json, "pid"))
95
+ // We initialize this in Process::initializeStickySessionId(),
96
+ // called from Group::attach().
97
+ // We should probably some day refactor this. The reason we do
98
+ // it the way we do right now is because some day we want to be able
99
+ // to attach external processes, so the best place to initialize this
100
+ // information is in Group::attach().
95
101
  //stickySessionId(getJsonUintField(json, "sticky_session_id", 0))
96
102
  {
97
103
  StaticString gupid = getJsonStaticStringField(json, "gupid");
@@ -39,7 +39,7 @@
39
39
  #include <Utils/VariantMap.h>
40
40
  #include <Core/ApplicationPool/Options.h>
41
41
  #include <Core/SpawningKit/Config.h>
42
- #include <Core/UnionStation/Core.h>
42
+ #include <Core/UnionStation/Context.h>
43
43
  #include <Core/UnionStation/Transaction.h>
44
44
 
45
45
  namespace tut {
@@ -225,7 +225,7 @@ Group::spawnThreadOOBWRequest(GroupPtr self, ProcessPtr process) {
225
225
  connection.fail = true;
226
226
  ScopeGuard guard(boost::bind(&Socket::checkinConnection, socket, connection));
227
227
 
228
- // This is copied from RequestHandler when it is sending data using the
228
+ // This is copied from Core::Controller when it is sending data using the
229
229
  // "session" protocol.
230
230
  char sizeField[sizeof(boost::uint32_t)];
231
231
  SmallVector<StaticString, 10> data;
@@ -411,6 +411,10 @@ Group::attach(const ProcessPtr &process,
411
411
  }
412
412
 
413
413
  process->initializeStickySessionId(generateStickySessionId());
414
+ if (options.forceMaxConcurrentRequestsPerProcess != -1) {
415
+ process->forceMaxConcurrency(options.forceMaxConcurrentRequestsPerProcess);
416
+ }
417
+
414
418
  P_DEBUG("Attaching process " << process->inspect());
415
419
  addProcessToList(process, enabledProcesses);
416
420
 
@@ -175,10 +175,10 @@ void processAndLogNewSpawnException(SpawnException &e, const Options &options,
175
175
  char filename[PATH_MAX];
176
176
  stringstream stream;
177
177
 
178
- if (options.analytics && config->unionStationCore != NULL) {
178
+ if (options.analytics && config->unionStationContext != NULL) {
179
179
  try {
180
180
  UPDATE_TRACE_POINT();
181
- transaction = config->unionStationCore->newTransaction(
181
+ transaction = config->unionStationContext->newTransaction(
182
182
  options.getAppGroupName(),
183
183
  "exceptions",
184
184
  options.unionStationKey);
@@ -36,7 +36,7 @@
36
36
  #include <ResourceLocator.h>
37
37
  #include <StaticString.h>
38
38
  #include <Utils.h>
39
- #include <Core/UnionStation/Core.h>
39
+ #include <Core/UnionStation/Context.h>
40
40
  #include <Core/UnionStation/Transaction.h>
41
41
 
42
42
  namespace Passenger {
@@ -281,6 +281,15 @@ public:
281
281
  */
282
282
  StaticString environmentVariables;
283
283
 
284
+ /**
285
+ * If set to a value that isn't -1, makes Passenger ignore the application's
286
+ * advertised socket concurrency, and believe that the concurrency should be
287
+ * the given value.
288
+ *
289
+ * Defaults to -1.
290
+ */
291
+ int forceMaxConcurrentRequestsPerProcess;
292
+
284
293
  /** Whether debugger support should be enabled. */
285
294
  bool debugger;
286
295
 
@@ -350,6 +359,12 @@ public:
350
359
  */
351
360
  unsigned int maxRequestQueueSize;
352
361
 
362
+ /**
363
+ * Whether websocket connections should be aborted on process shutdown
364
+ * or restart.
365
+ */
366
+ bool abortWebsocketsOnProcessShutdown;
367
+
353
368
  /**
354
369
  * The Union Station key to use in case analytics logging is enabled.
355
370
  * It is used by Pool::collectAnalytics() and other administrative
@@ -461,6 +476,7 @@ public:
461
476
  ruby(DEFAULT_RUBY, sizeof(DEFAULT_RUBY) - 1),
462
477
  python(DEFAULT_PYTHON, sizeof(DEFAULT_PYTHON) - 1),
463
478
  nodejs(DEFAULT_NODEJS, sizeof(DEFAULT_NODEJS) - 1),
479
+ forceMaxConcurrentRequestsPerProcess(-1),
464
480
  debugger(false),
465
481
  loadShellEnvvars(true),
466
482
  userSwitching(true),
@@ -472,6 +488,7 @@ public:
472
488
  maxPreloaderIdleTime(-1),
473
489
  maxOutOfBandWorkInstances(1),
474
490
  maxRequestQueueSize(100),
491
+ abortWebsocketsOnProcessShutdown(true),
475
492
 
476
493
  stickySessionId(0),
477
494
  statThrottleRate(DEFAULT_STAT_THROTTLE_RATE),
@@ -405,7 +405,7 @@ public:
405
405
 
406
406
  Context *getContext();
407
407
  const SpawningKit::ConfigPtr &getSpawningKitConfig() const;
408
- const UnionStation::CorePtr &getUnionStationCore() const;
408
+ const UnionStation::ContextPtr &getUnionStationContext() const;
409
409
  const RandomGeneratorPtr &getRandomGenerator() const;
410
410
 
411
411
 
@@ -112,8 +112,8 @@ void
112
112
  Pool::prepareUnionStationProcessStateLogs(vector<UnionStationLogEntry> &logEntries,
113
113
  const GroupPtr &group) const
114
114
  {
115
- const UnionStation::CorePtr &unionStationCore = getUnionStationCore();
116
- if (group->options.analytics && unionStationCore != NULL) {
115
+ const UnionStation::ContextPtr &unionStationContext = getUnionStationContext();
116
+ if (group->options.analytics && unionStationContext != NULL) {
117
117
  logEntries.push_back(UnionStationLogEntry());
118
118
  UnionStationLogEntry &entry = logEntries.back();
119
119
  stringstream stream;
@@ -133,8 +133,8 @@ void
133
133
  Pool::prepareUnionStationSystemMetricsLogs(vector<UnionStationLogEntry> &logEntries,
134
134
  const GroupPtr &group) const
135
135
  {
136
- const UnionStation::CorePtr &unionStationCore = getUnionStationCore();
137
- if (group->options.analytics && unionStationCore != NULL) {
136
+ const UnionStation::ContextPtr &unionStationContext = getUnionStationContext();
137
+ if (group->options.analytics && unionStationContext != NULL) {
138
138
  logEntries.push_back(UnionStationLogEntry());
139
139
  UnionStationLogEntry &entry = logEntries.back();
140
140
  stringstream stream;
@@ -228,12 +228,12 @@ Pool::realCollectAnalytics() {
228
228
  l.unlock();
229
229
  UPDATE_TRACE_POINT();
230
230
  if (!logEntries.empty()) {
231
- const UnionStation::CorePtr &unionStationCore = getUnionStationCore();
231
+ const UnionStation::ContextPtr &unionStationContext = getUnionStationContext();
232
232
  P_DEBUG("Sending process and system metrics to Union Station");
233
233
  while (!logEntries.empty()) {
234
234
  UnionStationLogEntry &entry = logEntries.back();
235
235
  UnionStation::TransactionPtr transaction =
236
- unionStationCore->newTransaction(
236
+ unionStationContext->newTransaction(
237
237
  entry.groupName,
238
238
  entry.category,
239
239
  entry.key);
@@ -227,9 +227,9 @@ Pool::getSpawningKitConfig() const {
227
227
  return context.getSpawningKitConfig();
228
228
  }
229
229
 
230
- const UnionStation::CorePtr &
231
- Pool::getUnionStationCore() const {
232
- return getSpawningKitConfig()->unionStationCore;
230
+ const UnionStation::ContextPtr &
231
+ Pool::getUnionStationContext() const {
232
+ return getSpawningKitConfig()->unionStationContext;
233
233
  }
234
234
 
235
235
  const RandomGeneratorPtr &
@@ -91,7 +91,7 @@ Pool::initDebugging() {
91
91
  * Should be called right after the agent has received
92
92
  * the message to exit gracefully. This will tell processes to
93
93
  * abort any long-running connections, e.g. WebSocket connections,
94
- * because the RequestHandler has to wait until all connections are
94
+ * because the Core::Controller has to wait until all connections are
95
95
  * finished before proceeding with shutdown.
96
96
  */
97
97
  void
@@ -25,6 +25,12 @@
25
25
  */
26
26
  #include <Core/ApplicationPool/Pool.h>
27
27
 
28
+ /*************************************************************************
29
+ *
30
+ * Miscellaneous functions for ApplicationPool2::Pool
31
+ *
32
+ *************************************************************************/
33
+
28
34
  namespace Passenger {
29
35
  namespace ApplicationPool2 {
30
36
 
@@ -293,7 +293,7 @@ private:
293
293
  Socket *socket = &(*it);
294
294
  if (socket->protocol == "session" || socket->protocol == "http_session") {
295
295
  if (sessionSocketCount == MAX_SESSION_SOCKETS) {
296
- throw RuntimeException("The process has many session sockets. "
296
+ throw RuntimeException("The process has too many session sockets. "
297
297
  "A maximum of " + toString(MAX_SESSION_SOCKETS) + " is allowed");
298
298
  }
299
299
  sessionSockets[sessionSocketCount] = socket;
@@ -480,6 +480,11 @@ public:
480
480
  info.stickySessionId = value;
481
481
  }
482
482
 
483
+ void forceMaxConcurrency(int value) {
484
+ assert(value >= 0);
485
+ concurrency = value;
486
+ }
487
+
483
488
  void shutdownNotRequired() {
484
489
  requiresShutdown = false;
485
490
  }
@@ -226,20 +226,17 @@ public:
226
226
  int busyness() const {
227
227
  /* Different sockets within a Process may have different
228
228
  * 'concurrency' values. We want:
229
- * - Process.sessionSockets to sort the sockets from least used to most used.
230
- * - to give sockets with concurrency == 0 more priority over sockets
231
- * with concurrency > 0.
232
- * Therefore, we describe our busyness as a percentage of 'concurrency', with
233
- * the percentage value in [0..INT_MAX] instead of [0..1].
229
+ * - the socket with the smallest busyness to be be picked for routing.
230
+ * - to give sockets with concurrency == 0 more priority (in general)
231
+ * over sockets with concurrency > 0.
232
+ * Therefore, in case of sockets with concurrency > 0, we describe our
233
+ * busyness as a percentage of 'concurrency', with the percentage value
234
+ * in [0..INT_MAX] instead of [0..1]. That way, the busyness value
235
+ * of sockets with concurrency > 0 is usually higher than that of sockets
236
+ * with concurrency == 0.
234
237
  */
235
238
  if (concurrency == 0) {
236
- // Allows Process.sessionSockets to give
237
- // idle sockets more priority.
238
- if (sessions == 0) {
239
- return 0;
240
- } else {
241
- return 1;
242
- }
239
+ return sessions;
243
240
  } else {
244
241
  return (int) (((long long) sessions * INT_MAX) / (double) concurrency);
245
242
  }
@@ -0,0 +1,422 @@
1
+ /*
2
+ * Phusion Passenger - https://www.phusionpassenger.com/
3
+ * Copyright (c) 2011-2015 Phusion Holding B.V.
4
+ *
5
+ * "Passenger", "Phusion Passenger" and "Union Station" are registered
6
+ * trademarks of Phusion Holding B.V.
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ #ifndef _PASSENGER_CORE_CONTROLLER_H_
28
+ #define _PASSENGER_CORE_CONTROLLER_H_
29
+
30
+
31
+ //#define DEBUG_CC_EVENT_LOOP_BLOCKING
32
+
33
+ #define CC_BENCHMARK_POINT(client, req, value) \
34
+ do { \
35
+ if (OXT_UNLIKELY(benchmarkMode == value)) { \
36
+ writeBenchmarkResponse(&client, &req); \
37
+ return; \
38
+ } \
39
+ } while (false)
40
+
41
+
42
+ #include <boost/shared_ptr.hpp>
43
+ #include <boost/make_shared.hpp>
44
+ #include <boost/cstdint.hpp>
45
+ #include <oxt/macros.hpp>
46
+ #include <ev++.h>
47
+ #include <ostream>
48
+
49
+ #if defined(__GLIBCXX__) || defined(__APPLE__)
50
+ #include <cxxabi.h>
51
+ #define CXX_ABI_API_AVAILABLE
52
+ #endif
53
+
54
+ #include <sys/types.h>
55
+ #include <sys/uio.h>
56
+ #include <utility>
57
+ #include <typeinfo>
58
+ #include <cstdio>
59
+ #include <cstdlib>
60
+ #include <cstddef>
61
+ #include <cassert>
62
+ #include <cctype>
63
+
64
+ #include <Logging.h>
65
+ #include <MessageReadersWriters.h>
66
+ #include <Constants.h>
67
+ #include <ServerKit/Errors.h>
68
+ #include <ServerKit/HttpServer.h>
69
+ #include <ServerKit/HttpHeaderParser.h>
70
+ #include <MemoryKit/palloc.h>
71
+ #include <DataStructures/LString.h>
72
+ #include <DataStructures/StringKeyTable.h>
73
+ #include <StaticString.h>
74
+ #include <Utils.h>
75
+ #include <Utils/StrIntUtils.h>
76
+ #include <Utils/IOUtils.h>
77
+ #include <Utils/JsonUtils.h>
78
+ #include <Utils/HttpConstants.h>
79
+ #include <Utils/VariantMap.h>
80
+ #include <Utils/Timer.h>
81
+ #include <Core/ApplicationPool/ErrorRenderer.h>
82
+ #include <Core/Controller/Client.h>
83
+ #include <Core/Controller/AppResponse.h>
84
+ #include <Core/Controller/TurboCaching.h>
85
+ #include <Core/UnionStation/Context.h>
86
+
87
+ namespace Passenger {
88
+
89
+ using namespace std;
90
+ using namespace boost;
91
+ using namespace oxt;
92
+ using namespace ApplicationPool2;
93
+
94
+
95
+ namespace ServerKit {
96
+ extern const HashedStaticString HTTP_COOKIE;
97
+ extern const HashedStaticString HTTP_SET_COOKIE;
98
+ }
99
+
100
+ namespace Core {
101
+
102
+
103
+ class Controller: public ServerKit::HttpServer<Controller, Client> {
104
+ public:
105
+ enum BenchmarkMode {
106
+ BM_NONE,
107
+ BM_AFTER_ACCEPT,
108
+ BM_BEFORE_CHECKOUT,
109
+ BM_AFTER_CHECKOUT,
110
+ BM_RESPONSE_BEGIN,
111
+ BM_UNKNOWN
112
+ };
113
+
114
+ private:
115
+ typedef ServerKit::HttpServer<Controller, Client> ParentClass;
116
+ typedef ServerKit::Channel Channel;
117
+ typedef ServerKit::FdSinkChannel FdSinkChannel;
118
+ typedef ServerKit::FdSourceChannel FdSourceChannel;
119
+ typedef ServerKit::FileBufferedChannel FileBufferedChannel;
120
+ typedef ServerKit::FileBufferedFdSinkChannel FileBufferedFdSinkChannel;
121
+
122
+ static const unsigned int MAX_SESSION_CHECKOUT_TRY = 10;
123
+
124
+ unsigned int statThrottleRate;
125
+ unsigned int responseBufferHighWatermark;
126
+ BenchmarkMode benchmarkMode: 3;
127
+ bool singleAppMode: 1;
128
+ bool showVersionInHeader: 1;
129
+ bool stickySessions: 1;
130
+ bool gracefulExit: 1;
131
+
132
+ const VariantMap *agentsOptions;
133
+ psg_pool_t *stringPool;
134
+ StringKeyTable< boost::shared_ptr<Options> > poolOptionsCache;
135
+
136
+ StaticString defaultRuby;
137
+ StaticString ustRouterAddress;
138
+ StaticString ustRouterPassword;
139
+ StaticString defaultUser;
140
+ StaticString defaultGroup;
141
+ StaticString defaultServerName;
142
+ StaticString defaultServerPort;
143
+ StaticString serverSoftware;
144
+ StaticString defaultStickySessionsCookieName;
145
+ StaticString defaultVaryTurbocacheByCookie;
146
+
147
+ HashedStaticString PASSENGER_APP_GROUP_NAME;
148
+ HashedStaticString PASSENGER_ENV_VARS;
149
+ HashedStaticString PASSENGER_MAX_REQUESTS;
150
+ HashedStaticString PASSENGER_STICKY_SESSIONS;
151
+ HashedStaticString PASSENGER_STICKY_SESSIONS_COOKIE_NAME;
152
+ HashedStaticString PASSENGER_REQUEST_OOB_WORK;
153
+ HashedStaticString UNION_STATION_SUPPORT;
154
+ HashedStaticString REMOTE_ADDR;
155
+ HashedStaticString REMOTE_PORT;
156
+ HashedStaticString REMOTE_USER;
157
+ HashedStaticString FLAGS;
158
+ HashedStaticString HTTP_COOKIE;
159
+ HashedStaticString HTTP_DATE;
160
+ HashedStaticString HTTP_HOST;
161
+ HashedStaticString HTTP_CONTENT_LENGTH;
162
+ HashedStaticString HTTP_CONTENT_TYPE;
163
+ HashedStaticString HTTP_EXPECT;
164
+ HashedStaticString HTTP_CONNECTION;
165
+ HashedStaticString HTTP_STATUS;
166
+ HashedStaticString HTTP_TRANSFER_ENCODING;
167
+
168
+ unsigned int threadNumber;
169
+ StaticString serverLogName;
170
+
171
+ friend class TurboCaching<Request>;
172
+ friend class ResponseCache<Request>;
173
+ struct ev_check checkWatcher;
174
+ TurboCaching<Request> turboCaching;
175
+
176
+ #ifdef DEBUG_CC_EVENT_LOOP_BLOCKING
177
+ struct ev_prepare prepareWatcher;
178
+ ev_tstamp timeBeforeBlocking;
179
+ #endif
180
+
181
+
182
+ /****** Stage: initiatelize request ******/
183
+
184
+ struct RequestAnalysis;
185
+
186
+ void initializeFlags(Client *client, Request *req, RequestAnalysis &analysis);
187
+ bool respondFromTurboCache(Client *client, Request *req);
188
+ void initializePoolOptions(Client *client, Request *req, RequestAnalysis &analysis);
189
+ void fillPoolOptionsFromAgentsOptions(Options &options);
190
+ static void fillPoolOption(Request *req, StaticString &field,
191
+ const HashedStaticString &name);
192
+ static void fillPoolOption(Request *req, int &field,
193
+ const HashedStaticString &name);
194
+ static void fillPoolOption(Request *req, bool &field,
195
+ const HashedStaticString &name);
196
+ static void fillPoolOption(Request *req, unsigned int &field,
197
+ const HashedStaticString &name);
198
+ static void fillPoolOption(Request *req, unsigned long &field,
199
+ const HashedStaticString &name);
200
+ static void fillPoolOption(Request *req, long &field,
201
+ const HashedStaticString &name);
202
+ static void fillPoolOptionSecToMsec(Request *req, unsigned int &field,
203
+ const HashedStaticString &name);
204
+ void createNewPoolOptions(Client *client, Request *req,
205
+ const HashedStaticString &appGroupName);
206
+ void initializeUnionStation(Client *client, Request *req, RequestAnalysis &analysis);
207
+ void setStickySessionId(Client *client, Request *req);
208
+ const LString *getStickySessionCookieName(Request *req);
209
+
210
+
211
+ /****** Stage: buffering body ******/
212
+
213
+ void beginBufferingBody(Client *client, Request *req);
214
+ Channel::Result whenBufferingBody_onRequestBody(Client *client, Request *req,
215
+ const MemoryKit::mbuf &buffer, int errcode);
216
+
217
+
218
+ /****** Stage: checkout session ******/
219
+
220
+ void checkoutSession(Client *client, Request *req);
221
+ static void sessionCheckedOut(const SessionPtr &session,
222
+ const ExceptionPtr &e, void *userData);
223
+ void sessionCheckedOutFromAnotherThread(Client *client, Request *req,
224
+ SessionPtr session, ExceptionPtr e);
225
+ void sessionCheckedOutFromEventLoopThread(Client *client, Request *req,
226
+ const SessionPtr &session, const ExceptionPtr &e);
227
+ void maybeSend100Continue(Client *client, Request *req);
228
+ void initiateSession(Client *client, Request *req);
229
+ static void checkoutSessionLater(Request *req);
230
+ void reportSessionCheckoutError(Client *client, Request *req,
231
+ const ExceptionPtr &e);
232
+ void writeRequestQueueFullExceptionErrorResponse(Client *client,
233
+ Request *req, const boost::shared_ptr<RequestQueueFullException> &e);
234
+ void writeSpawnExceptionErrorResponse(Client *client, Request *req,
235
+ const boost::shared_ptr<SpawnException> &e);
236
+ void writeOtherExceptionErrorResponse(Client *client, Request *req,
237
+ const ExceptionPtr &e);
238
+ void endRequestWithErrorResponse(Client **c, Request **r,
239
+ const StaticString &message, const SpawnException *e = NULL);
240
+ bool friendlyErrorPagesEnabled(Request *req);
241
+
242
+
243
+ /****** Stage: send request to application ******/
244
+
245
+ struct SessionProtocolWorkingState;
246
+ struct HttpHeaderConstructionCache;
247
+
248
+ void sendHeaderToApp(Client *client, Request *req);
249
+ void sendHeaderToAppWithSessionProtocol(Client *client, Request *req);
250
+ static void sendBodyToAppWhenAppSinkIdle(Channel *_channel, unsigned int size);
251
+ unsigned int determineHeaderSizeForSessionProtocol(Request *req,
252
+ SessionProtocolWorkingState &state, string delta_monotonic);
253
+ bool constructHeaderForSessionProtocol(Request *req, char * restrict buffer,
254
+ unsigned int &size, const SessionProtocolWorkingState &state, string delta_monotonic);
255
+ void sendHeaderToAppWithHttpProtocol(Client *client, Request *req);
256
+ bool constructHeaderBuffersForHttpProtocol(Request *req, struct iovec *buffers,
257
+ unsigned int maxbuffers, unsigned int & restrict_ref nbuffers,
258
+ unsigned int & restrict_ref dataSize, HttpHeaderConstructionCache &cache);
259
+ bool sendHeaderToAppWithHttpProtocolAndWritev(Request *req, ssize_t &bytesWritten,
260
+ HttpHeaderConstructionCache &cache);
261
+ void sendHeaderToAppWithHttpProtocolWithBuffering(Request *req, unsigned int offset,
262
+ HttpHeaderConstructionCache &cache);
263
+ void sendBodyToApp(Client *client, Request *req);
264
+ void halfCloseAppSink(Client *client, Request *req);
265
+ Channel::Result whenSendingRequest_onRequestBody(Client *client, Request *req,
266
+ const MemoryKit::mbuf &buffer, int errcode);
267
+ static void resumeRequestBodyChannelWhenAppSinkIdle(Channel *_channel,
268
+ unsigned int size);
269
+ void startBodyChannel(Client *client, Request *req);
270
+ void stopBodyChannel(Client *client, Request *req);
271
+ void logAppSocketWriteError(Client *client, int errcode);
272
+
273
+
274
+ /****** Stage: forward application response to client ******/
275
+
276
+ static Channel::Result _onAppSourceData(Channel *_channel,
277
+ const MemoryKit::mbuf &buffer, int errcode);
278
+ Channel::Result onAppSourceData(Client *client, Request *req,
279
+ const MemoryKit::mbuf &buffer, int errcode);
280
+ void onAppResponseBegin(Client *client, Request *req);
281
+ void prepareAppResponseCaching(Client *client, Request *req);
282
+ void onAppResponse100Continue(Client *client, Request *req);
283
+ bool constructHeaderBuffersForResponse(Request *req, struct iovec *buffers,
284
+ unsigned int maxbuffers, unsigned int & restrict_ref nbuffers,
285
+ unsigned int & restrict_ref dataSize,
286
+ unsigned int & restrict_ref nCacheableBuffers);
287
+ unsigned int constructDateHeaderBuffersForResponse(char *dateStr,
288
+ unsigned int bufsize);
289
+ bool sendResponseHeaderWithWritev(Client *client, Request *req,
290
+ ssize_t &bytesWritten);
291
+ void sendResponseHeaderWithBuffering(Client *client, Request *req,
292
+ unsigned int offset);
293
+ void logResponseHeaders(Client *client, Request *req, struct iovec *buffers,
294
+ unsigned int nbuffers, unsigned int dataSize);
295
+ void markHeaderBuffersForTurboCaching(Client *client, Request *req,
296
+ struct iovec *buffers, unsigned int nbuffers);
297
+ static ServerKit::HttpHeaderParser<AppResponse, ServerKit::HttpParseResponse>
298
+ createAppResponseHeaderParser(ServerKit::Context *ctx, Request *req);
299
+ static ServerKit::HttpChunkedBodyParser createAppResponseChunkedBodyParser(
300
+ Request *req);
301
+ static unsigned int formatAppResponseChunkedBodyParserLoggingPrefix(char *buf,
302
+ unsigned int bufsize, void *userData);
303
+ void prepareAppResponseChunkedBodyParsing(Client *client, Request *req);
304
+ void writeResponseAndMarkForTurboCaching(Client *client, Request *req,
305
+ const MemoryKit::mbuf &buffer);
306
+ void markResponsePartForTurboCaching(Client *client, Request *req,
307
+ const MemoryKit::mbuf &buffer);
308
+ void maybeThrottleAppSource(Client *client, Request *req);
309
+ static void _outputBuffersFlushed(FileBufferedChannel *_channel);
310
+ void outputBuffersFlushed(Client *client, Request *req);
311
+ static void _outputDataFlushed(FileBufferedChannel *_channel);
312
+ void outputDataFlushed(Client *client, Request *req);
313
+ void handleAppResponseBodyEnd(Client *client, Request *req);
314
+ OXT_FORCE_INLINE void keepAliveAppConnection(Client *client, Request *req);
315
+ void storeAppResponseInTurboCache(Client *client, Request *req);
316
+ void finalizeUnionStationWithSuccess(Client *client, Request *req);
317
+
318
+
319
+ /***** Hooks ******/
320
+
321
+ static Channel::Result onBodyBufferData(Channel *_channel,
322
+ const MemoryKit::mbuf &buffer, int errcode);
323
+ #ifdef DEBUG_CC_EVENT_LOOP_BLOCKING
324
+ static void onEventLoopPrepare(EV_P_ struct ev_prepare *w, int revents);
325
+ #endif
326
+ static void onEventLoopCheck(EV_P_ struct ev_check *w, int revents);
327
+
328
+
329
+ /****** Internal utility functions ******/
330
+
331
+ static TurboCaching<Request>::State getTurboCachingInitialState(
332
+ const VariantMap *agentsOptions);
333
+ void generateServerLogName(unsigned int number);
334
+ void disconnectWithClientSocketWriteError(Client **client, int e);
335
+ void disconnectWithAppSocketIncompleteResponseError(Client **client);
336
+ void disconnectWithAppSocketReadError(Client **client, int e);
337
+ void disconnectWithAppSocketWriteError(Client **client, int e);
338
+ void endRequestWithAppSocketIncompleteResponse(Client **client,
339
+ Request **req);
340
+ void endRequestWithAppSocketReadError(Client **client, Request **req,
341
+ int e);
342
+ void endRequestWithSimpleResponse(Client **c, Request **r,
343
+ const StaticString &body, int code = 200);
344
+ void endRequestAsBadGateway(Client **client, Request **req);
345
+ void writeBenchmarkResponse(Client **client, Request **req,
346
+ bool end = true);
347
+ bool getBoolOption(Request *req, const HashedStaticString &name,
348
+ bool defaultValue = false);
349
+ template<typename Number> static Number clamp(Number value,
350
+ Number min, Number max);
351
+ static void gatherBuffers(char * restrict dest, unsigned int size,
352
+ const struct iovec *buffers, unsigned int nbuffers);
353
+ static LString *resolveSymlink(const StaticString &path, psg_pool_t *pool);
354
+ void parseCookieHeader(psg_pool_t *pool, const LString *headerValue,
355
+ vector< pair<StaticString, StaticString> > &cookies) const;
356
+ #ifdef DEBUG_CC_EVENT_LOOP_BLOCKING
357
+ void reportLargeTimeDiff(Client *client, const char *name,
358
+ ev_tstamp fromTime, ev_tstamp toTime);
359
+ #endif
360
+
361
+
362
+ protected:
363
+ /****** Stage: initiatelize request ******/
364
+
365
+ virtual void onRequestBegin(Client *client, Request *req);
366
+
367
+
368
+ /****** Hooks ******/
369
+
370
+ virtual void onClientAccepted(Client *client);
371
+ virtual void onRequestObjectCreated(Client *client, Request *req);
372
+ virtual void deinitializeClient(Client *client);
373
+ virtual void reinitializeRequest(Client *client, Request *req);
374
+ virtual void deinitializeRequest(Client *client, Request *req);
375
+ void reinitializeAppResponse(Client *client, Request *req);
376
+ void deinitializeAppResponse(Client *client, Request *req);
377
+ virtual Channel::Result onRequestBody(Client *client, Request *req,
378
+ const MemoryKit::mbuf &buffer, int errcode);
379
+ virtual bool shouldDisconnectClientOnShutdown(Client *client);
380
+ virtual bool supportsUpgrade(Client *client, Request *req);
381
+
382
+
383
+ public:
384
+ ResourceLocator *resourceLocator;
385
+ PoolPtr appPool;
386
+ UnionStation::ContextPtr unionStationContext;
387
+
388
+
389
+ /****** Initialization and shutdown ******/
390
+
391
+ Controller(ServerKit::Context *context, const VariantMap *_agentsOptions,
392
+ unsigned int _threadNumber = 1);
393
+ ~Controller();
394
+ void initialize();
395
+
396
+
397
+ /****** Hooks ******/
398
+
399
+ virtual unsigned int getClientName(const Client *client, char *buf, size_t size) const;
400
+ virtual StaticString getServerName() const;
401
+
402
+
403
+ /****** State inspection and configuration ******/
404
+
405
+ virtual Json::Value getConfigAsJson() const;
406
+ virtual void configure(const Json::Value &doc);
407
+ virtual Json::Value inspectStateAsJson() const;
408
+ virtual Json::Value inspectClientStateAsJson(const Client *client) const;
409
+ virtual Json::Value inspectRequestStateAsJson(const Request *req) const;
410
+
411
+
412
+ /****** Miscellaneous *******/
413
+
414
+ static BenchmarkMode parseBenchmarkMode(const StaticString mode);
415
+ void disconnectLongRunningConnections(const StaticString &gupid);
416
+ };
417
+
418
+
419
+ } // namespace Core
420
+ } // namespace Passenger
421
+
422
+ #endif /* _PASSENGER_CORE_CONTROLLER_H_ */