passenger 4.0.27 → 4.0.28

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 (156) hide show
  1. data.tar.gz.asc +7 -7
  2. data/.gitignore +1 -0
  3. data/NEWS +22 -0
  4. data/build/preprocessor.rb +10 -0
  5. data/build/rpm.rb +74 -65
  6. data/debian.template/rules.template +8 -0
  7. data/dev/copy_boost_headers.rb +11 -2
  8. data/doc/Users guide Apache.idmap.txt +161 -145
  9. data/doc/Users guide Apache.txt +12 -1
  10. data/doc/Users guide Nginx.idmap.txt +142 -126
  11. data/doc/Users guide Nginx.txt +14 -1
  12. data/doc/Users guide Standalone.txt +1 -0
  13. data/doc/users_guide_snippets/environment_variables.txt +1 -1
  14. data/doc/users_guide_snippets/installation.txt +2 -0
  15. data/doc/users_guide_snippets/tips.txt +118 -0
  16. data/ext/apache2/Configuration.cpp +0 -6
  17. data/ext/apache2/Configuration.hpp +0 -5
  18. data/ext/apache2/ConfigurationCommands.cpp +7 -0
  19. data/ext/apache2/ConfigurationFields.hpp +2 -0
  20. data/ext/apache2/ConfigurationSetters.cpp +24 -0
  21. data/ext/apache2/CreateDirConfig.cpp +1 -0
  22. data/ext/apache2/Hooks.cpp +0 -1
  23. data/ext/apache2/MergeDirConfig.cpp +7 -0
  24. data/ext/apache2/SetHeaders.cpp +5 -1
  25. data/ext/boost/cregex.hpp +39 -0
  26. data/ext/boost/libs/regex/src/c_regex_traits.cpp +193 -0
  27. data/ext/boost/libs/regex/src/cpp_regex_traits.cpp +117 -0
  28. data/ext/boost/libs/regex/src/cregex.cpp +660 -0
  29. data/ext/boost/libs/regex/src/instances.cpp +32 -0
  30. data/ext/boost/libs/regex/src/internals.hpp +35 -0
  31. data/ext/boost/libs/regex/src/posix_api.cpp +296 -0
  32. data/ext/boost/libs/regex/src/regex.cpp +227 -0
  33. data/ext/boost/libs/regex/src/regex_debug.cpp +59 -0
  34. data/ext/boost/libs/regex/src/regex_raw_buffer.cpp +72 -0
  35. data/ext/boost/libs/regex/src/regex_traits_defaults.cpp +692 -0
  36. data/ext/boost/libs/regex/src/static_mutex.cpp +179 -0
  37. data/ext/boost/libs/regex/src/wc_regex_traits.cpp +301 -0
  38. data/ext/boost/libs/regex/src/wide_posix_api.cpp +315 -0
  39. data/ext/boost/libs/regex/src/winstances.cpp +35 -0
  40. data/ext/boost/regex.h +100 -0
  41. data/ext/boost/regex.hpp +37 -0
  42. data/ext/boost/regex/concepts.hpp +1128 -0
  43. data/ext/boost/regex/config.hpp +435 -0
  44. data/ext/boost/regex/config/borland.hpp +72 -0
  45. data/ext/boost/regex/config/cwchar.hpp +207 -0
  46. data/ext/boost/regex/mfc.hpp +190 -0
  47. data/ext/boost/regex/pattern_except.hpp +100 -0
  48. data/ext/boost/regex/pending/object_cache.hpp +165 -0
  49. data/ext/boost/regex/pending/static_mutex.hpp +179 -0
  50. data/ext/boost/regex/pending/unicode_iterator.hpp +776 -0
  51. data/ext/boost/regex/regex_traits.hpp +35 -0
  52. data/ext/boost/regex/user.hpp +93 -0
  53. data/ext/boost/regex/v4/basic_regex.hpp +782 -0
  54. data/ext/boost/regex/v4/basic_regex_creator.hpp +1571 -0
  55. data/ext/boost/regex/v4/basic_regex_parser.hpp +2874 -0
  56. data/ext/boost/regex/v4/c_regex_traits.hpp +211 -0
  57. data/ext/boost/regex/v4/char_regex_traits.hpp +81 -0
  58. data/ext/boost/regex/v4/cpp_regex_traits.hpp +1099 -0
  59. data/ext/boost/regex/v4/cregex.hpp +330 -0
  60. data/ext/boost/regex/v4/error_type.hpp +59 -0
  61. data/ext/boost/regex/v4/fileiter.hpp +455 -0
  62. data/ext/boost/regex/v4/instances.hpp +222 -0
  63. data/ext/boost/regex/v4/iterator_category.hpp +91 -0
  64. data/ext/boost/regex/v4/iterator_traits.hpp +135 -0
  65. data/ext/boost/regex/v4/match_flags.hpp +138 -0
  66. data/ext/boost/regex/v4/match_results.hpp +702 -0
  67. data/ext/boost/regex/v4/mem_block_cache.hpp +99 -0
  68. data/ext/boost/regex/v4/perl_matcher.hpp +587 -0
  69. data/ext/boost/regex/v4/perl_matcher_common.hpp +996 -0
  70. data/ext/boost/regex/v4/perl_matcher_non_recursive.hpp +1642 -0
  71. data/ext/boost/regex/v4/perl_matcher_recursive.hpp +991 -0
  72. data/ext/boost/regex/v4/primary_transform.hpp +146 -0
  73. data/ext/boost/regex/v4/protected_call.hpp +81 -0
  74. data/ext/boost/regex/v4/regbase.hpp +180 -0
  75. data/ext/boost/regex/v4/regex.hpp +202 -0
  76. data/ext/boost/regex/v4/regex_format.hpp +1156 -0
  77. data/ext/boost/regex/v4/regex_fwd.hpp +73 -0
  78. data/ext/boost/regex/v4/regex_grep.hpp +155 -0
  79. data/ext/boost/regex/v4/regex_iterator.hpp +201 -0
  80. data/ext/boost/regex/v4/regex_match.hpp +382 -0
  81. data/ext/boost/regex/v4/regex_merge.hpp +93 -0
  82. data/ext/boost/regex/v4/regex_raw_buffer.hpp +210 -0
  83. data/ext/boost/regex/v4/regex_replace.hpp +99 -0
  84. data/ext/boost/regex/v4/regex_search.hpp +217 -0
  85. data/ext/boost/regex/v4/regex_split.hpp +172 -0
  86. data/ext/boost/regex/v4/regex_token_iterator.hpp +342 -0
  87. data/ext/boost/regex/v4/regex_traits.hpp +189 -0
  88. data/ext/boost/regex/v4/regex_traits_defaults.hpp +371 -0
  89. data/ext/boost/regex/v4/regex_workaround.hpp +232 -0
  90. data/ext/boost/regex/v4/states.hpp +301 -0
  91. data/ext/boost/regex/v4/sub_match.hpp +512 -0
  92. data/ext/boost/regex/v4/syntax_type.hpp +105 -0
  93. data/ext/boost/regex/v4/u32regex_iterator.hpp +193 -0
  94. data/ext/boost/regex/v4/u32regex_token_iterator.hpp +377 -0
  95. data/ext/boost/regex/v4/w32_regex_traits.hpp +741 -0
  96. data/ext/boost/regex_fwd.hpp +33 -0
  97. data/ext/common/AgentsStarter.h +0 -11
  98. data/ext/common/ApplicationPool2/Common.h +1 -7
  99. data/ext/common/ApplicationPool2/DirectSpawner.h +3 -3
  100. data/ext/common/ApplicationPool2/Group.h +166 -69
  101. data/ext/common/ApplicationPool2/Implementation.cpp +55 -10
  102. data/ext/common/ApplicationPool2/Options.h +45 -10
  103. data/ext/common/ApplicationPool2/PipeWatcher.h +1 -2
  104. data/ext/common/ApplicationPool2/Pool.h +29 -7
  105. data/ext/common/ApplicationPool2/Process.h +22 -3
  106. data/ext/common/ApplicationPool2/Session.h +1 -0
  107. data/ext/common/ApplicationPool2/SmartSpawner.h +5 -10
  108. data/ext/common/ApplicationPool2/Spawner.h +10 -15
  109. data/ext/common/ApplicationPool2/SuperGroup.h +10 -9
  110. data/ext/common/Constants.h +1 -3
  111. data/ext/common/Hooks.h +193 -0
  112. data/ext/common/Logging.cpp +67 -2
  113. data/ext/common/Logging.h +23 -1
  114. data/ext/common/Utils.cpp +0 -21
  115. data/ext/common/Utils.h +0 -42
  116. data/ext/common/Utils/CachedFileStat.hpp +1 -1
  117. data/ext/common/Utils/StrIntUtils.h +61 -14
  118. data/ext/common/Utils/StringMap.h +4 -0
  119. data/ext/common/agents/HelperAgent/AgentOptions.h +4 -4
  120. data/ext/common/agents/HelperAgent/Main.cpp +2 -3
  121. data/ext/common/agents/HelperAgent/RequestHandler.h +65 -2
  122. data/ext/common/agents/LoggingAgent/FilterSupport.h +3 -1
  123. data/ext/common/agents/Watchdog/Main.cpp +8 -72
  124. data/ext/nginx/CacheLocationConfig.c +29 -1
  125. data/ext/nginx/Configuration.c +0 -12
  126. data/ext/nginx/Configuration.h +0 -1
  127. data/ext/nginx/ConfigurationCommands.c +10 -0
  128. data/ext/nginx/ConfigurationFields.h +2 -0
  129. data/ext/nginx/CreateLocationConfig.c +4 -0
  130. data/ext/nginx/MergeLocationConfig.c +6 -0
  131. data/ext/oxt/system_calls.cpp +7 -1
  132. data/ext/oxt/system_calls.hpp +7 -7
  133. data/helper-scripts/node-loader.js +6 -2
  134. data/helper-scripts/rack-loader.rb +5 -2
  135. data/helper-scripts/rack-preloader.rb +5 -2
  136. data/lib/phusion_passenger.rb +1 -1
  137. data/lib/phusion_passenger/apache2/config_options.rb +8 -0
  138. data/lib/phusion_passenger/constants.rb +0 -1
  139. data/lib/phusion_passenger/nginx/config_options.rb +9 -2
  140. data/lib/phusion_passenger/platform_info/apache.rb +2 -1
  141. data/lib/phusion_passenger/platform_info/compiler.rb +15 -1
  142. data/lib/phusion_passenger/platform_info/cxx_portability.rb +2 -0
  143. data/node_lib/phusion_passenger/httplib_emulation.js +85 -17
  144. data/node_lib/phusion_passenger/request_handler.js +10 -2
  145. data/rpm/Vagrantfile +32 -0
  146. data/rpm/get_distro_id.py +4 -0
  147. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +2 -2
  148. data/test/cxx/ApplicationPool2/PoolTest.cpp +60 -9
  149. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +2 -6
  150. data/test/cxx/CachedFileStatTest.cpp +5 -5
  151. data/test/cxx/RequestHandlerTest.cpp +3 -6
  152. data/test/cxx/UtilsTest.cpp +30 -0
  153. data/test/node/httplib_emulation_spec.js +491 -0
  154. data/test/node/spec_helper.js +25 -0
  155. metadata +78 -2
  156. metadata.gz.asc +7 -7
