passenger 5.3.7 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +14 -0
- data/build/agent.rb +4 -2
- data/build/support/cxx_dependency_map.rb +134 -0
- data/resources/templates/standalone/server.erb +1 -0
- data/src/agent/AgentMain.cpp +4 -0
- data/src/agent/Core/ApplicationPool/Group/StateInspection.cpp +1 -1
- data/src/agent/Core/ApplicationPool/Options.h +7 -7
- data/src/agent/Core/ApplicationPool/Process.h +3 -0
- data/src/agent/Core/Config.h +9 -2
- data/src/agent/Core/Controller/Config.h +27 -6
- data/src/agent/Core/Controller/InitRequest.cpp +12 -7
- data/src/agent/Core/Controller/InitializationAndShutdown.cpp +2 -0
- data/src/agent/Core/CoreMain.cpp +62 -33
- data/src/agent/Core/OptionParser.h +6 -0
- data/src/agent/Core/SpawningKit/Spawner.h +20 -5
- data/src/agent/Core/SpawningKit/UserSwitchingRules.h +13 -6
- data/src/agent/Core/TelemetryCollector.h +1 -0
- data/src/agent/FileReadHelper/FileReadHelperMain.cpp +198 -0
- data/src/agent/Watchdog/Config.h +1 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp +5 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedSetterFuncs.cpp +15 -0
- data/src/apache2_module/DirConfig/AutoGeneratedCreateFunction.cpp +5 -0
- data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp +13 -0
- data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp +7 -0
- data/src/apache2_module/DirConfig/AutoGeneratedStruct.h +13 -0
- data/src/apache2_module/DirectoryMapper.h +14 -3
- data/src/apache2_module/Hooks.cpp +15 -4
- data/src/cxx_supportlib/AppLocalConfigFileUtils.h +148 -0
- data/src/cxx_supportlib/AppTypeDetector/CBindings.cpp +12 -1
- data/src/cxx_supportlib/AppTypeDetector/CBindings.h +2 -0
- data/src/cxx_supportlib/AppTypeDetector/Detector.h +38 -4
- data/src/cxx_supportlib/Constants.h +1 -1
- data/src/nginx_module/ConfigGeneral/AutoGeneratedDefinitions.c +16 -0
- data/src/nginx_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.c +6 -0
- data/src/nginx_module/ConfigGeneral/AutoGeneratedSetterFuncs.c +12 -0
- data/src/nginx_module/Configuration.c +20 -0
- data/src/nginx_module/ContentHandler.c +301 -23
- data/src/nginx_module/ContentHandler.h +5 -0
- data/src/nginx_module/LocationConfig/AutoGeneratedCreateFunction.c +10 -0
- data/src/nginx_module/LocationConfig/AutoGeneratedManifestGeneration.c +27 -0
- data/src/nginx_module/LocationConfig/AutoGeneratedMergeFunction.c +3 -0
- data/src/nginx_module/LocationConfig/AutoGeneratedStruct.h +7 -0
- data/src/nginx_module/ngx_http_passenger_module.h +6 -1
- data/src/ruby_supportlib/phusion_passenger.rb +6 -5
- data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +6 -0
- data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +14 -0
- data/src/ruby_supportlib/phusion_passenger/standalone/app_finder.rb +1 -0
- data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +11 -1
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +1 -0
- metadata +4 -2
@@ -0,0 +1,198 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2018 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
|
+
// A helper app that reads from an arbitrary file.
|
28
|
+
// Its main reason for existance is to allow root processes (such as the Core)
|
29
|
+
// to read from arbitrary files in a way that's safe from symlink and other
|
30
|
+
// kinds of attacks. See the documentation for safeReadFile()
|
31
|
+
// to learn more about the different types of attacks.
|
32
|
+
//
|
33
|
+
// file-read-helper is used when the caller cannot use safeReadFile(),
|
34
|
+
// e.g. when the following two conditions hold at the same time:
|
35
|
+
//
|
36
|
+
// 1. The caller does not have control over the safety of the parent
|
37
|
+
// directories leading to the file.
|
38
|
+
// 2. The caller cannot choose not to disclose the contents of the file.
|
39
|
+
//
|
40
|
+
// file-read-helper MUST be used in combination with exec-helper in order
|
41
|
+
// to lower its privilege, otherwise no protection is provided.
|
42
|
+
|
43
|
+
#include <cstdio>
|
44
|
+
#include <cstdlib>
|
45
|
+
#include <cstddef>
|
46
|
+
#include <cerrno>
|
47
|
+
#include <cstring>
|
48
|
+
#include <string>
|
49
|
+
#include <algorithm>
|
50
|
+
#include <limits>
|
51
|
+
|
52
|
+
#include <fcntl.h>
|
53
|
+
#include <unistd.h>
|
54
|
+
|
55
|
+
#include <Constants.h>
|
56
|
+
#include <ProcessManagement/Utils.h>
|
57
|
+
#include <IOTools/IOUtils.h>
|
58
|
+
#include <Utils/OptionParsing.h>
|
59
|
+
|
60
|
+
namespace Passenger {
|
61
|
+
namespace FileReadHelper {
|
62
|
+
|
63
|
+
using namespace std;
|
64
|
+
|
65
|
+
|
66
|
+
struct Options {
|
67
|
+
size_t limit;
|
68
|
+
int programArgStart;
|
69
|
+
|
70
|
+
Options()
|
71
|
+
: limit(std::numeric_limits<size_t>::max()),
|
72
|
+
programArgStart(2)
|
73
|
+
{ }
|
74
|
+
};
|
75
|
+
|
76
|
+
static void
|
77
|
+
usage() {
|
78
|
+
// ....|---------------Keep output within standard terminal width (80 chars)------------|
|
79
|
+
printf("Usage: " AGENT_EXE " file-read-helper [OPTIONS...] <PATH>\n");
|
80
|
+
printf("Reads the given file with O_NONBLOCK.\n");
|
81
|
+
printf("\n");
|
82
|
+
printf("Options:\n");
|
83
|
+
printf(" --limit <SIZE> Limit the number of bytes read (default: unlimited).\n");
|
84
|
+
printf(" --help Show this help message.\n");
|
85
|
+
}
|
86
|
+
|
87
|
+
static bool
|
88
|
+
parseOption(int argc, const char *argv[], int &i, Options &options) {
|
89
|
+
OptionParser p(usage);
|
90
|
+
|
91
|
+
if (p.isValueFlag(argc, i, argv[i], '\0', "--limit")) {
|
92
|
+
options.limit = atoi(argv[i + 1]);
|
93
|
+
i += 2;
|
94
|
+
} else {
|
95
|
+
return false;
|
96
|
+
}
|
97
|
+
return true;
|
98
|
+
}
|
99
|
+
|
100
|
+
static bool
|
101
|
+
parseOptions(int argc, const char *argv[], Options &options) {
|
102
|
+
OptionParser p(usage);
|
103
|
+
int i = 2;
|
104
|
+
|
105
|
+
while (i < argc) {
|
106
|
+
if (parseOption(argc, argv, i, options)) {
|
107
|
+
continue;
|
108
|
+
} else if (p.isFlag(argv[i], 'h', "--help")) {
|
109
|
+
usage();
|
110
|
+
exit(0);
|
111
|
+
} else if (*argv[i] == '-') {
|
112
|
+
fprintf(stderr, "ERROR: unrecognized argument %s. Please type "
|
113
|
+
"'%s file-read-helper --help' for usage.\n", argv[i], argv[0]);
|
114
|
+
exit(1);
|
115
|
+
} else {
|
116
|
+
options.programArgStart = i;
|
117
|
+
return true;
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
return true;
|
122
|
+
}
|
123
|
+
|
124
|
+
int
|
125
|
+
fileReadHelperMain(int argc, char *argv[]) {
|
126
|
+
if (argc < 3) {
|
127
|
+
usage();
|
128
|
+
exit(1);
|
129
|
+
}
|
130
|
+
|
131
|
+
Options options;
|
132
|
+
if (!parseOptions(argc, (const char **) argv, options)) {
|
133
|
+
fprintf(stderr, "Error parsing arguments.\n");
|
134
|
+
usage();
|
135
|
+
exit(1);
|
136
|
+
}
|
137
|
+
|
138
|
+
if (argc != options.programArgStart + 1) {
|
139
|
+
fprintf(stderr, "ERROR: no file path given. Please type "
|
140
|
+
"'%s file-read-helper --help' for usage.\n", argv[0]);
|
141
|
+
exit(1);
|
142
|
+
}
|
143
|
+
|
144
|
+
if (geteuid() == 0) {
|
145
|
+
fprintf(stderr, "ERROR: file-read-helper cannot be run with root"
|
146
|
+
" privileges. Please use in combination with exec-helper.\n");
|
147
|
+
exit(1);
|
148
|
+
}
|
149
|
+
|
150
|
+
resetSignalHandlersAndMask();
|
151
|
+
disableMallocDebugging();
|
152
|
+
|
153
|
+
const char *path = argv[options.programArgStart];
|
154
|
+
int fd;
|
155
|
+
do {
|
156
|
+
fd = open(path, O_RDONLY | O_NONBLOCK);
|
157
|
+
} while (fd == -1 && errno == EINTR);
|
158
|
+
if (fd == -1) {
|
159
|
+
int e = errno;
|
160
|
+
fprintf(stderr, "Error opening %s for reading: %s (errno=%d)\n",
|
161
|
+
path, strerror(e), e);
|
162
|
+
exit(1);
|
163
|
+
}
|
164
|
+
|
165
|
+
size_t totalRead = 0;
|
166
|
+
char buf[1024 * 16];
|
167
|
+
|
168
|
+
while (totalRead < options.limit) {
|
169
|
+
ssize_t ret;
|
170
|
+
do {
|
171
|
+
ret = read(fd, buf,
|
172
|
+
std::min<size_t>(sizeof(buf), options.limit - totalRead));
|
173
|
+
} while (ret == -1 && errno == EINTR);
|
174
|
+
if (ret == -1) {
|
175
|
+
int e = errno;
|
176
|
+
fprintf(stderr, "Error reading from %s: %s (errno=%d)\n",
|
177
|
+
path, strerror(e), e);
|
178
|
+
exit(1);
|
179
|
+
} else if (ret == 0) {
|
180
|
+
break;
|
181
|
+
} else {
|
182
|
+
totalRead += ret;
|
183
|
+
writeExact(1, StaticString(buf, ret));
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
return 0;
|
188
|
+
}
|
189
|
+
|
190
|
+
|
191
|
+
} // namespace FileReadHelper
|
192
|
+
} // namespace Passenger
|
193
|
+
|
194
|
+
|
195
|
+
int
|
196
|
+
fileReadHelperMain(int argc, char *argv[]) {
|
197
|
+
return Passenger::FileReadHelper::fileReadHelperMain(argc, argv);
|
198
|
+
}
|
data/src/agent/Watchdog/Config.h
CHANGED
@@ -150,6 +150,7 @@ using namespace std;
|
|
150
150
|
* setsid boolean - default(false)
|
151
151
|
* show_version_in_header boolean - default(true)
|
152
152
|
* single_app_mode_app_root string - default,read_only
|
153
|
+
* single_app_mode_app_start_command string - read_only
|
153
154
|
* single_app_mode_app_type string - read_only
|
154
155
|
* single_app_mode_startup_file string - read_only
|
155
156
|
* standalone_engine string - default
|
@@ -107,6 +107,11 @@ extern "C" const command_rec passenger_commands[] = {
|
|
107
107
|
NULL,
|
108
108
|
RSRC_CONF | ACCESS_CONF,
|
109
109
|
"The application's root directory."),
|
110
|
+
AP_INIT_TAKE1("PassengerAppStartCommand",
|
111
|
+
(Take1Func) cmd_passenger_app_start_command,
|
112
|
+
NULL,
|
113
|
+
RSRC_CONF | ACCESS_CONF,
|
114
|
+
"Command string for starting the application."),
|
110
115
|
AP_INIT_TAKE1("PassengerAppType",
|
111
116
|
(Take1Func) cmd_passenger_app_type,
|
112
117
|
NULL,
|
@@ -203,6 +203,21 @@ cmd_passenger_app_root(cmd_parms *cmd, void *pcfg, const char *arg) {
|
|
203
203
|
return NULL;
|
204
204
|
}
|
205
205
|
|
206
|
+
static const char *
|
207
|
+
cmd_passenger_app_start_command(cmd_parms *cmd, void *pcfg, const char *arg) {
|
208
|
+
const char *err = ap_check_cmd_context(cmd, NOT_IN_FILES);
|
209
|
+
if (err != NULL) {
|
210
|
+
return err;
|
211
|
+
}
|
212
|
+
|
213
|
+
DirConfig *config = (DirConfig *) pcfg;
|
214
|
+
config->mAppStartCommandSourceFile = cmd->directive->filename;
|
215
|
+
config->mAppStartCommandSourceLine = cmd->directive->line_num;
|
216
|
+
config->mAppStartCommandExplicitlySet = true;
|
217
|
+
config->mAppStartCommand = arg;
|
218
|
+
return NULL;
|
219
|
+
}
|
220
|
+
|
206
221
|
static const char *
|
207
222
|
cmd_passenger_app_type(cmd_parms *cmd, void *pcfg, const char *arg) {
|
208
223
|
const char *err = ap_check_cmd_context(cmd, NOT_IN_FILES);
|
@@ -64,6 +64,9 @@ createDirConfig_autoGenerated(DirConfig *config) {
|
|
64
64
|
/*
|
65
65
|
* config->mAppRoot: default initialized
|
66
66
|
*/
|
67
|
+
/*
|
68
|
+
* config->mAppStartCommand: default initialized
|
69
|
+
*/
|
67
70
|
/*
|
68
71
|
* config->mAppType: default initialized
|
69
72
|
*/
|
@@ -124,6 +127,7 @@ createDirConfig_autoGenerated(DirConfig *config) {
|
|
124
127
|
config->mAppGroupNameSourceLine = 0;
|
125
128
|
config->mAppLogFileSourceLine = 0;
|
126
129
|
config->mAppRootSourceLine = 0;
|
130
|
+
config->mAppStartCommandSourceLine = 0;
|
127
131
|
config->mAppTypeSourceLine = 0;
|
128
132
|
config->mBaseURIsSourceLine = 0;
|
129
133
|
config->mBufferResponseSourceLine = 0;
|
@@ -158,6 +162,7 @@ createDirConfig_autoGenerated(DirConfig *config) {
|
|
158
162
|
config->mAppGroupNameExplicitlySet = false;
|
159
163
|
config->mAppLogFileExplicitlySet = false;
|
160
164
|
config->mAppRootExplicitlySet = false;
|
165
|
+
config->mAppStartCommandExplicitlySet = false;
|
161
166
|
config->mAppTypeExplicitlySet = false;
|
162
167
|
config->mBaseURIsExplicitlySet = false;
|
163
168
|
config->mBufferResponseExplicitlySet = false;
|
@@ -116,6 +116,19 @@ ConfigManifestGenerator::autoGenerated_generateConfigManifestForDirConfig(server
|
|
116
116
|
pdconf->mAppRoot.data(),
|
117
117
|
pdconf->mAppRoot.data() + pdconf->mAppRoot.size());
|
118
118
|
}
|
119
|
+
if (pdconf->mAppStartCommandExplicitlySet) {
|
120
|
+
findOrCreateAppAndLocOptionsContainers(serverRec, csconf, cdconf,
|
121
|
+
pdconf, context, &appOptionsContainer, &locOptionsContainer);
|
122
|
+
Json::Value &optionContainer = findOrCreateOptionContainer(*appOptionsContainer,
|
123
|
+
"PassengerAppStartCommand",
|
124
|
+
sizeof("PassengerAppStartCommand") - 1);
|
125
|
+
Json::Value &hierarchyMember = addOptionContainerHierarchyMember(optionContainer,
|
126
|
+
pdconf->mAppStartCommandSourceFile,
|
127
|
+
pdconf->mAppStartCommandSourceLine);
|
128
|
+
hierarchyMember["value"] = Json::Value(
|
129
|
+
pdconf->mAppStartCommand.data(),
|
130
|
+
pdconf->mAppStartCommand.data() + pdconf->mAppStartCommand.size());
|
131
|
+
}
|
119
132
|
if (pdconf->mAppTypeExplicitlySet) {
|
120
133
|
findOrCreateAppAndLocOptionsContainers(serverRec, csconf, cdconf,
|
121
134
|
pdconf, context, &appOptionsContainer, &locOptionsContainer);
|
@@ -68,6 +68,10 @@ mergeDirConfig_autoGenerated(DirConfig *config, DirConfig *base, DirConfig *add)
|
|
68
68
|
(!add->mAppRoot.empty())
|
69
69
|
? add->mAppRoot
|
70
70
|
: base->mAppRoot;
|
71
|
+
config->mAppStartCommand =
|
72
|
+
(!add->mAppStartCommand.empty())
|
73
|
+
? add->mAppStartCommand
|
74
|
+
: base->mAppStartCommand;
|
71
75
|
config->mAppType =
|
72
76
|
(!add->mAppType.empty())
|
73
77
|
? add->mAppType
|
@@ -186,6 +190,7 @@ mergeDirConfig_autoGenerated(DirConfig *config, DirConfig *base, DirConfig *add)
|
|
186
190
|
config->mAppGroupNameSourceFile = add->mAppGroupNameSourceFile;
|
187
191
|
config->mAppLogFileSourceFile = add->mAppLogFileSourceFile;
|
188
192
|
config->mAppRootSourceFile = add->mAppRootSourceFile;
|
193
|
+
config->mAppStartCommandSourceFile = add->mAppStartCommandSourceFile;
|
189
194
|
config->mAppTypeSourceFile = add->mAppTypeSourceFile;
|
190
195
|
config->mBaseURIsSourceFile = add->mBaseURIsSourceFile;
|
191
196
|
config->mBufferResponseSourceFile = add->mBufferResponseSourceFile;
|
@@ -220,6 +225,7 @@ mergeDirConfig_autoGenerated(DirConfig *config, DirConfig *base, DirConfig *add)
|
|
220
225
|
config->mAppGroupNameSourceLine = add->mAppGroupNameSourceLine;
|
221
226
|
config->mAppLogFileSourceLine = add->mAppLogFileSourceLine;
|
222
227
|
config->mAppRootSourceLine = add->mAppRootSourceLine;
|
228
|
+
config->mAppStartCommandSourceLine = add->mAppStartCommandSourceLine;
|
223
229
|
config->mAppTypeSourceLine = add->mAppTypeSourceLine;
|
224
230
|
config->mBaseURIsSourceLine = add->mBaseURIsSourceLine;
|
225
231
|
config->mBufferResponseSourceLine = add->mBufferResponseSourceLine;
|
@@ -254,6 +260,7 @@ mergeDirConfig_autoGenerated(DirConfig *config, DirConfig *base, DirConfig *add)
|
|
254
260
|
config->mAppGroupNameExplicitlySet = add->mAppGroupNameExplicitlySet;
|
255
261
|
config->mAppLogFileExplicitlySet = add->mAppLogFileExplicitlySet;
|
256
262
|
config->mAppRootExplicitlySet = add->mAppRootExplicitlySet;
|
263
|
+
config->mAppStartCommandExplicitlySet = add->mAppStartCommandExplicitlySet;
|
257
264
|
config->mAppTypeExplicitlySet = add->mAppTypeExplicitlySet;
|
258
265
|
config->mBaseURIsExplicitlySet = add->mBaseURIsExplicitlySet;
|
259
266
|
config->mBufferResponseExplicitlySet = add->mBufferResponseExplicitlySet;
|
@@ -156,6 +156,11 @@ struct AutoGeneratedDirConfig {
|
|
156
156
|
*/
|
157
157
|
StaticString mAppRoot;
|
158
158
|
|
159
|
+
/*
|
160
|
+
* Command string for starting the application.
|
161
|
+
*/
|
162
|
+
StaticString mAppStartCommand;
|
163
|
+
|
159
164
|
/*
|
160
165
|
* Force specific application type.
|
161
166
|
*/
|
@@ -242,6 +247,7 @@ struct AutoGeneratedDirConfig {
|
|
242
247
|
StaticString mAppGroupNameSourceFile;
|
243
248
|
StaticString mAppLogFileSourceFile;
|
244
249
|
StaticString mAppRootSourceFile;
|
250
|
+
StaticString mAppStartCommandSourceFile;
|
245
251
|
StaticString mAppTypeSourceFile;
|
246
252
|
StaticString mGroupSourceFile;
|
247
253
|
StaticString mMeteorAppSettingsSourceFile;
|
@@ -276,6 +282,7 @@ struct AutoGeneratedDirConfig {
|
|
276
282
|
unsigned int mAppGroupNameSourceLine;
|
277
283
|
unsigned int mAppLogFileSourceLine;
|
278
284
|
unsigned int mAppRootSourceLine;
|
285
|
+
unsigned int mAppStartCommandSourceLine;
|
279
286
|
unsigned int mAppTypeSourceLine;
|
280
287
|
unsigned int mGroupSourceLine;
|
281
288
|
unsigned int mMeteorAppSettingsSourceLine;
|
@@ -310,6 +317,7 @@ struct AutoGeneratedDirConfig {
|
|
310
317
|
bool mAppGroupNameExplicitlySet: 1;
|
311
318
|
bool mAppLogFileExplicitlySet: 1;
|
312
319
|
bool mAppRootExplicitlySet: 1;
|
320
|
+
bool mAppStartCommandExplicitlySet: 1;
|
313
321
|
bool mAppTypeExplicitlySet: 1;
|
314
322
|
bool mGroupExplicitlySet: 1;
|
315
323
|
bool mMeteorAppSettingsExplicitlySet: 1;
|
@@ -489,6 +497,11 @@ struct AutoGeneratedDirConfig {
|
|
489
497
|
return mAppRoot;
|
490
498
|
}
|
491
499
|
|
500
|
+
StaticString
|
501
|
+
getAppStartCommand() const {
|
502
|
+
return mAppStartCommand;
|
503
|
+
}
|
504
|
+
|
492
505
|
StaticString
|
493
506
|
getAppType() const {
|
494
507
|
return mAppType;
|
@@ -77,6 +77,7 @@ private:
|
|
77
77
|
request_rec *r;
|
78
78
|
CachedFileStat *cstat;
|
79
79
|
boost::mutex *cstatMutex;
|
80
|
+
boost::mutex *configMutex;
|
80
81
|
const char *baseURI;
|
81
82
|
string publicDir;
|
82
83
|
string appRoot;
|
@@ -148,10 +149,16 @@ private:
|
|
148
149
|
|
149
150
|
UPDATE_TRACE_POINT();
|
150
151
|
AppTypeDetector::Detector detector(registry, cstat,
|
151
|
-
cstatMutex, throttleRate);
|
152
|
+
cstatMutex, throttleRate, configMutex);
|
152
153
|
AppTypeDetector::Detector::Result detectorResult;
|
153
154
|
string appRoot;
|
154
|
-
|
155
|
+
// If `AppStartCommand` is set, then it means the config specified that it is
|
156
|
+
// either a generic app or a Kuria app.
|
157
|
+
if (!config->getAppStartCommand().empty()) {
|
158
|
+
appRoot = config->getAppRoot();
|
159
|
+
} else if (config->getAppType().empty()) {
|
160
|
+
// If neither `AppStartCommand` nor `AppType` are set, then
|
161
|
+
// autodetect what kind of app this is.
|
155
162
|
if (config->getAppRoot().empty()) {
|
156
163
|
detectorResult = detector.checkDocumentRoot(publicDir,
|
157
164
|
baseURI != NULL,
|
@@ -161,6 +168,9 @@ private:
|
|
161
168
|
detectorResult = detector.checkAppRoot(appRoot);
|
162
169
|
}
|
163
170
|
} else if (!config->getAppRoot().empty()) {
|
171
|
+
// If `AppStartCommand` is not set but `AppType` is (as well as
|
172
|
+
// the required `AppRoot`), then verify whether the given
|
173
|
+
// `AppType` value is supported and resolve aliases.
|
164
174
|
appRoot = config->getAppRoot().toString();
|
165
175
|
detectorResult.wrapperRegistryEntry = ®istry.lookup(
|
166
176
|
config->getAppType());
|
@@ -186,13 +196,14 @@ public:
|
|
186
196
|
DirectoryMapper(request_rec *r, DirConfig *config,
|
187
197
|
const WrapperRegistry::Registry &_registry,
|
188
198
|
CachedFileStat *cstat, boost::mutex *cstatMutex,
|
189
|
-
unsigned int throttleRate)
|
199
|
+
unsigned int throttleRate, boost::mutex *configMutex)
|
190
200
|
: registry(_registry)
|
191
201
|
{
|
192
202
|
this->r = r;
|
193
203
|
this->config = config;
|
194
204
|
this->cstat = cstat;
|
195
205
|
this->cstatMutex = cstatMutex;
|
206
|
+
this->configMutex = configMutex;
|
196
207
|
this->throttleRate = throttleRate;
|
197
208
|
baseURI = NULL;
|
198
209
|
autoDetectionDone = false;
|
@@ -237,6 +237,7 @@ private:
|
|
237
237
|
CachedFileStat cstat;
|
238
238
|
WatchdogLauncher watchdogLauncher;
|
239
239
|
boost::mutex cstatMutex;
|
240
|
+
boost::mutex configMutex;
|
240
241
|
|
241
242
|
static Json::Value strsetToJson(const set<string> &input) {
|
242
243
|
Json::Value result(Json::arrayValue);
|
@@ -446,9 +447,11 @@ private:
|
|
446
447
|
TRACE_POINT();
|
447
448
|
|
448
449
|
DirectoryMapper mapper(r, config, wrapperRegistry, &cstat,
|
449
|
-
|
450
|
+
&cstatMutex, serverConfig.statThrottleRate, &configMutex);
|
450
451
|
try {
|
451
|
-
if (
|
452
|
+
if (config->getAppStartCommand().empty()
|
453
|
+
&& mapper.getDetectorResult().isNull())
|
454
|
+
{
|
452
455
|
// (B) is not true.
|
453
456
|
disableRequestNote(r);
|
454
457
|
return false;
|
@@ -988,8 +991,16 @@ private:
|
|
988
991
|
// Phusion Passenger options.
|
989
992
|
addHeader(result, P_STATIC_STRING("!~PASSENGER_APP_ROOT"),
|
990
993
|
mapper.getAppRoot());
|
991
|
-
|
992
|
-
|
994
|
+
if (!config->getAppStartCommand().empty()) {
|
995
|
+
addHeader(result, P_STATIC_STRING("!~PASSENGER_APP_START_COMMAND"),
|
996
|
+
config->getAppStartCommand());
|
997
|
+
} else if (mapper.getDetectorResult().wrapperRegistryEntry != NULL) {
|
998
|
+
addHeader(result, P_STATIC_STRING("!~PASSENGER_APP_TYPE"),
|
999
|
+
mapper.getDetectorResult().wrapperRegistryEntry->language);
|
1000
|
+
} else {
|
1001
|
+
addHeader(result, P_STATIC_STRING("!~PASSENGER_APP_START_COMMAND"),
|
1002
|
+
mapper.getDetectorResult().appStartCommand);
|
1003
|
+
}
|
993
1004
|
constructRequestHeaders_autoGenerated(r, config, result);
|
994
1005
|
|
995
1006
|
/*********************/
|