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
@@ -51,6 +51,7 @@
51
51
  #include <Logging.h>
52
52
  #include <Exceptions.h>
53
53
  #include <StaticString.h>
54
+ #include <Hooks.h>
54
55
  #include <ResourceLocator.h>
55
56
  #include <Utils.h>
56
57
  #include <Utils/Base64.h>
@@ -427,81 +428,16 @@ inferDefaultGroup(const string &defaultUser) {
427
428
  return getGroupName(userEntry->pw_gid);
428
429
  }
429
430
 
430
- static vector< pair<string, string> >
431
- agentsOptionsToEnvVars(const VariantMap &agentsOptions) {
432
- vector< pair<string, string> > result;
433
- VariantMap::ConstIterator it, end = agentsOptions.end();
434
-
435
- result.reserve(agentsOptions.size());
436
- for (it = agentsOptions.begin(); it != end; it++) {
437
- result.push_back(make_pair("passenger_" + it->first, it->second));
438
- }
439
-
440
- return result;
441
- }
442
-
443
431
  static void
444
- setEnvVarsFromVector(const vector< pair<string, string> > &envvars) {
445
- vector< pair<string, string> >::const_iterator it;
446
-
447
- for (it = envvars.begin(); it != envvars.end(); it++) {
448
- setenv(it->first.c_str(), it->second.c_str(), 1);
449
- }
450
- }
451
-
452
- static bool
453
- runHookScript(const char *name) {
432
+ runHookScriptAndThrowOnError(const char *name) {
454
433
  TRACE_POINT();
455
- string value = agentsOptions.get(string("hook_") + name, false);
456
- if (value.empty()) {
457
- return true;
458
- }
459
-
460
- vector< pair<string, string> > envvars = agentsOptionsToEnvVars(agentsOptions);
461
- pid_t pid;
462
- int e, status;
463
-
464
- P_INFO("Running " << name << " hook script: " << value);
465
-
466
- pid = fork();
467
- if (pid == 0) {
468
- resetSignalHandlersAndMask();
469
- disableMallocDebugging();
470
- closeAllFileDescriptors(2);
471
- setEnvVarsFromVector(envvars);
434
+ HookScriptOptions options;
472
435
 
473
- execlp(value.c_str(), value.c_str(), (const char * const) 0);
474
- e = errno;
475
- fprintf(stderr, "*** ERROR: Cannot execute %s hook script %s: %s (errno=%d)\n",
476
- name, value.c_str(), strerror(e), e);
477
- fflush(stderr);
478
- _exit(1);
479
- return true; // Never reached.
436
+ options.name = name;
437
+ options.spec = agentsOptions.get(string("hook_") + name, false);
438
+ options.agentsOptions = &agentsOptions;
480
439
 
481
- } else if (pid == -1) {
482
- e = errno;
483
- P_ERROR("Cannot fork a process for hook script " << value <<
484
- ": " << strerror(e) << " (errno=" << e << ")");
485
- return false;
486
-
487
- } else if (waitpid(pid, &status, 0) == -1) {
488
- e = errno;
489
- P_ERROR("Unable to wait for hook script " << value <<
490
- " (PID " << pid << "): " << strerror(e) << " (errno=" <<
491
- e << ")");
492
- return false;
493
-
494
- } else {
495
- P_INFO("Hook script " << value << " (PID " << pid <<
496
- ") exited with status " << WEXITSTATUS(status));
497
- return WEXITSTATUS(status) == 0;
498
- }
499
- }
500
-
501
- static void
502
- runHookScriptAndThrowOnError(const char *name) {
503
- TRACE_POINT();
504
- if (!runHookScript(name)) {
440
+ if (!runHookScripts(options)) {
505
441
  throw RuntimeException(string("Hook script ") + name + " failed");
506
442
  }
507
443
  }
@@ -551,8 +487,8 @@ initializeOptions() {
551
487
  .setDefault ("default_ruby", DEFAULT_RUBY)
552
488
  .setDefault ("default_python", DEFAULT_PYTHON)
553
489
  .setDefaultInt ("max_pool_size", DEFAULT_MAX_POOL_SIZE)
554
- .setDefaultInt ("max_instances_per_app", DEFAULT_MAX_INSTANCES_PER_APP)
555
490
  .setDefaultInt ("pool_idle_time", DEFAULT_POOL_IDLE_TIME);
491
+ agentsOptions.set ("passenger_version", PASSENGER_VERSION);
556
492
 
557
493
  // Check for required options
558
494
  UPDATE_TRACE_POINT();
@@ -90,6 +90,17 @@ u_char int_buf[32], *end, *buf, *pos;
90
90
 
91
91
 
92
92
 
93
+ if (conf->max_instances_per_app != NGX_CONF_UNSET) {
94
+ end = ngx_snprintf(int_buf,
95
+ sizeof(int_buf) - 1,
96
+ "%d",
97
+ conf->max_instances_per_app);
98
+ len += 24;
99
+ len += end - int_buf + 1;
100
+ }
101
+
102
+
103
+
93
104
  if (conf->max_requests != NGX_CONF_UNSET) {
94
105
  end = ngx_snprintf(int_buf,
95
106
  sizeof(int_buf) - 1,
@@ -308,7 +319,7 @@ buf = pos = ngx_pnalloc(cf->pool, len);
308
319
 
309
320
  if (conf->min_instances != NGX_CONF_UNSET) {
310
321
  pos = ngx_copy(pos,
311
- "PASSENGER_MIN_INSTANCES",
322
+ "PASSENGER_MIN_PROCESSES",
312
323
  24);
313
324
  end = ngx_snprintf(int_buf,
314
325
  sizeof(int_buf) - 1,
@@ -323,6 +334,23 @@ buf = pos = ngx_pnalloc(cf->pool, len);
323
334
 
324
335
 
325
336
 
337
+ if (conf->max_instances_per_app != NGX_CONF_UNSET) {
338
+ pos = ngx_copy(pos,
339
+ "PASSENGER_MAX_PROCESSES",
340
+ 24);
341
+ end = ngx_snprintf(int_buf,
342
+ sizeof(int_buf) - 1,
343
+ "%d",
344
+ conf->max_instances_per_app);
345
+ pos = ngx_copy(pos,
346
+ int_buf,
347
+ end - int_buf);
348
+ *pos = '\0';
349
+ pos++;
350
+ }
351
+
352
+
353
+
326
354
  if (conf->max_requests != NGX_CONF_UNSET) {
327
355
  pos = ngx_copy(pos,
328
356
  "PASSENGER_MAX_REQUESTS",
@@ -78,7 +78,6 @@ passenger_create_main_conf(ngx_conf_t *cf)
78
78
  conf->debug_log_file.len = 0;
79
79
  conf->abort_on_startup_error = NGX_CONF_UNSET;
80
80
  conf->max_pool_size = (ngx_uint_t) NGX_CONF_UNSET;
81
- conf->max_instances_per_app = (ngx_uint_t) NGX_CONF_UNSET;
82
81
  conf->pool_idle_time = (ngx_uint_t) NGX_CONF_UNSET;
83
82
  conf->user_switching = NGX_CONF_UNSET;
84
83
  conf->default_user.data = NULL;
@@ -137,10 +136,6 @@ passenger_init_main_conf(ngx_conf_t *cf, void *conf_pointer)
137
136
  conf->max_pool_size = DEFAULT_MAX_POOL_SIZE;
138
137
  }
139
138
 
140
- if (conf->max_instances_per_app == (ngx_uint_t) NGX_CONF_UNSET) {
141
- conf->max_instances_per_app = DEFAULT_MAX_INSTANCES_PER_APP;
142
- }
143
-
144
139
  if (conf->pool_idle_time == (ngx_uint_t) NGX_CONF_UNSET) {
145
140
  conf->pool_idle_time = DEFAULT_POOL_IDLE_TIME;
146
141
  }
@@ -972,13 +967,6 @@ const ngx_command_t passenger_commands[] = {
972
967
  offsetof(passenger_main_conf_t, max_pool_size),
973
968
  NULL },
974
969
 
975
- { ngx_string("passenger_max_instances_per_app"),
976
- NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
977
- ngx_conf_set_num_slot,
978
- NGX_HTTP_MAIN_CONF_OFFSET,
979
- offsetof(passenger_main_conf_t, max_instances_per_app),
980
- NULL },
981
-
982
970
  { ngx_string("passenger_pool_idle_time"),
983
971
  NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
984
972
  ngx_conf_set_num_slot,
@@ -57,7 +57,6 @@ typedef struct {
57
57
  ngx_str_t temp_dir;
58
58
  ngx_flag_t abort_on_startup_error;
59
59
  ngx_uint_t max_pool_size;
60
- ngx_uint_t max_instances_per_app;
61
60
  ngx_uint_t pool_idle_time;
62
61
  ngx_flag_t user_switching;
63
62
  ngx_str_t default_user;
@@ -109,6 +109,16 @@
109
109
  NULL
110
110
  },
111
111
 
112
+ {
113
+
114
+ ngx_string("passenger_max_instances_per_app"),
115
+ NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
116
+ ngx_conf_set_num_slot,
117
+ NGX_HTTP_LOC_CONF_OFFSET,
118
+ offsetof(passenger_loc_conf_t, max_instances_per_app),
119
+ NULL
120
+ },
121
+
112
122
  {
113
123
 
114
124
  ngx_string("passenger_max_requests"),
@@ -49,6 +49,8 @@
49
49
 
50
50
  ngx_int_t load_shell_envvars;
51
51
 
52
+ ngx_int_t max_instances_per_app;
53
+
52
54
  ngx_int_t max_preloader_idle_time;
53
55
 
54
56
  ngx_int_t max_request_queue_size;
@@ -72,6 +72,10 @@
72
72
 
73
73
 
74
74
 
75
+ conf->max_instances_per_app = NGX_CONF_UNSET;
76
+
77
+
78
+
75
79
  conf->max_requests = NGX_CONF_UNSET;
76
80
 
77
81
 
@@ -82,6 +82,12 @@
82
82
 
83
83
 
84
84
 
85
+ ngx_conf_merge_value(conf->max_instances_per_app,
86
+ prev->max_instances_per_app,
87
+ NGX_CONF_UNSET);
88
+
89
+
90
+
85
91
  ngx_conf_merge_value(conf->max_requests,
86
92
  prev->max_requests,
87
93
  NGX_CONF_UNSET);
@@ -718,7 +718,13 @@ syscalls::waitpid(pid_t pid, int *status, int options) {
718
718
  *************************************/
719
719
 
720
720
  #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
721
- __thread bool this_thread::_syscalls_interruptable = true;
721
+ /* This variable is an int instead of a bool, because a bug in GCC 4.6
722
+ * can cause segmentation faults for bool TLS variables.
723
+ * https://code.google.com/p/phusion-passenger/issues/detail?id=902
724
+ * http://stackoverflow.com/questions/20410943/segmentation-fault-when-accessing-statically-initialized-thread-variable?noredirect=1#comment30483943_20410943
725
+ * https://bugzilla.redhat.com/show_bug.cgi?id=731228
726
+ */
727
+ __thread int this_thread::_syscalls_interruptable = 1;
722
728
 
723
729
  bool
724
730
  this_thread::syscalls_interruptable() {
@@ -188,7 +188,7 @@ namespace this_thread {
188
188
  * @intern
189
189
  */
190
190
  #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
191
- extern __thread bool _syscalls_interruptable;
191
+ extern __thread int _syscalls_interruptable;
192
192
  #else
193
193
  extern thread_specific_ptr<bool> _syscalls_interruptable;
194
194
  #endif
@@ -211,8 +211,8 @@ namespace this_thread {
211
211
  public:
212
212
  enable_syscall_interruption() {
213
213
  #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
214
- last_value = _syscalls_interruptable;
215
- _syscalls_interruptable = true;
214
+ last_value = !!_syscalls_interruptable;
215
+ _syscalls_interruptable = 1;
216
216
  #else
217
217
  if (_syscalls_interruptable.get() == NULL) {
218
218
  last_value = true;
@@ -246,8 +246,8 @@ namespace this_thread {
246
246
  public:
247
247
  disable_syscall_interruption() {
248
248
  #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
249
- last_value = _syscalls_interruptable;
250
- _syscalls_interruptable = false;
249
+ last_value = !!_syscalls_interruptable;
250
+ _syscalls_interruptable = 0;
251
251
  #else
252
252
  if (_syscalls_interruptable.get() == NULL) {
253
253
  last_value = true;
@@ -274,11 +274,11 @@ namespace this_thread {
274
274
  */
275
275
  class restore_syscall_interruption {
276
276
  private:
277
- int last_value;
277
+ bool last_value;
278
278
  public:
279
279
  restore_syscall_interruption(const disable_syscall_interruption &intr) {
280
280
  #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
281
- last_value = _syscalls_interruptable;
281
+ last_value = !!_syscalls_interruptable;
282
282
  _syscalls_interruptable = intr.last_value;
283
283
  #else
284
284
  assert(_syscalls_interruptable.get() != NULL);
@@ -128,6 +128,9 @@ function installServer() {
128
128
  if (!PhusionPassenger._appInstalled) {
129
129
  PhusionPassenger._appInstalled = true;
130
130
  PhusionPassenger._server = server;
131
+ server.address = function() {
132
+ return 'passenger';
133
+ }
131
134
  finalizeStartup();
132
135
 
133
136
  PhusionPassenger.on('request', function(headers, socket, bodyBegin) {
@@ -149,6 +152,7 @@ function installServer() {
149
152
  server.once('listening', callback);
150
153
  }
151
154
  server.emit('listening');
155
+ return server;
152
156
  } else {
153
157
  throw new Error("http.Server.listen() was called more than once, which " +
154
158
  "is not allowed because Phusion Passenger is in auto-install mode. " +
@@ -162,12 +166,12 @@ function installServer() {
162
166
  function listenAndMaybeInstall(port) {
163
167
  if (port === 'passenger') {
164
168
  if (!PhusionPassenger._appInstalled) {
165
- installServer.apply(this, arguments);
169
+ return installServer.apply(this, arguments);
166
170
  } else {
167
171
  throw new Error("You may only call listen('passenger') once");
168
172
  }
169
173
  } else {
170
- this.originalListen.apply(this, arguments);
174
+ return this.originalListen.apply(this, arguments);
171
175
  }
172
176
  }
173
177
 
@@ -69,9 +69,12 @@ module App
69
69
  LoaderSharedHelpers.run_load_path_setup_code(options)
70
70
  LoaderSharedHelpers.before_loading_app_code_step2(options)
71
71
 
72
- require 'rubygems'
72
+ begin
73
+ require 'rubygems'
74
+ rescue LoadError
75
+ end
73
76
  require 'rack'
74
- rackup_file = ENV["RACKUP_FILE"] || options["rackup_file"] || "config.ru"
77
+ rackup_file = options["startup_file"] || "config.ru"
75
78
  rackup_code = ::File.open(rackup_file, 'rb') do |f|
76
79
  f.read
77
80
  end
@@ -96,9 +96,12 @@ module App
96
96
  LoaderSharedHelpers.run_load_path_setup_code(options)
97
97
  LoaderSharedHelpers.before_loading_app_code_step2(options)
98
98
 
99
- require 'rubygems'
99
+ begin
100
+ require 'rubygems'
101
+ rescue LoadError
102
+ end
100
103
  require 'rack'
101
- rackup_file = ENV["RACKUP_FILE"] || options["rackup_file"] || "config.ru"
104
+ rackup_file = options["startup_file"] || "config.ru"
102
105
  rackup_code = ::File.open(rackup_file, 'rb') do |f|
103
106
  f.read
104
107
  end
@@ -30,7 +30,7 @@ module PhusionPassenger
30
30
 
31
31
  PACKAGE_NAME = 'passenger'
32
32
  # Run 'rake ext/common/Constants.h' after changing this number.
33
- VERSION_STRING = '4.0.27'
33
+ VERSION_STRING = '4.0.28'
34
34
 
35
35
  PREFERRED_NGINX_VERSION = '1.4.4'
36
36
  NGINX_SHA256_CHECKSUM = '7c989a58e5408c9593da0bebcd0e4ffc3d892d1316ba5042ddb0be5b0b4102b9'
@@ -88,8 +88,16 @@ APACHE2_DIRECTORY_CONFIGURATION_OPTIONS = [
88
88
  :type => :integer,
89
89
  :context => ["OR_LIMIT", "ACCESS_CONF", "RSRC_CONF"],
90
90
  :min_value => 0,
91
+ :header => "PASSENGER_MIN_PROCESSES",
91
92
  :desc => "The minimum number of application instances to keep when cleaning idle instances."
92
93
  },
94
+ {
95
+ :name => "PassengerMaxInstancesPerApp",
96
+ :type => :integer,
97
+ :context => ["RSRC_CONF"],
98
+ :header => "PASSENGER_MAX_PROCESSES",
99
+ :desc => "The maximum number of simultaneously alive application instances a single application may occupy."
100
+ },
93
101
  {
94
102
  :name => "PassengerUser",
95
103
  :type => :string,
@@ -41,7 +41,6 @@ module PhusionPassenger
41
41
  DEFAULT_MAX_POOL_SIZE = 6
42
42
  DEFAULT_POOL_IDLE_TIME = 300
43
43
  DEFAULT_START_TIMEOUT = 90_000
44
- DEFAULT_MAX_INSTANCES_PER_APP = 0
45
44
  DEFAULT_WEB_APP_USER = "nobody"
46
45
  DEFAULT_CONCURRENCY_MODEL = "process"
47
46
  DEFAULT_THREAD_COUNT = 1
@@ -114,8 +114,15 @@ LOCATION_CONFIGURATION_OPTIONS = [
114
114
  :type => :flag
115
115
  },
116
116
  {
117
- :name => 'passenger_min_instances',
118
- :type => :integer
117
+ :name => 'passenger_min_instances',
118
+ :type => :integer,
119
+ :header => 'PASSENGER_MIN_PROCESSES'
120
+ },
121
+ {
122
+ :name => 'passenger_max_instances_per_app',
123
+ :context => [:main],
124
+ :type => :integer,
125
+ :header => 'PASSENGER_MAX_PROCESSES'
119
126
  },
120
127
  {
121
128
  :name => 'passenger_max_requests',
@@ -1,3 +1,4 @@
1
+ # encoding: binary
1
2
  # Phusion Passenger - https://www.phusionpassenger.com/
2
3
  # Copyright (c) 2010-2013 Phusion
3
4
  #
@@ -184,7 +185,7 @@ module PlatformInfo
184
185
 
185
186
  def self.httpd_actual_error_log(options = nil)
186
187
  if config_file = httpd_default_config_file(options)
187
- contents = File.read(config_file)
188
+ contents = File.open(config_file, "rb") { |f| f.read }
188
189
  # We don't want to match comments
189
190
  contents.gsub!(/^[ \t]*#.*/, '')
190
191
  if contents =~ /^ErrorLog (.+)$/
@@ -130,7 +130,7 @@ private
130
130
  command = create_compiler_command(language,
131
131
  "-c '#{filename}' -o '#{filename}.o'",
132
132
  '-feliminate-unused-debug-symbols -feliminate-unused-debug-types')
133
- result = run_compiler("Checking for #{compiler_type_name} compiler '--feliminate-unused-debug-{symbols,types}' support",
133
+ result = run_compiler("Checking for #{compiler_type_name} compiler '-feliminate-unused-debug-{symbols,types}' support",
134
134
  command, filename, '', true)
135
135
  return result && result[:output].empty?
136
136
  ensure
@@ -427,6 +427,20 @@ public
427
427
  end
428
428
  memoize :adress_sanitizer_flag
429
429
 
430
+ def self.cxx_11_flag
431
+ source = %Q{
432
+ #include <unordered_map>
433
+ }
434
+ if try_compile("Checking for C++ -std=gnu++11 compiler flag", :cxx, source, '-std=gnu++11')
435
+ return "-std=gnu++11"
436
+ elsif try_compile("Checking for C++ -std=c++11 compiler flag", :cxx, source, '-std=c++')
437
+ return "-std=c++11"
438
+ else
439
+ return nil
440
+ end
441
+ end
442
+ memoize :cxx_11_flag, true
443
+
430
444
  def self.has_rt_library?
431
445
  return try_link("Checking for -lrt support",
432
446
  :c, "int main() { return 0; }\n", '-lrt')