@@ -102,6 +102,7 @@ Here is an example configuration file:
102
102
  ------------------
103
103
 
104
104
 
105
+ [[advanced_configuration]]
105
106
  === Advanced configuration
106
107
 
107
108
  Phusion Passenger Standalone is built on the same technology that powers link:Users%20guide%20Nginx.html[Phusion Passenger for Nginx], so any configuration option supported by Phusion Passenger for Nginx can be applied to Standalone as well. You can do this by editing the Standalone configuration template directly.
@@ -226,7 +226,7 @@ PATH=/usr/bin:/usr/local/bin
226
226
  You can pass environment variables to Phusion Passenger-served apps through various methods:
227
227
 
228
228
  * When running Apache, use the `PassEnv` and `SetEnv` directives of link:http://httpd.apache.org/docs/2.4/mod/mod_env.html[mod_env]. This is supported starting from Phusion Passenger 4.0.
229
- * When running Nginx, use the `env` directive. Unlike Apache, Nginx's `env` directive can only be set globally and cannot be customized on a per-virtual host basis.
229
+ * When running Nginx, use the <<passenger_set_cgi_param,passenger_set_cgi_param>> directive.
230
230
  * Through your `bashrc`. Starting from version 4.0, Phusion Passenger 4.0 spawns applications through bash and inherit all bash environment variables. Phusion Passenger Standalone tends to be started from the shell and thus inherits all environment variables set by the shell.
