passenger 5.0.27 → 5.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.
- checksums.yaml +4 -4
- data/CHANGELOG +14 -1
- data/CONTRIBUTORS +2 -0
- data/Rakefile +6 -5
- data/build/agent.rb +1 -1
- data/build/basics.rb +6 -71
- data/build/misc.rb +2 -2
- data/build/nginx.rb +18 -1
- data/build/packaging.rb +3 -1
- data/build/{cplusplus_support.rb → support/cplusplus.rb} +0 -0
- data/build/{cxx_dependency_map.rb → support/cxx_dependency_map.rb} +72 -1
- data/build/support/general.rb +106 -0
- data/dev/ci/run_travis.sh +9 -0
- data/dev/vagrant/nginx_rakefile +1 -1
- data/src/agent/Core/ApplicationPool/Options.h +4 -0
- data/src/agent/Core/Controller/CheckoutSession.cpp +1 -2
- data/src/agent/Core/Controller/InitRequest.cpp +1 -0
- data/src/agent/Core/SpawningKit/DirectSpawner.h +12 -0
- data/src/agent/Core/SpawningKit/SmartSpawner.h +13 -2
- data/src/agent/Core/SpawningKit/Spawner.h +35 -0
- data/src/agent/Core/SpawningKit/UserSwitchingRules.h +12 -6
- data/src/apache2_module/ConfigurationCommands.cpp +7 -0
- data/src/apache2_module/ConfigurationFields.hpp +2 -0
- data/src/apache2_module/ConfigurationSetters.cpp +34 -0
- data/src/apache2_module/CreateDirConfig.cpp +1 -0
- data/src/apache2_module/MergeDirConfig.cpp +7 -0
- data/src/apache2_module/SetHeaders.cpp +5 -0
- data/src/cxx_supportlib/Constants.h +3 -1
- data/src/cxx_supportlib/Logging.h +11 -8
- data/src/cxx_supportlib/LveLoggingDecorator.h +92 -0
- data/src/cxx_supportlib/MemoryKit/mbuf.cpp +51 -16
- data/src/cxx_supportlib/MemoryKit/mbuf.h +27 -24
- data/src/cxx_supportlib/ServerKit/HttpServer.h +4 -0
- data/src/cxx_supportlib/vendor-copy/adhoc_lve.h +304 -0
- data/src/nginx_module/Configuration.c +8 -0
- data/src/nginx_module/config +26 -12
- data/src/ruby_supportlib/phusion_passenger.rb +8 -8
- data/src/ruby_supportlib/phusion_passenger/admin_tools/memory_stats.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +8 -0
- data/src/ruby_supportlib/phusion_passenger/common_library.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger/config/about_command.rb +26 -1
- data/src/ruby_supportlib/phusion_passenger/config/main.rb +2 -0
- data/src/ruby_supportlib/phusion_passenger/constants.rb +1 -0
- data/src/ruby_supportlib/phusion_passenger/packaging.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/platform_info/cxx_portability.rb +1 -0
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command/nginx_engine.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +2 -1
- metadata +7 -4
@@ -0,0 +1,106 @@
|
|
1
|
+
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
+
# Copyright (c) 2010-2016 Phusion Holding B.V.
|
3
|
+
#
|
4
|
+
# "Passenger", "Phusion Passenger" and "Union Station" are registered
|
5
|
+
# trademarks of Phusion Holding B.V.
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in
|
15
|
+
# all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
# THE SOFTWARE.
|
24
|
+
|
25
|
+
class TemplateRenderer
|
26
|
+
def initialize(filename)
|
27
|
+
require 'erb' if !defined?(ERB)
|
28
|
+
@erb = ERB.new(File.read(filename), nil, "-")
|
29
|
+
@erb.filename = filename
|
30
|
+
end
|
31
|
+
|
32
|
+
def render
|
33
|
+
return @erb.result(binding)
|
34
|
+
end
|
35
|
+
|
36
|
+
def render_to(filename)
|
37
|
+
puts "Creating #{filename}"
|
38
|
+
text = render
|
39
|
+
# When packaging, some timestamps may be modified. The user may not
|
40
|
+
# have write access to the source root (for example, when Passenger
|
41
|
+
# Standalone is compiling its runtime), so we only write to the file
|
42
|
+
# when necessary.
|
43
|
+
if !File.exist?(filename) || File.writable?(filename) || File.read(filename) != text
|
44
|
+
File.open(filename, 'w') do |f|
|
45
|
+
f.write(text)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Pathname
|
52
|
+
if !method_defined?(:/)
|
53
|
+
def /(other)
|
54
|
+
self + other.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def string_option(name, default_value = nil)
|
60
|
+
value = ENV[name]
|
61
|
+
if value.nil? || value.empty?
|
62
|
+
if default_value.respond_to?(:call)
|
63
|
+
default_value.call
|
64
|
+
else
|
65
|
+
default_value
|
66
|
+
end
|
67
|
+
else
|
68
|
+
value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def pathname_option(name, default_value)
|
73
|
+
Pathname.new(string_option(name, default_value))
|
74
|
+
end
|
75
|
+
|
76
|
+
def compiler_flag_option(name, default_value = '')
|
77
|
+
string_option(name, default_value).gsub("\n", " ")
|
78
|
+
end
|
79
|
+
|
80
|
+
def boolean_option(name, default_value = false)
|
81
|
+
value = ENV[name]
|
82
|
+
if value.nil? || value.empty?
|
83
|
+
default_value
|
84
|
+
else
|
85
|
+
value == "yes" || value == "on" || value == "true" || value == "1"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def maybe_wrap_in_ccache(command)
|
90
|
+
if boolean_option('USE_CCACHE', false) && command !~ /^ccache /
|
91
|
+
"ccache #{command}"
|
92
|
+
else
|
93
|
+
command
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def ensure_target_directory_exists(target)
|
98
|
+
dir = File.dirname(target)
|
99
|
+
if !File.exist?(dir)
|
100
|
+
sh "mkdir -p #{dir}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def shesc(path)
|
105
|
+
Shellwords.escape(path)
|
106
|
+
end
|
data/dev/ci/run_travis.sh
CHANGED
@@ -16,6 +16,8 @@ fi
|
|
16
16
|
|
17
17
|
COMPILE_CONCURRENCY=${COMPILE_CONCURRENCY:-2}
|
18
18
|
|
19
|
+
TEST_DYNAMIC_WITH_NGINX_VERSION=1.9.15
|
20
|
+
|
19
21
|
export VERBOSE=1
|
20
22
|
export TRACE=1
|
21
23
|
export DEVDEPS_DEFAULT=no
|
@@ -213,6 +215,13 @@ if [[ "$TEST_NGINX" = 1 ]]; then
|
|
213
215
|
install_node_and_modules
|
214
216
|
run ./bin/passenger-install-nginx-module --auto --prefix=/tmp/nginx --auto-download
|
215
217
|
run bundle exec drake -j$COMPILE_CONCURRENCY test:integration:nginx
|
218
|
+
|
219
|
+
run curl -sSLO http://www.nginx.org/download/nginx-$TEST_DYNAMIC_WITH_NGINX_VERSION.tar.gz
|
220
|
+
run tar zxf nginx-$TEST_DYNAMIC_WITH_NGINX_VERSION.tar.gz
|
221
|
+
run cd nginx-$TEST_DYNAMIC_WITH_NGINX_VERSION
|
222
|
+
run ./configure --add-dynamic-module=$(../bin/passenger-config --nginx-addon-dir)
|
223
|
+
run make
|
224
|
+
run cd ..
|
216
225
|
fi
|
217
226
|
|
218
227
|
if [[ "$TEST_APACHE2" = 1 ]]; then
|
data/dev/vagrant/nginx_rakefile
CHANGED
@@ -27,7 +27,7 @@ task :configure do
|
|
27
27
|
" --with-http_ssl_module" +
|
28
28
|
" --with-http_gzip_static_module" +
|
29
29
|
" --with-http_stub_status_module" +
|
30
|
-
" --with-
|
30
|
+
" --with-http_v2_module" +
|
31
31
|
" --with-ipv6" +
|
32
32
|
" --with-debug"
|
33
33
|
sh "sed", "-E", "-i", 's/ -O[0-9]? / -ggdb /g', "objs/Makefile"
|
@@ -237,6 +237,9 @@ public:
|
|
237
237
|
/** See class overview. Defaults to the defaultUser's primary group. */
|
238
238
|
StaticString defaultGroup;
|
239
239
|
|
240
|
+
/** Minimum user id starting from which entering LVE and CageFS is allowed. */
|
241
|
+
unsigned int lveMinUid;
|
242
|
+
|
240
243
|
/**
|
241
244
|
* The directory which contains restart.txt and always_restart.txt.
|
242
245
|
* An empty string means that the default directory should be used.
|
@@ -474,6 +477,7 @@ public:
|
|
474
477
|
baseURI("/", 1),
|
475
478
|
spawnMethod(DEFAULT_SPAWN_METHOD, sizeof(DEFAULT_SPAWN_METHOD) - 1),
|
476
479
|
defaultUser(PASSENGER_DEFAULT_USER, sizeof(PASSENGER_DEFAULT_USER) - 1),
|
480
|
+
lveMinUid(DEFAULT_LVE_MIN_UID),
|
477
481
|
integrationMode(DEFAULT_INTEGRATION_MODE, sizeof(DEFAULT_INTEGRATION_MODE) - 1),
|
478
482
|
ruby(DEFAULT_RUBY, sizeof(DEFAULT_RUBY) - 1),
|
479
483
|
python(DEFAULT_PYTHON, sizeof(DEFAULT_PYTHON) - 1),
|
@@ -378,8 +378,7 @@ Controller::friendlyErrorPagesEnabled(Request *req) {
|
|
378
378
|
bool defaultValue;
|
379
379
|
string defaultStr = agentsOptions->get("friendly_error_pages");
|
380
380
|
if (defaultStr == "auto") {
|
381
|
-
defaultValue = req->options.environment
|
382
|
-
&& req->options.environment != "production";
|
381
|
+
defaultValue = (req->options.environment == "development");
|
383
382
|
} else {
|
384
383
|
defaultValue = defaultStr == "true";
|
385
384
|
}
|
@@ -383,6 +383,7 @@ Controller::createNewPoolOptions(Client *client, Request *req,
|
|
383
383
|
fillPoolOption(req, options.loadShellEnvvars, "!~PASSENGER_LOAD_SHELL_ENVVARS");
|
384
384
|
fillPoolOption(req, options.fileDescriptorUlimit, "!~PASSENGER_APP_FILE_DESCRIPTOR_ULIMIT");
|
385
385
|
fillPoolOption(req, options.raiseInternalError, "!~PASSENGER_RAISE_INTERNAL_ERROR");
|
386
|
+
fillPoolOption(req, options.lveMinUid, "!~PASSENGER_LVE_MIN_UID");
|
386
387
|
/******************/
|
387
388
|
|
388
389
|
boost::shared_ptr<Options> optionsCopy = boost::make_shared<Options>(options);
|
@@ -28,9 +28,11 @@
|
|
28
28
|
|
29
29
|
#include <Core/SpawningKit/Spawner.h>
|
30
30
|
#include <Constants.h>
|
31
|
+
#include <LveLoggingDecorator.h>
|
31
32
|
#include <limits.h> // for PTHREAD_STACK_MIN
|
32
33
|
#include <pthread.h>
|
33
34
|
|
35
|
+
#include <adhoc_lve.h>
|
34
36
|
|
35
37
|
namespace Passenger {
|
36
38
|
namespace SpawningKit {
|
@@ -167,6 +169,14 @@ public:
|
|
167
169
|
preparation.userSwitching.gid);
|
168
170
|
pid_t pid;
|
169
171
|
|
172
|
+
adhoc_lve::LveEnter scopedLveEnter(LveLoggingDecorator::lveInitOnce(),
|
173
|
+
preparation.userSwitching.uid,
|
174
|
+
options.lveMinUid,
|
175
|
+
LveLoggingDecorator::lveExitCallback);
|
176
|
+
LveLoggingDecorator::logLveEnter(scopedLveEnter,
|
177
|
+
preparation.userSwitching.uid,
|
178
|
+
options.lveMinUid);
|
179
|
+
|
170
180
|
pid = syscalls::fork();
|
171
181
|
if (pid == 0) {
|
172
182
|
setenv("PASSENGER_DEBUG_DIR", debugDir->getPath().c_str(), 1);
|
@@ -203,6 +213,8 @@ public:
|
|
203
213
|
|
204
214
|
} else {
|
205
215
|
UPDATE_TRACE_POINT();
|
216
|
+
scopedLveEnter.exit();
|
217
|
+
|
206
218
|
P_LOG_FILE_DESCRIPTOR_PURPOSE(adminSocket.first,
|
207
219
|
"App " << pid << " (" << options.appRoot << ") adminSocket[0]");
|
208
220
|
P_LOG_FILE_DESCRIPTOR_PURPOSE(adminSocket.second,
|
@@ -29,6 +29,9 @@
|
|
29
29
|
#include <Core/SpawningKit/Spawner.h>
|
30
30
|
#include <Core/SpawningKit/PipeWatcher.h>
|
31
31
|
#include <Constants.h>
|
32
|
+
#include <LveLoggingDecorator.h>
|
33
|
+
|
34
|
+
#include <adhoc_lve.h>
|
32
35
|
|
33
36
|
namespace Passenger {
|
34
37
|
namespace SpawningKit {
|
@@ -212,9 +215,15 @@ private:
|
|
212
215
|
Pipe errorPipe = createPipe(__FILE__, __LINE__);
|
213
216
|
DebugDirPtr debugDir = boost::make_shared<DebugDir>(preparation.userSwitching.uid,
|
214
217
|
preparation.userSwitching.gid);
|
215
|
-
pid_t pid;
|
216
218
|
|
217
|
-
|
219
|
+
adhoc_lve::LveEnter scopedLveEnter(LveLoggingDecorator::lveInitOnce(),
|
220
|
+
preparation.userSwitching.uid,
|
221
|
+
options.lveMinUid,
|
222
|
+
LveLoggingDecorator::lveExitCallback);
|
223
|
+
LveLoggingDecorator::logLveEnter(scopedLveEnter,
|
224
|
+
preparation.userSwitching.uid,
|
225
|
+
options.lveMinUid);
|
226
|
+
pid_t pid = syscalls::fork();
|
218
227
|
if (pid == 0) {
|
219
228
|
setenv("PASSENGER_DEBUG_DIR", debugDir->getPath().c_str(), 1);
|
220
229
|
purgeStdio(stdout);
|
@@ -249,6 +258,8 @@ private:
|
|
249
258
|
throw SystemException("Cannot fork a new process", e);
|
250
259
|
|
251
260
|
} else {
|
261
|
+
scopedLveEnter.exit();
|
262
|
+
|
252
263
|
UPDATE_TRACE_POINT();
|
253
264
|
P_LOG_FILE_DESCRIPTOR_PURPOSE(adminSocket.first,
|
254
265
|
"Preloader " << pid << " (" << options.appRoot << ") adminSocket[0]");
|
@@ -78,6 +78,7 @@
|
|
78
78
|
#include <pwd.h>
|
79
79
|
#include <grp.h>
|
80
80
|
#include <dirent.h>
|
81
|
+
#include <adhoc_lve.h>
|
81
82
|
#include <modp_b64.h>
|
82
83
|
#include <FileDescriptor.h>
|
83
84
|
#include <Exceptions.h>
|
@@ -871,8 +872,42 @@ protected:
|
|
871
872
|
}
|
872
873
|
}
|
873
874
|
|
875
|
+
void enterLveJail(const struct passwd * pw) {
|
876
|
+
if (!pw)
|
877
|
+
return;
|
878
|
+
|
879
|
+
string lve_init_err;
|
880
|
+
adhoc_lve::LibLve& liblve = adhoc_lve::LveInitSignleton::getInstance(&lve_init_err);
|
881
|
+
if (liblve.is_error())
|
882
|
+
{
|
883
|
+
printf("!> Error\n");
|
884
|
+
printf("!> \n");
|
885
|
+
printf("!> Failed to init LVE library%s%s\n",
|
886
|
+
lve_init_err.empty()? "" : ": ",
|
887
|
+
lve_init_err.c_str());
|
888
|
+
fflush(stdout);
|
889
|
+
_exit(1);
|
890
|
+
}
|
891
|
+
|
892
|
+
if (!liblve.is_lve_available())
|
893
|
+
return;
|
894
|
+
|
895
|
+
string jail_err;
|
896
|
+
int rc = liblve.jail(pw, jail_err);
|
897
|
+
if (rc < 0)
|
898
|
+
{
|
899
|
+
printf("!> Error\n");
|
900
|
+
printf("!> \n");
|
901
|
+
printf("enterLve() failed: %s\n", jail_err.c_str());
|
902
|
+
fflush(stdout);
|
903
|
+
_exit(1);
|
904
|
+
}
|
905
|
+
}
|
906
|
+
|
874
907
|
void switchUser(const SpawnPreparationInfo &info) {
|
875
908
|
if (info.userSwitching.enabled) {
|
909
|
+
enterLveJail(&info.userSwitching.lveUserPwd);
|
910
|
+
|
876
911
|
bool setgroupsCalled = false;
|
877
912
|
#ifdef HAVE_GETGROUPLIST
|
878
913
|
if (info.userSwitching.ngroups <= NGROUPS_MAX) {
|
@@ -55,7 +55,10 @@ struct UserSwitchingInfo {
|
|
55
55
|
uid_t uid;
|
56
56
|
gid_t gid;
|
57
57
|
int ngroups;
|
58
|
-
shared_array<gid_t> gidset;
|
58
|
+
boost::shared_array<gid_t> gidset;
|
59
|
+
|
60
|
+
struct passwd lveUserPwd, *lveUserPwdComplete;
|
61
|
+
boost::shared_array<char> lveUserPwdStrBuf;
|
59
62
|
};
|
60
63
|
|
61
64
|
inline UserSwitchingInfo
|
@@ -64,9 +67,10 @@ prepareUserSwitching(const Options &options) {
|
|
64
67
|
UserSwitchingInfo info;
|
65
68
|
|
66
69
|
if (geteuid() != 0) {
|
67
|
-
struct passwd pwd
|
70
|
+
struct passwd &pwd = info.lveUserPwd;
|
71
|
+
boost::shared_array<char> &strings = info.lveUserPwdStrBuf;
|
72
|
+
struct passwd *userInfo;
|
68
73
|
long bufSize;
|
69
|
-
shared_array<char> strings;
|
70
74
|
|
71
75
|
// _SC_GETPW_R_SIZE_MAX is not a maximum:
|
72
76
|
// http://tomlee.co/2012/10/problems-with-large-linux-unix-groups-and-getgrgid_r-getgrnam_r/
|
@@ -97,11 +101,13 @@ prepareUserSwitching(const Options &options) {
|
|
97
101
|
string defaultGroup;
|
98
102
|
string startupFile = absolutizePath(options.getStartupFile(),
|
99
103
|
absolutizePath(options.appRoot));
|
100
|
-
struct passwd pwd
|
104
|
+
struct passwd &pwd = info.lveUserPwd;
|
105
|
+
boost::shared_array<char> &pwdBuf = info.lveUserPwdStrBuf;
|
106
|
+
struct passwd *userInfo;
|
101
107
|
struct group grp;
|
102
108
|
gid_t groupId = (gid_t) -1;
|
103
109
|
long pwdBufSize, grpBufSize;
|
104
|
-
shared_array<char>
|
110
|
+
boost::shared_array<char> grpBuf;
|
105
111
|
int ret;
|
106
112
|
|
107
113
|
// _SC_GETPW_R_SIZE_MAX/_SC_GETGR_R_SIZE_MAX are not maximums:
|
@@ -250,7 +256,7 @@ prepareUserSwitching(const Options &options) {
|
|
250
256
|
int e = errno;
|
251
257
|
throw SystemException("getgrouplist() failed", e);
|
252
258
|
}
|
253
|
-
info.gidset = shared_array<gid_t>(new gid_t[info.ngroups]);
|
259
|
+
info.gidset = boost::shared_array<gid_t>(new gid_t[info.ngroups]);
|
254
260
|
for (int i = 0; i < info.ngroups; i++) {
|
255
261
|
info.gidset[i] = groups[i];
|
256
262
|
}
|
@@ -237,6 +237,13 @@
|
|
237
237
|
"Force Passenger to believe that an application process can handle the given number of concurrent requests per process"),
|
238
238
|
|
239
239
|
|
240
|
+
AP_INIT_TAKE1("PassengerLveMinUid",
|
241
|
+
(Take1Func) cmd_passenger_lve_min_uid,
|
242
|
+
NULL,
|
243
|
+
RSRC_CONF,
|
244
|
+
"Minimum user id starting from which entering LVE and CageFS is allowed."),
|
245
|
+
|
246
|
+
|
240
247
|
AP_INIT_TAKE1("RailsEnv",
|
241
248
|
(Take1Func) cmd_passenger_app_env,
|
242
249
|
NULL,
|
@@ -61,6 +61,8 @@ struct GeneratedDirConfigPart {
|
|
61
61
|
Threeway stickySessionsCookieName;
|
62
62
|
/** Force Passenger to believe that an application process can handle the given number of concurrent requests per process */
|
63
63
|
int forceMaxConcurrentRequestsPerProcess;
|
64
|
+
/** Minimum user id starting from which entering LVE and CageFS is allowed. */
|
65
|
+
int lveMinUid;
|
64
66
|
/** The maximum number of simultaneously alive application instances a single application may occupy. */
|
65
67
|
int maxInstancesPerApp;
|
66
68
|
/** The maximum number of seconds that a preloader process may be idle before it is shutdown. */
|
@@ -444,4 +444,38 @@
|
|
444
444
|
}
|
445
445
|
}
|
446
446
|
|
447
|
+
|
448
|
+
static const char *
|
449
|
+
cmd_passenger_lve_min_uid(cmd_parms *cmd, void *pcfg, const char *arg) {
|
450
|
+
DirConfig *config = (DirConfig *) pcfg;
|
451
|
+
char *end;
|
452
|
+
long result;
|
453
|
+
|
454
|
+
result = strtol(arg, &end, 10);
|
455
|
+
if (*end != '\0') {
|
456
|
+
string message = "Invalid number specified for ";
|
457
|
+
message.append(cmd->directive->directive);
|
458
|
+
message.append(".");
|
459
|
+
|
460
|
+
char *messageStr = (char *) apr_palloc(cmd->temp_pool,
|
461
|
+
message.size() + 1);
|
462
|
+
memcpy(messageStr, message.c_str(), message.size() + 1);
|
463
|
+
return messageStr;
|
464
|
+
|
465
|
+
} else if (result < 0) {
|
466
|
+
string message = "Value for ";
|
467
|
+
message.append(cmd->directive->directive);
|
468
|
+
message.append(" must be greater than or equal to 0.");
|
469
|
+
|
470
|
+
char *messageStr = (char *) apr_palloc(cmd->temp_pool,
|
471
|
+
message.size() + 1);
|
472
|
+
memcpy(messageStr, message.c_str(), message.size() + 1);
|
473
|
+
return messageStr;
|
474
|
+
|
475
|
+
} else {
|
476
|
+
config->lveMinUid = (int) result;
|
477
|
+
return NULL;
|
478
|
+
}
|
479
|
+
}
|
480
|
+
|
447
481
|
|
@@ -155,3 +155,8 @@
|
|
155
155
|
sizeof("!~PASSENGER_FORCE_MAX_CONCURRENT_REQUESTS_PER_PROCESS") - 1), config->forceMaxConcurrentRequestsPerProcess);
|
156
156
|
|
157
157
|
|
158
|
+
|
159
|
+
addHeader(r, result, StaticString("!~PASSENGER_LVE_MIN_UID",
|
160
|
+
sizeof("!~PASSENGER_LVE_MIN_UID") - 1), config->lveMinUid);
|
161
|
+
|
162
|
+
|
@@ -65,6 +65,8 @@
|
|
65
65
|
|
66
66
|
#define DEFAULT_LOG_LEVEL 3
|
67
67
|
|
68
|
+
#define DEFAULT_LVE_MIN_UID 500
|
69
|
+
|
68
70
|
#define DEFAULT_MAX_POOL_SIZE 6
|
69
71
|
|
70
72
|
#define DEFAULT_MAX_PRELOADER_IDLE_TIME 300
|
@@ -121,7 +123,7 @@
|
|
121
123
|
|
122
124
|
#define PASSENGER_DEFAULT_USER "nobody"
|
123
125
|
|
124
|
-
#define PASSENGER_VERSION "5.0.
|
126
|
+
#define PASSENGER_VERSION "5.0.28"
|
125
127
|
|
126
128
|
#define POOL_HELPER_THREAD_STACK_SIZE 262144
|
127
129
|
|