231
231
  * Through Apache and Nginx, as described earlier in this chapter. Any environment variables that you set on Apache and Nginx itself are inherited by Phusion Passenger, and thus by Phusion Passenger-served apps as well.
232
232
  * Through the application itself. Most programming languages provide APIs for setting environment variables. For example in Ruby you can write:
@@ -191,6 +191,8 @@ endif::[]
191
191
 
192
192
  === Installing or upgrading on Red Hat, Fedora, CentOS or ScientificLinux
193
193
 
194
+ WARNING: The RPMs are currently unmaintained. As such, the repository only contains Phusion Passenger 3.x (the latest version is 4.x), which did not support Node.js, Meteor, multiple Rubies, etc. For more recent versions of Phusion Passenger, you are suggested to install from gem or tarball instead.
195
+
194
196
  YUM repositories with RPMs are maintained by link:https://github.com/erikogan/passenger[Erik Ogan] and link:http://stealthymonkeys.com/[Stealthy Monkeys Consulting]. Only packages for the open source version of Phusion Passenger are provided. link:https://www.phusionpassenger.com/enterprise[Phusion Passenger Enterprise] customers should use the <<rubygems_generic_install,generic RubyGems installation method>> or <<tarball_generic_install,the generic tarball installation method>> instead.
195
197
 
196
198
  If you use YUM to install Phusion Passenger then you do not need to run `passenger-install-apache2-module` or `passenger-install-nginx-module`. The YUM packages contain all the binaries that you need. You also don't need to modify any Apache or Nginx configuration to get them to load Phusion Passenger, the packages provide configuration snippets for you as well.
@@ -386,6 +386,124 @@ References:
386
386
 
387
387
  - link:http://blog.phusion.nl/2013/01/22/phusion-passenger-4-technology-preview-out-of-band-work/[The Phusion Blog article which first introduced this feature.]
388
388
 
389
+ === Hooks
390
+
391
+ :version: 4.0.28
392
+ include::since_version.txt[]
393
+
394
+ Phusion Passenger provides a powerful but simple hooking system, which allows you to extend many aspects of Phusion Passenger's behavior. The hooking system works by executing commands during certain events. Event parameters are passed to the command in the form of environment variables.
395
+
396
+ ifdef::apache[]
397
+ You can define hooks by setting the configuration option `PassengerCtl hook_<HOOK NAME> <COMMAND TO EXECUTE>`.
398
+ endif::apache[]
399
+ ifdef::nginx[]
400
+ You can define hooks by setting the configuration option `passenger_ctl hook_<HOOK NAME> <COMMAND TO EXECUTE>;`.
401
+ endif::nginx[]
402
+ ifdef::standalone[]
403
+ You can define hooks by <<advanced_configuration,editing the advanced configuration file>>, and adding the configuration option `passenger_ctl hook_<HOOK NAME> <COMMAND TO EXECUTE>;`.
404
+ endif::standalone[]
405
+
406
+ ==== Example
407
+
408
+ The hook system is best demonstrated with a simple example. In the following example we will hook into the `attached_process` event. This event is called whenever Phusion Passenger has successfully spawned an application processes and added it to the process pool. We print the process's PID and application root.
409
+
410
+ First, let's create a script `/home/phusion/attached.sh` which is to be called during the hook.
411
+
412
+ [source,sh]
413
+ ---------------------------------------------------
414
+ #!/bin/sh
415
+ echo "Attached process $PASSENGER_PROCESS_PID for app $PASSENGER_APP_ROOT."
416
+ ---------------------------------------------------
417
+
418
+ Then we make it executable:
419
+
420
+ ---------------------------------------------------
421
+ chmod +x /home/phusion/attached.sh
422
+ ---------------------------------------------------
423
+
424
+ And we define the hook in the configuration file:
425
+
426
+ ifdef::apache[]
427
+ ---------------------------------------------------
428
+ PassengerCtl hook_attached_process /home/phusion/attached.sh
429
+ ---------------------------------------------------
430
+ endif::apache[]
431
+ ifdef::nginx[]
432
+ ---------------------------------------------------
433
+ passenger_ctl hook_attached_process /home/phusion/attached.sh;
434
+ ---------------------------------------------------
435
+ endif::nginx[]
436
+ ifdef::standalone[]
437
+ ---------------------------------------------------
438
+ passenger_ctl hook_attached_process /home/phusion/attached.sh;
439
+ ---------------------------------------------------
440
+ endif::standalone[]
441
+
442
+ Now restart the web server and access a web app hosted by Phusion Passenger. You should see our message in the web server error log:
443
+
444
+ ---------------------------------------------------
445
+ [ 2013-12-10 16:12:21.6456 28934/0x1064cb000 Hooks.h:129 ]: Running attached_process hook script: /home/phusion/attached.sh
446
+ Attached process 28303 for app /webapps/foobar.
447
+ [ 2013-12-10 16:12:21.6580 28934/0x1064cb000 Hooks.h:161 ]: Hook script /home/phusion/attached.sh (PID 28948) exited with status 0
448
+ ---------------------------------------------------
449
+
450
+ ==== Environment
451
+
452
+ A lot of information is passed to hook scripts in the form of environment variables. They are all uppercase and begin with `PASSENGER_`. Some environment variables are passed to all hook scripts, others are passed depending on the hook.
453
+
454
+ Here are some of the environment variables which are passed to all hooks, unless documented otherwise:
455
+
456
+ * `PASSENGER_VERSION`
457
+ * `PASSENGER_PASSENGER_ROOT`
458
+ * `PASSENGER_SERVER_INSTANCE_DIR`
459
+ * `PASSENGER_GENERATION_PATH`
460
+
461
+ ==== Blocking and concurrency
462
+
463
+ All hooks block. That is, Phusion Passenger waits until your hook command is finished. You should therefore be careful when writing hook scripts: if your script never finishes, so Phusion Passenger does not do that either.
464
+
465
+ If you have a bug in your script and it blocks, then you will be able to see that using the command `passenger-status --show=backtraces` which prints the backtraces of all threads in the Phusion Passenger HelperAgent. Look for the `runSingleHookScript` function in the backtrace. The following example shows at line 2 that Phusion Passenger is waiting for the hook script `/home/phusion/badscript.sh`.
466
+
467
+ ---------------------------------------------------------------------------------------------------
468
+ Thread 'Group process spawner: /home/phusion/webapp.test#default' (0x1062d4000):
469
+ in 'bool Passenger::runSingleHookScript(Passenger::HookScriptOptions &, const string &, const vector<pair<string, string> > &)' (Hooks.h:116) -- /home/phusion/badscript.sh
470
+ in 'bool Passenger::runHookScripts(Passenger::HookScriptOptions &)' (Hooks.h:159)
471
+ in 'void Passenger::ApplicationPool2::Group::spawnThreadRealMain(const SpawnerPtr &, const Passenger::ApplicationPool2::Options &, unsigned int)' (Implementation.cpp:878)
472
+ ---------------------------------------------------------------------------------------------------
473
+
474
+ Hooks may be called concurrently. For example, while the `attached_process` hook is being called, a `detached_process` hook may be called, perhaps even for the same application. It is your responsibility to ensure that your hook scripts are concurrency-safe, e.g. by employing locks and other concurrency control techniques.
475
+
476
+ ==== Error handling
477
+
478
+ If a hook script fails -- that is, if it exits with anything other than exit code 0 -- then the error handling depends on the hook. Some hooks will abort, other hooks will ignore the error. In all cases, the result of the hook script is printed to the log.
479
+
480
+ ==== Available hooks
481
+
482
+ `before_watchdog_initialization`::
483
+ Called at the very beginning of Phusion Passenger's life cycle, during the start of the Watchdog process. The first hook is called before initialization is performed (before the HelperAgent is started). Errors in the hook script cause Phusion Passenger to abort.
484
+ `after_watchdog_initialization`::
485
+ Like `before_watchdog_initialization`, but called after initialization of all Phusion Passenger agent processes. Errors in the hook script cause Phusion Passenger to abort.
486
+ `attached_process`::
487
+ Called when Phusion Passenger has successfully spawned an application processes and added it to the process pool. Extra environment variables: `PASSENGER_PROCESS_PID`, `PASSENGER_APP_ROOT`. Errors in the hook script are ignored.
488
+ `detached_process`::
489
+ Called when Phusion Passenger has removed an application process from the process pool. This could happen when:
490
+ +
491
+ - The process has crashed, and Phusion Passenger noticed it.
492
+ - Phusion Passenger has shut down a process because it's been idle for too long.
493
+ - The administrator configured different resource limits, and Phusion Passenger is starting or shutting down processes in response.
494
+ - Phusion Passenger itself is shutting down.
495
+ +
496
+ Extra environment variables: `PASSENGER_PROCESS_PID`, `PASSENGER_APP_ROOT`. Errors in the hook script are ignored.
497
+
498
+ `after_initialize_supergroup`::
499
+ Called right after Phusion Passenger has allocated data structures for an application, and is about to spawn a process for the first time for this application. Errors in the hook script are ignored. Extra environment variables: `PASSENGER_APP_ROOT`.
500
+ `before_destroy_supergroup`::
501
+ Called right before Phusion Passenger decallocates data structures for an application. Errors in the hook script are ignored.
502
+ +
503
+ Note that the `after_initialize_supergroup` hook may be called while this hook is still being executed, so make sure that operations don't conflict with each other.
504
+ +
505
+ Extra environment variables: `PASSENGER_APP_ROOT`.
506
+
389
507
  [[flying_passenger]]
390
508
  === Flying Passenger
391
509
  :version: 4.0.6
@@ -251,7 +251,6 @@ DEFINE_SERVER_STR_CONFIG_SETTER(cmd_passenger_default_ruby, defaultRuby)
251
251
  DEFINE_SERVER_INT_CONFIG_SETTER(cmd_passenger_log_level, logLevel, unsigned int, 0)
252
252
  DEFINE_SERVER_STR_CONFIG_SETTER(cmd_passenger_debug_log_file, debugLogFile)
253
253
  DEFINE_SERVER_INT_CONFIG_SETTER(cmd_passenger_max_pool_size, maxPoolSize, unsigned int, 1)
254
- DEFINE_SERVER_INT_CONFIG_SETTER(cmd_passenger_max_instances_per_app, maxInstancesPerApp, unsigned int, 0)
255
254
  DEFINE_SERVER_INT_CONFIG_SETTER(cmd_passenger_pool_idle_time, poolIdleTime, unsigned int, 0)
256
255
  DEFINE_SERVER_BOOLEAN_CONFIG_SETTER(cmd_passenger_user_switching, userSwitching)
257
256
  DEFINE_SERVER_STR_CONFIG_SETTER(cmd_passenger_default_user, defaultUser)
@@ -444,11 +443,6 @@ const command_rec passenger_commands[] = {
444
443
  NULL,
445
444
  RSRC_CONF,
446
445
  "The maximum number of simultaneously alive application instances."),
447
- AP_INIT_TAKE1("PassengerMaxInstancesPerApp",
448
- (Take1Func) cmd_passenger_max_instances_per_app,
449
- NULL,
450
- RSRC_CONF,
451
- "The maximum number of simultaneously alive application instances a single application may occupy."),
452
446
  AP_INIT_TAKE1("PassengerPoolIdleTime",
453
447
  (Take1Func) cmd_passenger_pool_idle_time,
454
448
  NULL,
@@ -260,10 +260,6 @@ struct ServerConfig {
260
260
  * instances. */
261
261
  unsigned int maxPoolSize;
262
262
 
263
- /** The maximum number of simultaneously alive Rails application
264
- * that a single Rails application may occupy. */
265
- unsigned int maxInstancesPerApp;
266
-
267
263
  /** The maximum number of seconds that an application may be
268
264
  * idle before it gets terminated. */
269
265
  unsigned int poolIdleTime;
@@ -296,7 +292,6 @@ struct ServerConfig {
296
292
  logLevel = DEFAULT_LOG_LEVEL;
297
293
  debugLogFile = NULL;
298
294
  maxPoolSize = DEFAULT_MAX_POOL_SIZE;
299
- maxInstancesPerApp = DEFAULT_MAX_INSTANCES_PER_APP;
300
295
  poolIdleTime = DEFAULT_POOL_IDLE_TIME;
301
296
  userSwitching = true;
302
297
  defaultUser = DEFAULT_WEB_APP_USER;
@@ -89,6 +89,13 @@
89
89
  "The minimum number of application instances to keep when cleaning idle instances."),
90
90
 
91
91
 
92
+ AP_INIT_TAKE1("PassengerMaxInstancesPerApp",
93
+ (Take1Func) cmd_passenger_max_instances_per_app,
94
+ NULL,
95
+ RSRC_CONF,
96
+ "The maximum number of simultaneously alive application instances a single application may occupy."),
97
+
98
+
92
99
  AP_INIT_TAKE1("PassengerUser",
93
100
  (Take1Func) cmd_passenger_user,
94
101
  NULL,
@@ -48,6 +48,8 @@
48
48
  Threeway highPerformance;
49
49
  /** Whether to load environment variables from the shell before running the application. */
50
50
  Threeway loadShellEnvvars;
51
+ /** The maximum number of simultaneously alive application instances a single application may occupy. */
52
+ int maxInstancesPerApp;
51
53
  /** The maximum number of queued requests. */
52
54
  int maxRequestQueueSize;
53
55
  /** The maximum number of requests that an application instance may process. */
@@ -105,6 +105,30 @@
105
105
  }
106
106
 
107
107
 
108
+ static const char *
109
+ cmd_passenger_max_instances_per_app(cmd_parms *cmd, void *pcfg, const char *arg) {
110
+ DirConfig *config = (DirConfig *) pcfg;
111
+ char *end;
112
+ long result;
113
+
114
+ result = strtol(arg, &end, 10);
115
+ if (*end != '\0') {
116
+ string message = "Invalid number specified for ";
117
+ message.append(cmd->directive->directive);
118
+ message.append(".");
119
+
120
+ char *messageStr = (char *) apr_palloc(cmd->temp_pool,
121
+ message.size() + 1);
122
+ memcpy(messageStr, message.c_str(), message.size() + 1);
123
+ return messageStr;
124
+
125
+ } else {
126
+ config->maxInstancesPerApp = (int) result;
127
+ return NULL;
128
+ }
129
+ }
130
+
131
+
108
132
  static const char *
109
133
  cmd_passenger_user(cmd_parms *cmd, void *pcfg, const char *arg) {
110
134
  DirConfig *config = (DirConfig *) pcfg;
@@ -43,6 +43,7 @@
43
43
  config->nodejs = NULL;
44
44
  config->appEnv = NULL;
45
45
  config->minInstances = UNSET_INT_VALUE;
46
+ config->maxInstancesPerApp = UNSET_INT_VALUE;
46
47
  config->user = NULL;
47
48
  config->group = NULL;
48
49
  config->errorOverride = DirConfig::UNSET;
@@ -1281,7 +1281,6 @@ public:
1281
1281
  .set ("default_ruby", serverConfig.defaultRuby)
1282
1282
  .setInt ("max_pool_size", serverConfig.maxPoolSize)
1283
1283
  .setInt ("pool_idle_time", serverConfig.poolIdleTime)
1284
- .setInt ("max_instances_per_app", serverConfig.maxInstancesPerApp)
1285
1284
  .set ("analytics_log_user", serverConfig.analyticsLogUser)
1286
1285
  .set ("analytics_log_group", serverConfig.analyticsLogGroup)
1287
1286
  .set ("union_station_gateway_address", serverConfig.unionStationGatewayAddress)
@@ -75,6 +75,13 @@
75
75
 
76
76
 
77
77
 
78
+ config->maxInstancesPerApp =
79
+ (add->maxInstancesPerApp == UNSET_INT_VALUE) ?
80
+ base->maxInstancesPerApp :
81
+ add->maxInstancesPerApp;
82
+
83
+
84
+
78
85
  config->user =
79
86
  (add->user == NULL) ?
80
87
  base->user :
@@ -56,7 +56,11 @@
56
56
 
57
57
 
58
58
 
59
- addHeader(r, output, "PASSENGER_MIN_INSTANCES", config->minInstances);
59
+ addHeader(r, output, "PASSENGER_MIN_PROCESSES", config->minInstances);
60
+
61
+
62
+
63
+ addHeader(r, output, "PASSENGER_MAX_PROCESSES", config->maxInstancesPerApp);
60
64
 
61
65
 
62
66
 
@@ -0,0 +1,39 @@
1
+ /*
2
+ *
3
+ * Copyright (c) 1998-2002
4
+ * John Maddock
5
+ *
6
+ * Use, modification and distribution are subject to the
7
+ * Boost Software License, Version 1.0. (See accompanying file
8
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
+ *
10
+ */
11
+
12
+ /*
13
+ * LOCATION: see http://www.boost.org/libs/regex for most recent version.
14
+ * FILE cregex.cpp
15
+ * VERSION see <boost/version.hpp>
16
+ * DESCRIPTION: Declares POSIX API functions
17
+ * + boost::RegEx high level wrapper.
18
+ */
19
+
20
+ #ifndef BOOST_RE_CREGEX_HPP
21
+ #define BOOST_RE_CREGEX_HPP
22
+
23
+ #ifndef BOOST_REGEX_CONFIG_HPP
24
+ #include <boost/regex/config.hpp>
25
+ #endif
26
+
27
+ #include <boost/regex/v4/cregex.hpp>
28
+
29
+ #endif /* include guard */
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
@@ -0,0 +1,193 @@
1
+ /*
2
+ *
3
+ * Copyright (c) 2004
4
+ * John Maddock
5
+ *
6
+ * Use, modification and distribution are subject to the
7
+ * Boost Software License, Version 1.0. (See accompanying file
8
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
+ *
10
+ */
11
+
12
+ /*
13
+ * LOCATION: see http://www.boost.org for most recent version.
14
+ * FILE: c_regex_traits.cpp
15
+ * VERSION: see <boost/version.hpp>
16
+ * DESCRIPTION: Implements out of line c_regex_traits<char> members
17
+ */
18
+
19
+
20
+ #define BOOST_REGEX_SOURCE
21
+
22
+ #include <boost/config.hpp>
23
+ #include <boost/detail/workaround.hpp>
24
+ #include "internals.hpp"
25
+
26
+ #if !BOOST_WORKAROUND(__BORLANDC__, < 0x560)
27
+
28
+ #include <boost/regex/v4/c_regex_traits.hpp>
29
+ #include <boost/regex/v4/primary_transform.hpp>
30
+ #include <boost/regex/v4/regex_traits_defaults.hpp>
31
+
32
+ #ifdef BOOST_NO_STDC_NAMESPACE
33
+ namespace std{
34
+ using ::strxfrm; using ::isspace;
35
+ using ::ispunct; using ::isalpha;
36
+ using ::isalnum; using ::iscntrl;
37
+ using ::isprint; using ::isupper;
38
+ using ::islower; using ::isdigit;
39
+ using ::isxdigit; using ::strtol;
40
+ }
41
+ #endif
42
+
43
+ #ifdef BOOST_HAS_ABI_HEADERS
44
+ # include BOOST_ABI_PREFIX
45
+ #endif
46
+
47
+ namespace boost{
48
+
49
+ c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transform(const char* p1, const char* p2)
50
+ {
51
+ std::string result(10, ' ');
52
+ std::size_t s = result.size();
53
+ std::size_t r;
54
+ std::string src(p1, p2);
55
+ while(s < (r = std::strxfrm(&*result.begin(), src.c_str(), s)))
56
+ {
57
+ result.append(r - s + 3, ' ');
58
+ s = result.size();
59
+ }
60
+ result.erase(r);
61
+ return result;
62
+ }
63
+
64
+ c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transform_primary(const char* p1, const char* p2)
65
+ {
66
+ static char s_delim;
67
+ static const int s_collate_type = ::boost::re_detail::find_sort_syntax(static_cast<c_regex_traits<char>*>(0), &s_delim);
68
+ std::string result;
69
+ //
70
+ // What we do here depends upon the format of the sort key returned by
71
+ // sort key returned by this->transform:
72
+ //
73
+ switch(s_collate_type)
74
+ {
75
+ case ::boost::re_detail::sort_C:
76
+ case ::boost::re_detail::sort_unknown:
77
+ // the best we can do is translate to lower case, then get a regular sort key:
78
+ {
79
+ result.assign(p1, p2);
80
+ for(std::string::size_type i = 0; i < result.size(); ++i)
81
+ result[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(result[i])));
82
+ result = transform(&*result.begin(), &*result.begin() + result.size());
83
+ break;
84
+ }
85
+ case ::boost::re_detail::sort_fixed:
86
+ {
87
+ // get a regular sort key, and then truncate it:
88
+ result = transform(p1, p2);
89
+ result.erase(s_delim);
90
+ break;
91
+ }
92
+ case ::boost::re_detail::sort_delim:
93
+ // get a regular sort key, and then truncate everything after the delim:
94
+ result = transform(p1, p2);
95
+ if(result.size() && (result[0] == s_delim))
96
+ break;
97
+ std::size_t i;
98
+ for(i = 0; i < result.size(); ++i)
99
+ {
100
+ if(result[i] == s_delim)
101
+ break;
102
+ }
103
+ result.erase(i);
104
+ break;
105
+ }
106
+ if(result.empty())
107
+ result = std::string(1, char(0));
108
+ return result;
109
+ }
110
+
111
+ c_regex_traits<char>::char_class_type BOOST_REGEX_CALL c_regex_traits<char>::lookup_classname(const char* p1, const char* p2)
112
+ {
113
+ static const char_class_type masks[] =
114
+ {
115
+ 0,
116
+ char_class_alnum,
117
+ char_class_alpha,
118
+ char_class_blank,
119
+ char_class_cntrl,
120
+ char_class_digit,
121
+ char_class_digit,
122
+ char_class_graph,
123
+ char_class_horizontal,
124
+ char_class_lower,
125
+ char_class_lower,
126
+ char_class_print,
127
+ char_class_punct,
128
+ char_class_space,
129
+ char_class_space,
130
+ char_class_upper,
131
+ char_class_unicode,
132
+ char_class_upper,
133
+ char_class_vertical,
134
+ char_class_alnum | char_class_word,
135
+ char_class_alnum | char_class_word,
136
+ char_class_xdigit,
137
+ };
138
+
139
+ int idx = ::boost::re_detail::get_default_class_id(p1, p2);
140
+ if(idx < 0)
141
+ {
142
+ std::string s(p1, p2);
143
+ for(std::string::size_type i = 0; i < s.size(); ++i)
144
+ s[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(s[i])));
145
+ idx = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
146
+ }
147
+ BOOST_ASSERT(std::size_t(idx+1) < sizeof(masks) / sizeof(masks[0]));
148
+ return masks[idx+1];
149
+ }
150
+
151
+ bool BOOST_REGEX_CALL c_regex_traits<char>::isctype(char c, char_class_type mask)
152
+ {
153
+ return
154
+ ((mask & char_class_space) && (std::isspace)(static_cast<unsigned char>(c)))
155
+ || ((mask & char_class_print) && (std::isprint)(static_cast<unsigned char>(c)))
156
+ || ((mask & char_class_cntrl) && (std::iscntrl)(static_cast<unsigned char>(c)))
157
+ || ((mask & char_class_upper) && (std::isupper)(static_cast<unsigned char>(c)))
158
+ || ((mask & char_class_lower) && (std::islower)(static_cast<unsigned char>(c)))
159
+ || ((mask & char_class_alpha) && (std::isalpha)(static_cast<unsigned char>(c)))
160
+ || ((mask & char_class_digit) && (std::isdigit)(static_cast<unsigned char>(c)))
161
+ || ((mask & char_class_punct) && (std::ispunct)(static_cast<unsigned char>(c)))
162
+ || ((mask & char_class_xdigit) && (std::isxdigit)(static_cast<unsigned char>(c)))
163
+ || ((mask & char_class_blank) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::re_detail::is_separator(c))
164
+ || ((mask & char_class_word) && (c == '_'))
165
+ || ((mask & char_class_vertical) && (::boost::re_detail::is_separator(c) || (c == '\v')))
166
+ || ((mask & char_class_horizontal) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::re_detail::is_separator(c) && (c != '\v'));
167
+ }
168
+
169
+ c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::lookup_collatename(const char* p1, const char* p2)
170
+ {
171
+ std::string s(p1, p2);
172
+ s = ::boost::re_detail::lookup_default_collate_name(s);
173
+ if(s.empty() && (p2-p1 == 1))
174
+ s.append(1, *p1);
175
+ return s;
176
+ }
177
+
178
+ int BOOST_REGEX_CALL c_regex_traits<char>::value(char c, int radix)
179
+ {
180
+ char b[2] = { c, '\0', };
181
+ char* ep;
182
+ int result = std::strtol(b, &ep, radix);
183
+ if(ep == b)
184
+ return -1;
185
+ return result;
186
+ }
187
+
188
+ }
189
+ #ifdef BOOST_HAS_ABI_HEADERS
190
+ # include BOOST_ABI_SUFFIX
191
+ #endif
192
+
193
+ #endif