passenger 4.0.48 → 4.0.49
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 +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +36 -2
- data/.travis.yml +1 -1
- data/CHANGELOG +16 -0
- data/Rakefile +0 -1
- data/build/apache2.rb +4 -4
- data/build/common_library.rb +18 -18
- data/build/cplusplus_support.rb +2 -2
- data/build/documentation.rb +1 -1
- data/build/integration_tests.rb +12 -4
- data/build/misc.rb +12 -7
- data/build/packaging.rb +14 -14
- data/build/preprocessor.rb +10 -10
- data/build/rake_extensions.rb +11 -11
- data/build/ruby_extension.rb +2 -2
- data/dev/ci/inituidgid +24 -0
- data/dev/ci/run_jenkins.sh +57 -0
- data/dev/ci/run_rpm_tests.sh +77 -0
- data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
- data/doc/Users guide Nginx.txt +2 -2
- data/doc/users_guide_snippets/environment_variables.txt +0 -2
- data/doc/users_guide_snippets/tips.txt +20 -1
- data/ext/apache2/Bucket.cpp +18 -18
- data/ext/apache2/Bucket.h +4 -4
- data/ext/apache2/Configuration.cpp +7 -7
- data/ext/apache2/Configuration.hpp +43 -43
- data/ext/apache2/DirectoryMapper.h +5 -5
- data/ext/apache2/Hooks.cpp +142 -142
- data/ext/apache2/MergeDirConfig.cpp +40 -40
- data/ext/common/Account.h +17 -17
- data/ext/common/AccountsDatabase.h +9 -9
- data/ext/common/AgentsStarter.cpp +2 -2
- data/ext/common/AgentsStarter.h +40 -40
- data/ext/common/ApplicationPool2/Common.h +10 -6
- data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
- data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
- data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
- data/ext/common/ApplicationPool2/Group.h +54 -38
- data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
- data/ext/common/ApplicationPool2/Options.h +98 -91
- data/ext/common/ApplicationPool2/Pool.h +70 -69
- data/ext/common/ApplicationPool2/Process.h +21 -21
- data/ext/common/ApplicationPool2/Session.h +11 -11
- data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
- data/ext/common/ApplicationPool2/Socket.h +19 -19
- data/ext/common/ApplicationPool2/Spawner.h +64 -72
- data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
- data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
- data/ext/common/BackgroundEventLoop.cpp +1 -1
- data/ext/common/BackgroundEventLoop.h +2 -2
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedBufferedInput.h +5 -5
- data/ext/common/EventedClient.h +51 -51
- data/ext/common/EventedMessageServer.h +39 -39
- data/ext/common/EventedServer.h +32 -32
- data/ext/common/Exceptions.h +23 -23
- data/ext/common/FileDescriptor.h +18 -18
- data/ext/common/Logging.cpp +1 -1
- data/ext/common/MessageClient.h +27 -27
- data/ext/common/MessageReadersWriters.h +79 -79
- data/ext/common/MessageServer.h +59 -59
- data/ext/common/RandomGenerator.h +12 -12
- data/ext/common/ResourceLocator.h +8 -8
- data/ext/common/SafeLibev.h +54 -25
- data/ext/common/ServerInstanceDir.h +31 -31
- data/ext/common/StaticString.h +50 -48
- data/ext/common/Utils.cpp +73 -78
- data/ext/common/Utils.h +6 -6
- data/ext/common/Utils/Base64.cpp +3 -3
- data/ext/common/Utils/Base64.h +7 -7
- data/ext/common/Utils/BlockingQueue.h +9 -9
- data/ext/common/Utils/BufferedIO.h +17 -17
- data/ext/common/Utils/CachedFileStat.hpp +16 -16
- data/ext/common/Utils/Dechunker.h +25 -25
- data/ext/common/Utils/FileChangeChecker.h +10 -10
- data/ext/common/Utils/MemZeroGuard.h +5 -5
- data/ext/common/Utils/MemoryBarrier.h +1 -1
- data/ext/common/Utils/MessageIO.h +61 -61
- data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
- data/ext/common/Utils/ScopeGuard.h +7 -7
- data/ext/common/Utils/SpeedMeter.h +1 -1
- data/ext/common/Utils/StrIntUtils.cpp +13 -13
- data/ext/common/Utils/StrIntUtils.h +3 -3
- data/ext/common/Utils/StringScanning.h +5 -5
- data/ext/common/Utils/SystemMetricsCollector.h +2 -2
- data/ext/common/Utils/SystemTime.h +10 -10
- data/ext/common/Utils/Template.h +2 -2
- data/ext/common/Utils/Timer.h +6 -6
- data/ext/common/Utils/VariantMap.h +29 -29
- data/ext/common/agents/Base.cpp +19 -19
- data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
- data/ext/common/agents/HelperAgent/Main.cpp +44 -43
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
- data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
- data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
- data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
- data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
- data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
- data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
- data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
- data/ext/common/agents/SpawnPreparer.cpp +4 -4
- data/ext/common/agents/TempDirToucher.c +2 -2
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
- data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/Main.cpp +22 -22
- data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
- data/ext/libeio/eio.c +1 -1
- data/ext/nginx/Configuration.c +30 -30
- data/ext/nginx/Configuration.h +1 -1
- data/ext/nginx/ContentHandler.c +54 -54
- data/ext/nginx/ContentHandler.h +3 -3
- data/ext/nginx/StaticContentHandler.c +2 -2
- data/ext/nginx/ngx_http_passenger_module.c +21 -21
- data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
- data/ext/oxt/detail/context.hpp +1 -1
- data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
- data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
- data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
- data/ext/oxt/dynamic_thread_group.hpp +18 -18
- data/ext/oxt/implementation.cpp +9 -8
- data/ext/oxt/macros.hpp +2 -2
- data/ext/oxt/system_calls.cpp +11 -11
- data/ext/oxt/system_calls.hpp +13 -13
- data/ext/oxt/thread.hpp +22 -14
- data/ext/ruby/passenger_native_support.c +55 -55
- data/lib/phusion_passenger.rb +24 -24
- data/lib/phusion_passenger/common_library.rb +2 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
- data/lib/phusion_passenger/packaging.rb +9 -4
- data/lib/phusion_passenger/platform_info/apache.rb +45 -31
- data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
- data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
- data/lib/phusion_passenger/standalone/command.rb +22 -22
- data/packaging/rpm/LICENSE.txt +19 -0
- data/packaging/rpm/Makefile +13 -0
- data/packaging/rpm/README.md +41 -0
- data/packaging/rpm/Vagrantfile +38 -0
- data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
- data/packaging/rpm/build +170 -0
- data/packaging/rpm/create_project +41 -0
- data/packaging/rpm/git_update +88 -0
- data/packaging/rpm/image/Dockerfile +37 -0
- data/packaging/rpm/image/Gemfile +3 -0
- data/packaging/rpm/image/Gemfile.lock +12 -0
- data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
- data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
- data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
- data/packaging/rpm/image/site-defaults.cfg +168 -0
- data/packaging/rpm/internal/build_tasks.rb +238 -0
- data/packaging/rpm/internal/dummygpg +11 -0
- data/packaging/rpm/internal/exec_build +42 -0
- data/packaging/rpm/internal/get_distro_arch +14 -0
- data/packaging/rpm/internal/get_distro_id +10 -0
- data/packaging/rpm/internal/git_update +27 -0
- data/packaging/rpm/internal/inituidgid +17 -0
- data/packaging/rpm/internal/my_init +344 -0
- data/packaging/rpm/internal/python27 +3 -0
- data/packaging/rpm/internal/repo_update +46 -0
- data/packaging/rpm/internal/setuser +26 -0
- data/packaging/rpm/internal/tracking_helper +40 -0
- data/packaging/rpm/jenkins_release +99 -0
- data/packaging/rpm/lib/build_tasks_support.rb +402 -0
- data/packaging/rpm/lib/preprocessor.rb +341 -0
- data/packaging/rpm/nginx_spec/404.html +119 -0
- data/packaging/rpm/nginx_spec/50x.html +119 -0
- data/packaging/rpm/nginx_spec/index.html +116 -0
- data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
- data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
- data/packaging/rpm/nginx_spec/nginx.conf +131 -0
- data/packaging/rpm/nginx_spec/nginx.init +144 -0
- data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
- data/packaging/rpm/nginx_spec/nginx.service +15 -0
- data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
- data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
- data/packaging/rpm/nginx_spec/passenger.conf +9 -0
- data/packaging/rpm/nginx_spec/poweredby.png +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
- data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
- data/packaging/rpm/repo_update +114 -0
- data/packaging/rpm/setup-system +60 -0
- data/packaging/rpm/shell +10 -0
- data/resources/templates/standalone/config.erb +3 -1
- data/test/config.json.rpm-automation +1 -1
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
- data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
- data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
- data/test/cxx/ScgiRequestParserTest.cpp +75 -61
- data/test/cxx/UtilsTest.cpp +86 -85
- data/test/gdbinit.example +3 -0
- data/test/integration_tests/nginx_tests.rb +3 -3
- data/test/integration_tests/source_packaging_test.rb +3 -1
- data/test/stub/nginx/nginx.conf.erb +8 -1
- data/test/support/nginx_controller.rb +7 -7
- metadata +62 -17
- metadata.gz.asc +7 -7
- data/build/rpm.rb +0 -128
- data/dev/rpmtool +0 -21
- data/dev/test_rpm_packaging.sh +0 -28
- data/rpm/get_distro_id.py +0 -4
@@ -78,7 +78,7 @@ private:
|
|
78
78
|
unsigned int throttleRate;
|
79
79
|
PassengerAppType appType: 7;
|
80
80
|
bool autoDetectionDone: 1;
|
81
|
-
|
81
|
+
|
82
82
|
const char *findBaseURI() const {
|
83
83
|
set<string>::const_iterator it, end = config->baseURIs.end();
|
84
84
|
const char *uri = r->uri;
|
@@ -188,7 +188,7 @@ public:
|
|
188
188
|
baseURI = NULL;
|
189
189
|
autoDetectionDone = false;
|
190
190
|
}
|
191
|
-
|
191
|
+
|
192
192
|
/**
|
193
193
|
* Determines whether the given HTTP request falls under one of the specified
|
194
194
|
* PassengerBaseURIs. If yes, then the first matching base URI will be returned.
|
@@ -206,7 +206,7 @@ public:
|
|
206
206
|
autoDetect();
|
207
207
|
return baseURI;
|
208
208
|
}
|
209
|
-
|
209
|
+
|
210
210
|
/**
|
211
211
|
* Returns the filename of the 'public' directory of the application
|
212
212
|
* that's associated with the HTTP request.
|
@@ -234,7 +234,7 @@ public:
|
|
234
234
|
autoDetect();
|
235
235
|
return appRoot;
|
236
236
|
}
|
237
|
-
|
237
|
+
|
238
238
|
/**
|
239
239
|
* Returns the application type that's associated with the HTTP request.
|
240
240
|
*
|
@@ -247,7 +247,7 @@ public:
|
|
247
247
|
autoDetect();
|
248
248
|
return appType;
|
249
249
|
}
|
250
|
-
|
250
|
+
|
251
251
|
/**
|
252
252
|
* Returns the application type (as a string) that's associated
|
253
253
|
* with the HTTP request.
|
data/ext/apache2/Hooks.cpp
CHANGED
@@ -124,14 +124,14 @@ private:
|
|
124
124
|
virtual ~ErrorReport() { }
|
125
125
|
virtual int report(request_rec *r) = 0;
|
126
126
|
};
|
127
|
-
|
127
|
+
|
128
128
|
class ReportFileSystemError: public ErrorReport {
|
129
129
|
private:
|
130
130
|
FileSystemException e;
|
131
|
-
|
131
|
+
|
132
132
|
public:
|
133
133
|
ReportFileSystemError(const FileSystemException &ex): e(ex) { }
|
134
|
-
|
134
|
+
|
135
135
|
int report(request_rec *r) {
|
136
136
|
r->status = 500;
|
137
137
|
ap_set_content_type(r, "text/html; charset=UTF-8");
|
@@ -156,10 +156,10 @@ private:
|
|
156
156
|
class ReportDocumentRootDeterminationError: public ErrorReport {
|
157
157
|
private:
|
158
158
|
DocumentRootDeterminationError e;
|
159
|
-
|
159
|
+
|
160
160
|
public:
|
161
161
|
ReportDocumentRootDeterminationError(const DocumentRootDeterminationError &ex): e(ex) { }
|
162
|
-
|
162
|
+
|
163
163
|
int report(request_rec *r) {
|
164
164
|
r->status = 500;
|
165
165
|
ap_set_content_type(r, "text/html; charset=UTF-8");
|
@@ -170,18 +170,18 @@ private:
|
|
170
170
|
return OK;
|
171
171
|
}
|
172
172
|
};
|
173
|
-
|
173
|
+
|
174
174
|
struct RequestNote {
|
175
175
|
DirectoryMapper mapper;
|
176
176
|
DirConfig *config;
|
177
177
|
ErrorReport *errorReport;
|
178
|
-
|
178
|
+
|
179
179
|
const char *handlerBeforeModRewrite;
|
180
180
|
char *filenameBeforeModRewrite;
|
181
181
|
apr_filetype_e oldFileType;
|
182
182
|
const char *handlerBeforeModAutoIndex;
|
183
183
|
bool enabled;
|
184
|
-
|
184
|
+
|
185
185
|
RequestNote(const DirectoryMapper &m, DirConfig *c)
|
186
186
|
: mapper(m),
|
187
187
|
config(c)
|
@@ -193,27 +193,27 @@ private:
|
|
193
193
|
handlerBeforeModAutoIndex = NULL;
|
194
194
|
enabled = true;
|
195
195
|
}
|
196
|
-
|
196
|
+
|
197
197
|
~RequestNote() {
|
198
198
|
delete errorReport;
|
199
199
|
}
|
200
|
-
|
200
|
+
|
201
201
|
static apr_status_t cleanup(void *p) {
|
202
202
|
delete (RequestNote *) p;
|
203
203
|
return APR_SUCCESS;
|
204
204
|
}
|
205
205
|
};
|
206
|
-
|
206
|
+
|
207
207
|
enum Threeway { YES, NO, UNKNOWN };
|
208
208
|
|
209
209
|
Threeway m_hasModRewrite, m_hasModDir, m_hasModAutoIndex, m_hasModXsendfile;
|
210
210
|
CachedFileStat cstat;
|
211
211
|
AgentsStarter agentsStarter;
|
212
|
-
|
212
|
+
|
213
213
|
inline DirConfig *getDirConfig(request_rec *r) {
|
214
214
|
return (DirConfig *) ap_get_module_config(r->per_dir_config, &passenger_module);
|
215
215
|
}
|
216
|
-
|
216
|
+
|
217
217
|
/**
|
218
218
|
* The existance of a request note means that the handler should be run.
|
219
219
|
*/
|
@@ -238,7 +238,7 @@ private:
|
|
238
238
|
note->enabled = false;
|
239
239
|
}
|
240
240
|
}
|
241
|
-
|
241
|
+
|
242
242
|
StaticString getRequestSocketFilename() const {
|
243
243
|
return agentsStarter.getRequestSocketFilename();
|
244
244
|
}
|
@@ -255,7 +255,7 @@ private:
|
|
255
255
|
FileDescriptor connectToHelperAgent() {
|
256
256
|
TRACE_POINT();
|
257
257
|
FileDescriptor conn;
|
258
|
-
|
258
|
+
|
259
259
|
try {
|
260
260
|
conn = connectToUnixServer(getRequestSocketFilename());
|
261
261
|
writeExact(conn, getRequestSocketPassword());
|
@@ -263,10 +263,10 @@ private:
|
|
263
263
|
if (e.code() == EPIPE || e.code() == ECONNREFUSED || e.code() == ENOENT) {
|
264
264
|
UPDATE_TRACE_POINT();
|
265
265
|
bool connected = false;
|
266
|
-
|
266
|
+
|
267
267
|
// Maybe the helper agent crashed. First wait 50 ms.
|
268
268
|
usleep(50000);
|
269
|
-
|
269
|
+
|
270
270
|
// Then try to reconnect to the helper agent for the
|
271
271
|
// next 5 seconds.
|
272
272
|
time_t deadline = time(NULL) + 5;
|
@@ -286,7 +286,7 @@ private:
|
|
286
286
|
}
|
287
287
|
}
|
288
288
|
}
|
289
|
-
|
289
|
+
|
290
290
|
if (!connected) {
|
291
291
|
UPDATE_TRACE_POINT();
|
292
292
|
throw IOException("Cannot connect to the helper agent at " +
|
@@ -298,7 +298,7 @@ private:
|
|
298
298
|
}
|
299
299
|
return conn;
|
300
300
|
}
|
301
|
-
|
301
|
+
|
302
302
|
bool hasModRewrite() {
|
303
303
|
if (m_hasModRewrite == UNKNOWN) {
|
304
304
|
if (ap_find_linked_module("mod_rewrite.c")) {
|
@@ -309,7 +309,7 @@ private:
|
|
309
309
|
}
|
310
310
|
return m_hasModRewrite == YES;
|
311
311
|
}
|
312
|
-
|
312
|
+
|
313
313
|
bool hasModDir() {
|
314
314
|
if (m_hasModDir == UNKNOWN) {
|
315
315
|
if (ap_find_linked_module("mod_dir.c")) {
|
@@ -320,7 +320,7 @@ private:
|
|
320
320
|
}
|
321
321
|
return m_hasModDir == YES;
|
322
322
|
}
|
323
|
-
|
323
|
+
|
324
324
|
bool hasModAutoIndex() {
|
325
325
|
if (m_hasModAutoIndex == UNKNOWN) {
|
326
326
|
if (ap_find_linked_module("mod_autoindex.c")) {
|
@@ -331,7 +331,7 @@ private:
|
|
331
331
|
}
|
332
332
|
return m_hasModAutoIndex == YES;
|
333
333
|
}
|
334
|
-
|
334
|
+
|
335
335
|
bool hasModXsendfile() {
|
336
336
|
if (m_hasModXsendfile == UNKNOWN) {
|
337
337
|
if (ap_find_linked_module("mod_xsendfile.c")) {
|
@@ -342,13 +342,13 @@ private:
|
|
342
342
|
}
|
343
343
|
return m_hasModXsendfile == YES;
|
344
344
|
}
|
345
|
-
|
345
|
+
|
346
346
|
int reportBusyException(request_rec *r) {
|
347
347
|
ap_custom_response(r, HTTP_SERVICE_UNAVAILABLE,
|
348
348
|
"This website is too busy right now. Please try again later.");
|
349
349
|
return HTTP_SERVICE_UNAVAILABLE;
|
350
350
|
}
|
351
|
-
|
351
|
+
|
352
352
|
/**
|
353
353
|
* Gather some information about the request and do some preparations.
|
354
354
|
*
|
@@ -372,7 +372,7 @@ private:
|
|
372
372
|
*/
|
373
373
|
bool prepareRequest(request_rec *r, DirConfig *config, const char *filename, bool coreModuleWillBeRun = false) {
|
374
374
|
TRACE_POINT();
|
375
|
-
|
375
|
+
|
376
376
|
DirectoryMapper mapper(r, config, &cstat, config->getStatThrottleRate());
|
377
377
|
try {
|
378
378
|
if (mapper.getApplicationType() == PAT_NONE) {
|
@@ -411,9 +411,9 @@ private:
|
|
411
411
|
return false;
|
412
412
|
}
|
413
413
|
}
|
414
|
-
|
414
|
+
|
415
415
|
// (B) is true.
|
416
|
-
|
416
|
+
|
417
417
|
try {
|
418
418
|
FileType fileType = getFileType(filename);
|
419
419
|
if (fileType == FT_REGULAR) {
|
@@ -421,7 +421,7 @@ private:
|
|
421
421
|
disableRequestNote(r);
|
422
422
|
return false;
|
423
423
|
}
|
424
|
-
|
424
|
+
|
425
425
|
// (C) is not true. Check whether (D) is true.
|
426
426
|
char *pageCacheFile;
|
427
427
|
/* Only GET requests may hit the page cache. This is
|
@@ -434,7 +434,7 @@ private:
|
|
434
434
|
if (r->method_number == M_GET) {
|
435
435
|
if (fileType == FT_DIRECTORY) {
|
436
436
|
size_t len;
|
437
|
-
|
437
|
+
|
438
438
|
len = strlen(filename);
|
439
439
|
if (len > 0 && filename[len - 1] == '/') {
|
440
440
|
pageCacheFile = apr_pstrcat(r->pool, filename,
|
@@ -483,14 +483,14 @@ private:
|
|
483
483
|
return false;
|
484
484
|
}
|
485
485
|
}
|
486
|
-
|
486
|
+
|
487
487
|
/**
|
488
488
|
* Most of the high-level logic for forwarding a request to the
|
489
489
|
* HelperAgent is contained in this method.
|
490
490
|
*/
|
491
491
|
int handleRequest(request_rec *r) {
|
492
492
|
/********** Step 1: preparation work **********/
|
493
|
-
|
493
|
+
|
494
494
|
/* Initialize OXT backtrace support if not already done for this thread */
|
495
495
|
if (oxt::get_thread_local_context() == NULL) {
|
496
496
|
/* There is no need to cleanup the context. Apache uses a static
|
@@ -505,7 +505,7 @@ private:
|
|
505
505
|
/* Check whether an error occured in prepareRequest() that should be reported
|
506
506
|
* to the browser.
|
507
507
|
*/
|
508
|
-
|
508
|
+
|
509
509
|
RequestNote *note = getRequestNote(r);
|
510
510
|
if (note == NULL) {
|
511
511
|
return DECLINED;
|
@@ -524,11 +524,11 @@ private:
|
|
524
524
|
* not want to preserve that Content-Type.
|
525
525
|
*/
|
526
526
|
ap_set_content_type(r, NULL);
|
527
|
-
|
527
|
+
|
528
528
|
TRACE_POINT();
|
529
529
|
DirConfig *config = note->config;
|
530
530
|
DirectoryMapper &mapper = note->mapper;
|
531
|
-
|
531
|
+
|
532
532
|
try {
|
533
533
|
mapper.getPublicDirectory();
|
534
534
|
} catch (const DocumentRootDeterminationError &e) {
|
@@ -541,17 +541,17 @@ private:
|
|
541
541
|
*/
|
542
542
|
return ReportFileSystemError(e).report(r);
|
543
543
|
}
|
544
|
-
|
545
|
-
|
544
|
+
|
545
|
+
|
546
546
|
UPDATE_TRACE_POINT();
|
547
547
|
try {
|
548
548
|
/********** Step 2: handle HTTP upload data, if any **********/
|
549
|
-
|
549
|
+
|
550
550
|
int httpStatus = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
|
551
551
|
if (httpStatus != OK) {
|
552
552
|
return httpStatus;
|
553
553
|
}
|
554
|
-
|
554
|
+
|
555
555
|
this_thread::disable_interruption di;
|
556
556
|
this_thread::disable_syscall_interruption dsi;
|
557
557
|
bool expectingUploadData;
|
@@ -559,11 +559,11 @@ private:
|
|
559
559
|
string uploadDataMemory;
|
560
560
|
boost::shared_ptr<BufferedUpload> uploadDataFile;
|
561
561
|
const char *contentLength;
|
562
|
-
|
562
|
+
|
563
563
|
expectingUploadData = ap_should_client_block(r);
|
564
564
|
contentLength = lookupHeader(r, "Content-Length");
|
565
565
|
shouldBufferUploads = config->bufferUpload != DirConfig::DISABLED;
|
566
|
-
|
566
|
+
|
567
567
|
/* If the HTTP upload data is larger than a threshold, or if the HTTP
|
568
568
|
* client sent HTTP upload data using the "chunked" transfer encoding
|
569
569
|
* (which implies Content-Length == NULL), then buffer the upload
|
@@ -599,34 +599,34 @@ private:
|
|
599
599
|
toString(uploadDataMemory.size()).c_str());
|
600
600
|
}
|
601
601
|
}
|
602
|
-
|
603
|
-
|
602
|
+
|
603
|
+
|
604
604
|
/********** Step 3: forwarding the request and request body
|
605
605
|
to the HelperAgent **********/
|
606
|
-
|
606
|
+
|
607
607
|
vector<StaticString> requestData;
|
608
608
|
string headerData;
|
609
609
|
unsigned int size;
|
610
610
|
char sizeString[16];
|
611
611
|
int ret;
|
612
|
-
|
612
|
+
|
613
613
|
requestData.reserve(3);
|
614
614
|
headerData.reserve(1024 * 2);
|
615
615
|
requestData.push_back(StaticString());
|
616
616
|
size = constructHeaders(r, config, requestData, mapper, headerData);
|
617
617
|
requestData.push_back(",");
|
618
|
-
|
618
|
+
|
619
619
|
ret = snprintf(sizeString, sizeof(sizeString) - 1, "%u:", size);
|
620
620
|
sizeString[ret] = '\0';
|
621
621
|
requestData[0] = StaticString(sizeString, ret);
|
622
|
-
|
622
|
+
|
623
623
|
if (expectingUploadData && shouldBufferUploads && uploadDataFile == NULL) {
|
624
624
|
requestData.push_back(uploadDataMemory);
|
625
625
|
}
|
626
|
-
|
626
|
+
|
627
627
|
FileDescriptor conn = connectToHelperAgent();
|
628
628
|
gatheredWrite(conn, &requestData[0], requestData.size());
|
629
|
-
|
629
|
+
|
630
630
|
if (expectingUploadData) {
|
631
631
|
if (shouldBufferUploads && uploadDataFile != NULL) {
|
632
632
|
sendRequestBody(conn, uploadDataFile);
|
@@ -635,7 +635,7 @@ private:
|
|
635
635
|
sendRequestBody(conn, r);
|
636
636
|
}
|
637
637
|
}
|
638
|
-
|
638
|
+
|
639
639
|
do {
|
640
640
|
ret = shutdown(conn, SHUT_WR);
|
641
641
|
} while (ret == -1 && errno == EINTR);
|
@@ -646,46 +646,46 @@ private:
|
|
646
646
|
int e = errno;
|
647
647
|
throw SystemException("Cannot shutdown(SHUT_WR) HelperAgent connection", e);
|
648
648
|
}
|
649
|
-
|
649
|
+
|
650
650
|
|
651
651
|
/********** Step 4: forwarding the response from the HelperAgent
|
652
652
|
back to the HTTP client **********/
|
653
|
-
|
653
|
+
|
654
654
|
UPDATE_TRACE_POINT();
|
655
655
|
apr_bucket_brigade *bb;
|
656
656
|
apr_bucket *b;
|
657
657
|
PassengerBucketStatePtr bucketState;
|
658
|
-
|
658
|
+
|
659
659
|
/* Setup the bucket brigade. */
|
660
660
|
bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
|
661
|
-
|
661
|
+
|
662
662
|
bucketState = boost::make_shared<PassengerBucketState>(conn);
|
663
663
|
b = passenger_bucket_create(bucketState, r->connection->bucket_alloc, config->getBufferResponse());
|
664
664
|
APR_BRIGADE_INSERT_TAIL(bb, b);
|
665
|
-
|
665
|
+
|
666
666
|
b = apr_bucket_eos_create(r->connection->bucket_alloc);
|
667
667
|
APR_BRIGADE_INSERT_TAIL(bb, b);
|
668
668
|
|
669
669
|
/* Now read the HTTP response header, parse it and fill relevant
|
670
670
|
* information in our request_rec structure.
|
671
671
|
*/
|
672
|
-
|
672
|
+
|
673
673
|
/* I know the required size for backendData because I read
|
674
674
|
* util_script.c's source. :-(
|
675
675
|
*/
|
676
676
|
char backendData[MAX_STRING_LEN];
|
677
677
|
Timer timer;
|
678
678
|
int result = ap_scan_script_header_err_brigade(r, bb, backendData);
|
679
|
-
|
679
|
+
|
680
680
|
if (result == OK) {
|
681
681
|
// The API documentation for ap_scan_script_err_brigade() says it
|
682
682
|
// returns HTTP_OK on success, but it actually returns OK.
|
683
|
-
|
683
|
+
|
684
684
|
/* We were able to parse the HTTP response header sent by the
|
685
685
|
* backend process! Proceed with passing the bucket brigade,
|
686
686
|
* for forwarding the response body to the HTTP client.
|
687
687
|
*/
|
688
|
-
|
688
|
+
|
689
689
|
/* Manually set the Status header because
|
690
690
|
* ap_scan_script_header_err_brigade() filters it
|
691
691
|
* out. Some broken HTTP clients depend on the
|
@@ -697,7 +697,7 @@ private:
|
|
697
697
|
r->status);
|
698
698
|
}
|
699
699
|
apr_table_setn(r->headers_out, "Status", r->status_line);
|
700
|
-
|
700
|
+
|
701
701
|
UPDATE_TRACE_POINT();
|
702
702
|
if (config->errorOverride == DirConfig::ENABLED
|
703
703
|
&& ap_is_HTTP_ERROR(r->status))
|
@@ -720,25 +720,25 @@ private:
|
|
720
720
|
apr_table_setn(r->err_headers_out, "Status", "500 Internal Server Error");
|
721
721
|
return HTTP_INTERNAL_SERVER_ERROR;
|
722
722
|
}
|
723
|
-
|
723
|
+
|
724
724
|
} catch (const thread_interrupted &e) {
|
725
725
|
P_TRACE(3, "A system call was interrupted during an HTTP request. Apache "
|
726
726
|
"is probably restarting or shutting down. Backtrace:\n" <<
|
727
727
|
e.backtrace());
|
728
728
|
return HTTP_INTERNAL_SERVER_ERROR;
|
729
|
-
|
729
|
+
|
730
730
|
} catch (const tracable_exception &e) {
|
731
731
|
P_ERROR("Unexpected error in mod_passenger: " <<
|
732
732
|
e.what() << "\n" << " Backtrace:\n" << e.backtrace());
|
733
733
|
return HTTP_INTERNAL_SERVER_ERROR;
|
734
|
-
|
734
|
+
|
735
735
|
} catch (const std::exception &e) {
|
736
736
|
P_ERROR("Unexpected error in mod_passenger: " <<
|
737
737
|
e.what() << "\n" << " Backtrace: not available");
|
738
738
|
return HTTP_INTERNAL_SERVER_ERROR;
|
739
739
|
}
|
740
740
|
}
|
741
|
-
|
741
|
+
|
742
742
|
unsigned int
|
743
743
|
escapeUri(unsigned char *dst, const unsigned char *src, size_t size) {
|
744
744
|
static const char hex[] = "0123456789abcdef";
|
@@ -760,7 +760,7 @@ private:
|
|
760
760
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
761
761
|
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
762
762
|
};
|
763
|
-
|
763
|
+
|
764
764
|
if (dst == NULL) {
|
765
765
|
/* find the number of the characters to be escaped */
|
766
766
|
unsigned int n = 0;
|
@@ -773,7 +773,7 @@ private:
|
|
773
773
|
}
|
774
774
|
return n;
|
775
775
|
}
|
776
|
-
|
776
|
+
|
777
777
|
while (size > 0) {
|
778
778
|
if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
|
779
779
|
*dst++ = '%';
|
@@ -797,14 +797,14 @@ private:
|
|
797
797
|
apr_tolower(headerName[sizeof("transfer-encoding") - 2]) == (u_char) 'g' &&
|
798
798
|
apr_strnatcasecmp(headerName + 1, "ransfer-encoding") == 0;
|
799
799
|
}
|
800
|
-
|
800
|
+
|
801
801
|
/**
|
802
802
|
* Convert an HTTP header name to a CGI environment name.
|
803
803
|
*/
|
804
804
|
char *httpToEnv(apr_pool_t *p, const char *headerName, size_t len) {
|
805
805
|
char *result = apr_pstrcat(p, "HTTP_", headerName, (char *) NULL);
|
806
806
|
char *current = result + sizeof("HTTP_") - 1;
|
807
|
-
|
807
|
+
|
808
808
|
while (*current != '\0') {
|
809
809
|
if (*current == '-') {
|
810
810
|
*current = '_';
|
@@ -813,14 +813,14 @@ private:
|
|
813
813
|
}
|
814
814
|
current++;
|
815
815
|
}
|
816
|
-
|
816
|
+
|
817
817
|
return result;
|
818
818
|
}
|
819
|
-
|
819
|
+
|
820
820
|
const char *lookupInTable(apr_table_t *table, const char *name) {
|
821
821
|
const apr_array_header_t *headers = apr_table_elts(table);
|
822
822
|
apr_table_entry_t *elements = (apr_table_entry_t *) headers->elts;
|
823
|
-
|
823
|
+
|
824
824
|
for (int i = 0; i < headers->nelts; i++) {
|
825
825
|
if (elements[i].key != NULL && strcasecmp(elements[i].key, name) == 0) {
|
826
826
|
return elements[i].val;
|
@@ -828,15 +828,15 @@ private:
|
|
828
828
|
}
|
829
829
|
return NULL;
|
830
830
|
}
|
831
|
-
|
831
|
+
|
832
832
|
const char *lookupHeader(request_rec *r, const char *name) {
|
833
833
|
return lookupInTable(r->headers_in, name);
|
834
834
|
}
|
835
|
-
|
835
|
+
|
836
836
|
const char *lookupEnv(request_rec *r, const char *name) {
|
837
837
|
return lookupInTable(r->subprocess_env, name);
|
838
838
|
}
|
839
|
-
|
839
|
+
|
840
840
|
void addHeader(string &headers, const char *name, const char *value) {
|
841
841
|
if (name != NULL && value != NULL) {
|
842
842
|
headers.append(name);
|
@@ -845,7 +845,7 @@ private:
|
|
845
845
|
headers.append(1, '\0');
|
846
846
|
}
|
847
847
|
}
|
848
|
-
|
848
|
+
|
849
849
|
void addHeader(string &headers, const char *name, const StaticString &value) {
|
850
850
|
if (name != NULL) {
|
851
851
|
headers.append(name);
|
@@ -874,13 +874,13 @@ private:
|
|
874
874
|
}
|
875
875
|
}
|
876
876
|
}
|
877
|
-
|
877
|
+
|
878
878
|
unsigned int constructHeaders(request_rec *r, DirConfig *config,
|
879
879
|
vector<StaticString> &requestData, DirectoryMapper &mapper,
|
880
880
|
string &output)
|
881
881
|
{
|
882
882
|
const char *baseURI = mapper.getBaseURI();
|
883
|
-
|
883
|
+
|
884
884
|
/*
|
885
885
|
* Apache unescapes URI's before passing them to Phusion Passenger,
|
886
886
|
* but backend processes expect the escaped version.
|
@@ -891,8 +891,8 @@ private:
|
|
891
891
|
char *escapedUri = (char *) apr_palloc(r->pool, uriLen + 2 * escaped + 1);
|
892
892
|
escapeUri((unsigned char *) escapedUri, (const unsigned char *) r->uri, uriLen);
|
893
893
|
escapedUri[uriLen + 2 * escaped] = '\0';
|
894
|
-
|
895
|
-
|
894
|
+
|
895
|
+
|
896
896
|
// Set standard CGI variables.
|
897
897
|
#ifdef AP_GET_SERVER_VERSION_DEPRECATED
|
898
898
|
addHeader(output, "SERVER_SOFTWARE", ap_get_server_banner());
|
@@ -917,7 +917,7 @@ private:
|
|
917
917
|
addHeader(output, "HTTPS", lookupEnv(r, "HTTPS"));
|
918
918
|
addHeader(output, "CONTENT_TYPE", lookupHeader(r, "Content-type"));
|
919
919
|
addHeader(output, "DOCUMENT_ROOT", ap_document_root(r));
|
920
|
-
|
920
|
+
|
921
921
|
if (config->allowsEncodedSlashes()) {
|
922
922
|
/*
|
923
923
|
* Apache decodes encoded slashes in r->uri, so we must use r->unparsed_uri
|
@@ -938,7 +938,7 @@ private:
|
|
938
938
|
}
|
939
939
|
addHeader(output, "REQUEST_URI", request_uri);
|
940
940
|
}
|
941
|
-
|
941
|
+
|
942
942
|
if (baseURI == NULL) {
|
943
943
|
addHeader(output, "SCRIPT_NAME", "");
|
944
944
|
addHeader(output, "PATH_INFO", escapedUri);
|
@@ -946,12 +946,12 @@ private:
|
|
946
946
|
addHeader(output, "SCRIPT_NAME", baseURI);
|
947
947
|
addHeader(output, "PATH_INFO", escapedUri + strlen(baseURI));
|
948
948
|
}
|
949
|
-
|
949
|
+
|
950
950
|
// Set HTTP headers.
|
951
951
|
const apr_array_header_t *hdrs_arr;
|
952
952
|
apr_table_entry_t *hdrs;
|
953
953
|
int i;
|
954
|
-
|
954
|
+
|
955
955
|
hdrs_arr = apr_table_elts(r->headers_in);
|
956
956
|
hdrs = (apr_table_entry_t *) hdrs_arr->elts;
|
957
957
|
for (i = 0; i < hdrs_arr->nelts; ++i) {
|
@@ -966,17 +966,17 @@ private:
|
|
966
966
|
addHeader(output, httpToEnv(r->pool, hdrs[i].key, keylen), hdrs[i].val);
|
967
967
|
}
|
968
968
|
}
|
969
|
-
|
969
|
+
|
970
970
|
// Add other environment variables.
|
971
971
|
const apr_array_header_t *env_arr;
|
972
972
|
apr_table_entry_t *env;
|
973
|
-
|
973
|
+
|
974
974
|
env_arr = apr_table_elts(r->subprocess_env);
|
975
975
|
env = (apr_table_entry_t*) env_arr->elts;
|
976
976
|
for (i = 0; i < env_arr->nelts; ++i) {
|
977
977
|
addHeader(output, env[i].key, env[i].val);
|
978
978
|
}
|
979
|
-
|
979
|
+
|
980
980
|
// Phusion Passenger options.
|
981
981
|
addHeader(output, "PASSENGER_STATUS_LINE", "false");
|
982
982
|
addHeader(output, "PASSENGER_APP_ROOT", mapper.getAppRoot());
|
@@ -1002,21 +1002,21 @@ private:
|
|
1002
1002
|
config->getUnionStationFilterString());
|
1003
1003
|
}
|
1004
1004
|
}
|
1005
|
-
|
1005
|
+
|
1006
1006
|
/*********************/
|
1007
1007
|
/*********************/
|
1008
|
-
|
1008
|
+
|
1009
1009
|
requestData.push_back(output);
|
1010
1010
|
return output.size();
|
1011
1011
|
}
|
1012
|
-
|
1012
|
+
|
1013
1013
|
void throwUploadBufferingException(request_rec *r, int code) {
|
1014
1014
|
DirConfig *config = getDirConfig(r);
|
1015
1015
|
string message("An error occured while "
|
1016
1016
|
"buffering HTTP upload data to "
|
1017
1017
|
"a temporary file in ");
|
1018
1018
|
message.append(getUploadBufferDir(config));
|
1019
|
-
|
1019
|
+
|
1020
1020
|
switch (code) {
|
1021
1021
|
case ENOSPC:
|
1022
1022
|
message.append(". Disk directory doesn't have enough disk space, "
|
@@ -1062,7 +1062,7 @@ private:
|
|
1062
1062
|
break;
|
1063
1063
|
}
|
1064
1064
|
}
|
1065
|
-
|
1065
|
+
|
1066
1066
|
/**
|
1067
1067
|
* Reads the next chunk of the request body and put it into a buffer.
|
1068
1068
|
*
|
@@ -1082,7 +1082,7 @@ private:
|
|
1082
1082
|
unsigned long readRequestBodyFromApache(request_rec *r, char *buffer, apr_size_t bufsiz) {
|
1083
1083
|
apr_status_t rv;
|
1084
1084
|
apr_bucket_brigade *bb;
|
1085
|
-
|
1085
|
+
|
1086
1086
|
if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) {
|
1087
1087
|
return 0;
|
1088
1088
|
}
|
@@ -1094,10 +1094,10 @@ private:
|
|
1094
1094
|
"unable to create a bucket brigade. Maybe the system doesn't have "
|
1095
1095
|
"enough free memory.");
|
1096
1096
|
}
|
1097
|
-
|
1097
|
+
|
1098
1098
|
rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
|
1099
1099
|
APR_BLOCK_READ, bufsiz);
|
1100
|
-
|
1100
|
+
|
1101
1101
|
/* We lose the failure code here. This is why ap_get_client_block should
|
1102
1102
|
* not be used.
|
1103
1103
|
*/
|
@@ -1107,7 +1107,7 @@ private:
|
|
1107
1107
|
*/
|
1108
1108
|
r->connection->keepalive = AP_CONN_CLOSE;
|
1109
1109
|
apr_brigade_destroy(bb);
|
1110
|
-
|
1110
|
+
|
1111
1111
|
char buf[150], *errorString, message[1024];
|
1112
1112
|
errorString = apr_strerror(rv, buf, sizeof(buf));
|
1113
1113
|
if (errorString != NULL) {
|
@@ -1122,7 +1122,7 @@ private:
|
|
1122
1122
|
message[sizeof(message) - 1] = '\0';
|
1123
1123
|
throw RuntimeException(message);
|
1124
1124
|
}
|
1125
|
-
|
1125
|
+
|
1126
1126
|
/* If this fails, it means that a filter is written incorrectly and that
|
1127
1127
|
* it needs to learn how to properly handle APR_BLOCK_READ requests by
|
1128
1128
|
* returning data when requested.
|
@@ -1150,7 +1150,7 @@ private:
|
|
1150
1150
|
rv = apr_brigade_flatten(bb, buffer, &bufsiz);
|
1151
1151
|
if (rv != APR_SUCCESS) {
|
1152
1152
|
apr_brigade_destroy(bb);
|
1153
|
-
|
1153
|
+
|
1154
1154
|
char buf[150], *errorString, message[1024];
|
1155
1155
|
errorString = apr_strerror(rv, buf, sizeof(buf));
|
1156
1156
|
if (errorString != NULL) {
|
@@ -1165,10 +1165,10 @@ private:
|
|
1165
1165
|
message[sizeof(message) - 1] = '\0';
|
1166
1166
|
throw IOException(message);
|
1167
1167
|
}
|
1168
|
-
|
1168
|
+
|
1169
1169
|
/* XXX yank me? */
|
1170
1170
|
r->read_length += bufsiz;
|
1171
|
-
|
1171
|
+
|
1172
1172
|
apr_brigade_destroy(bb);
|
1173
1173
|
return bufsiz;
|
1174
1174
|
}
|
@@ -1177,7 +1177,7 @@ private:
|
|
1177
1177
|
ServerInstanceDir::GenerationPtr generation = agentsStarter.getGeneration();
|
1178
1178
|
return config->getUploadBufferDir(generation.get());
|
1179
1179
|
}
|
1180
|
-
|
1180
|
+
|
1181
1181
|
/**
|
1182
1182
|
* Receive the HTTP upload data and buffer it into a BufferedUpload temp file.
|
1183
1183
|
*
|
@@ -1195,11 +1195,11 @@ private:
|
|
1195
1195
|
} catch (const SystemException &e) {
|
1196
1196
|
throwUploadBufferingException(r, e.code());
|
1197
1197
|
}
|
1198
|
-
|
1198
|
+
|
1199
1199
|
char buf[1024 * 32];
|
1200
1200
|
apr_off_t len;
|
1201
1201
|
size_t total_written = 0;
|
1202
|
-
|
1202
|
+
|
1203
1203
|
while ((len = readRequestBodyFromApache(r, buf, sizeof(buf))) > 0) {
|
1204
1204
|
size_t written = 0;
|
1205
1205
|
do {
|
@@ -1213,7 +1213,7 @@ private:
|
|
1213
1213
|
}
|
1214
1214
|
return tempFile;
|
1215
1215
|
}
|
1216
|
-
|
1216
|
+
|
1217
1217
|
/**
|
1218
1218
|
* Receive the HTTP upload data and buffer it into a string.
|
1219
1219
|
*
|
@@ -1231,25 +1231,25 @@ private:
|
|
1231
1231
|
unsigned long l_contentLength = 0;
|
1232
1232
|
char buf[1024 * 32];
|
1233
1233
|
apr_off_t len;
|
1234
|
-
|
1234
|
+
|
1235
1235
|
buffer.clear();
|
1236
1236
|
if (contentLength != NULL) {
|
1237
1237
|
l_contentLength = atol(contentLength);
|
1238
1238
|
buffer.reserve(l_contentLength);
|
1239
1239
|
}
|
1240
|
-
|
1240
|
+
|
1241
1241
|
while ((len = readRequestBodyFromApache(r, buf, sizeof(buf))) > 0) {
|
1242
1242
|
buffer.append(buf, len);
|
1243
1243
|
}
|
1244
1244
|
}
|
1245
|
-
|
1245
|
+
|
1246
1246
|
void sendRequestBody(const FileDescriptor &fd, boost::shared_ptr<BufferedUpload> &uploadData) {
|
1247
1247
|
TRACE_POINT();
|
1248
1248
|
rewind(uploadData->handle);
|
1249
1249
|
while (!feof(uploadData->handle)) {
|
1250
1250
|
char buf[1024 * 32];
|
1251
1251
|
size_t size;
|
1252
|
-
|
1252
|
+
|
1253
1253
|
size = fread(buf, 1, sizeof(buf), uploadData->handle);
|
1254
1254
|
try {
|
1255
1255
|
writeExact(fd, buf, size);
|
@@ -1269,7 +1269,7 @@ private:
|
|
1269
1269
|
TRACE_POINT();
|
1270
1270
|
char buf[1024 * 32];
|
1271
1271
|
apr_off_t len;
|
1272
|
-
|
1272
|
+
|
1273
1273
|
try {
|
1274
1274
|
while ((len = readRequestBodyFromApache(r, buf, sizeof(buf))) > 0) {
|
1275
1275
|
writeExact(fd, buf, len);
|
@@ -1299,10 +1299,10 @@ public:
|
|
1299
1299
|
m_hasModDir = UNKNOWN;
|
1300
1300
|
m_hasModAutoIndex = UNKNOWN;
|
1301
1301
|
m_hasModXsendfile = UNKNOWN;
|
1302
|
-
|
1302
|
+
|
1303
1303
|
P_DEBUG("Initializing Phusion Passenger...");
|
1304
1304
|
ap_add_version_component(pconf, "Phusion_Passenger/" PASSENGER_VERSION);
|
1305
|
-
|
1305
|
+
|
1306
1306
|
if (serverConfig.root == NULL) {
|
1307
1307
|
throw ConfigurationException("The 'PassengerRoot' configuration option "
|
1308
1308
|
"is not specified. This option is required, so please specify it. "
|
@@ -1331,16 +1331,16 @@ public:
|
|
1331
1331
|
.set ("union_station_gateway_cert", serverConfig.unionStationGatewayCert)
|
1332
1332
|
.set ("union_station_proxy_address", serverConfig.unionStationProxyAddress)
|
1333
1333
|
.setStrSet("prestart_urls", serverConfig.prestartURLs);
|
1334
|
-
|
1334
|
+
|
1335
1335
|
serverConfig.ctl.addTo(params);
|
1336
1336
|
|
1337
1337
|
agentsStarter.start(serverConfig.root, params);
|
1338
|
-
|
1338
|
+
|
1339
1339
|
// Store some relevant information in the generation directory.
|
1340
1340
|
string generationPath = agentsStarter.getGeneration()->getPath();
|
1341
1341
|
server_rec *server;
|
1342
1342
|
string configFiles;
|
1343
|
-
|
1343
|
+
|
1344
1344
|
#ifdef AP_GET_SERVER_VERSION_DEPRECATED
|
1345
1345
|
createFile(generationPath + "/web_server.txt",
|
1346
1346
|
ap_get_server_description());
|
@@ -1348,7 +1348,7 @@ public:
|
|
1348
1348
|
createFile(generationPath + "/web_server.txt",
|
1349
1349
|
ap_get_server_version());
|
1350
1350
|
#endif
|
1351
|
-
|
1351
|
+
|
1352
1352
|
for (server = s; server != NULL; server = server->next) {
|
1353
1353
|
if (server->defn_name != NULL) {
|
1354
1354
|
configFiles.append(server->defn_name);
|
@@ -1357,11 +1357,11 @@ public:
|
|
1357
1357
|
}
|
1358
1358
|
createFile(generationPath + "/config_files.txt", configFiles);
|
1359
1359
|
}
|
1360
|
-
|
1360
|
+
|
1361
1361
|
void childInit(apr_pool_t *pchild, server_rec *s) {
|
1362
1362
|
agentsStarter.detach();
|
1363
1363
|
}
|
1364
|
-
|
1364
|
+
|
1365
1365
|
int prepareRequestWhenInHighPerformanceMode(request_rec *r) {
|
1366
1366
|
DirConfig *config = getDirConfig(r);
|
1367
1367
|
if (config->isEnabled() && config->highPerformanceMode()) {
|
@@ -1374,21 +1374,21 @@ public:
|
|
1374
1374
|
return DECLINED;
|
1375
1375
|
}
|
1376
1376
|
}
|
1377
|
-
|
1377
|
+
|
1378
1378
|
/**
|
1379
1379
|
* This is the hook method for the map_to_storage hook. Apache's final map_to_storage hook
|
1380
1380
|
* method (defined in core.c) will do the following:
|
1381
1381
|
*
|
1382
1382
|
* If r->filename doesn't exist, then it will change the filename to the
|
1383
1383
|
* following form:
|
1384
|
-
*
|
1384
|
+
*
|
1385
1385
|
* A/B
|
1386
|
-
*
|
1386
|
+
*
|
1387
1387
|
* A is top-most directory that exists. B is the first filename piece that
|
1388
1388
|
* normally follows A. For example, suppose that a website's DocumentRoot
|
1389
1389
|
* is /website, on server http://test.com/. Suppose that there's also a
|
1390
1390
|
* directory /website/images. No other files or directories exist in /website.
|
1391
|
-
*
|
1391
|
+
*
|
1392
1392
|
* If we access: then r->filename will be:
|
1393
1393
|
* http://test.com/foo/bar /website/foo
|
1394
1394
|
* http://test.com/foo/bar/baz /website/foo
|
@@ -1402,7 +1402,7 @@ public:
|
|
1402
1402
|
apr_table_set(r->notes, "Phusion Passenger: original filename", r->filename);
|
1403
1403
|
return DECLINED;
|
1404
1404
|
}
|
1405
|
-
|
1405
|
+
|
1406
1406
|
int prepareRequestWhenNotInHighPerformanceMode(request_rec *r) {
|
1407
1407
|
DirConfig *config = getDirConfig(r);
|
1408
1408
|
if (config->isEnabled()) {
|
@@ -1432,7 +1432,7 @@ public:
|
|
1432
1432
|
return DECLINED;
|
1433
1433
|
}
|
1434
1434
|
}
|
1435
|
-
|
1435
|
+
|
1436
1436
|
/**
|
1437
1437
|
* The default .htaccess provided by on Rails on Rails (that is, before version 2.1.0)
|
1438
1438
|
* has the following mod_rewrite rules in it:
|
@@ -1465,7 +1465,7 @@ public:
|
|
1465
1465
|
if (note == 0 || !hasModRewrite()) {
|
1466
1466
|
return DECLINED;
|
1467
1467
|
}
|
1468
|
-
|
1468
|
+
|
1469
1469
|
if (r->handler != NULL && strcmp(r->handler, "redirect-handler") == 0) {
|
1470
1470
|
// Check whether r->filename looks like "redirect:.../dispatch.(f)cgi"
|
1471
1471
|
size_t len = strlen(r->filename);
|
@@ -1482,7 +1482,7 @@ public:
|
|
1482
1482
|
}
|
1483
1483
|
return DECLINED;
|
1484
1484
|
}
|
1485
|
-
|
1485
|
+
|
1486
1486
|
/**
|
1487
1487
|
* mod_dir does the following:
|
1488
1488
|
* If r->filename is a directory, and the URI doesn't end with a slash,
|
@@ -1506,7 +1506,7 @@ public:
|
|
1506
1506
|
}
|
1507
1507
|
return DECLINED;
|
1508
1508
|
}
|
1509
|
-
|
1509
|
+
|
1510
1510
|
int endBlockingModDir(request_rec *r) {
|
1511
1511
|
RequestNote *note = getRequestNote(r);
|
1512
1512
|
if (note != 0 && hasModDir()) {
|
@@ -1514,7 +1514,7 @@ public:
|
|
1514
1514
|
}
|
1515
1515
|
return DECLINED;
|
1516
1516
|
}
|
1517
|
-
|
1517
|
+
|
1518
1518
|
/**
|
1519
1519
|
* mod_autoindex will try to display a directory index for URIs that map to a directory.
|
1520
1520
|
* This is undesired because of page caching semantics. Suppose that a Rails application
|
@@ -1534,7 +1534,7 @@ public:
|
|
1534
1534
|
}
|
1535
1535
|
return DECLINED;
|
1536
1536
|
}
|
1537
|
-
|
1537
|
+
|
1538
1538
|
int endBlockingModAutoIndex(request_rec *r) {
|
1539
1539
|
RequestNote *note = getRequestNote(r);
|
1540
1540
|
if (note != 0 && hasModAutoIndex()) {
|
@@ -1542,7 +1542,7 @@ public:
|
|
1542
1542
|
}
|
1543
1543
|
return DECLINED;
|
1544
1544
|
}
|
1545
|
-
|
1545
|
+
|
1546
1546
|
int handleRequestWhenInHighPerformanceMode(request_rec *r) {
|
1547
1547
|
DirConfig *config = getDirConfig(r);
|
1548
1548
|
if (config->highPerformanceMode()) {
|
@@ -1551,7 +1551,7 @@ public:
|
|
1551
1551
|
return DECLINED;
|
1552
1552
|
}
|
1553
1553
|
}
|
1554
|
-
|
1554
|
+
|
1555
1555
|
int handleRequestWhenNotInHighPerformanceMode(request_rec *r) {
|
1556
1556
|
DirConfig *config = getDirConfig(r);
|
1557
1557
|
if (config->highPerformanceMode()) {
|
@@ -1625,18 +1625,18 @@ init_module(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *
|
|
1625
1625
|
destroy_hooks,
|
1626
1626
|
apr_pool_cleanup_null);
|
1627
1627
|
return OK;
|
1628
|
-
|
1628
|
+
|
1629
1629
|
} catch (const thread_interrupted &e) {
|
1630
1630
|
P_TRACE(2, "A system call was interrupted during mod_passenger "
|
1631
1631
|
"initialization. Apache might be restarting or shutting "
|
1632
1632
|
"down. Backtrace:\n" << e.backtrace());
|
1633
1633
|
return DECLINED;
|
1634
|
-
|
1634
|
+
|
1635
1635
|
} catch (const thread_resource_error &e) {
|
1636
1636
|
struct rlimit lim;
|
1637
1637
|
string pthread_threads_max;
|
1638
1638
|
int ret;
|
1639
|
-
|
1639
|
+
|
1640
1640
|
lim.rlim_cur = 0;
|
1641
1641
|
lim.rlim_max = 0;
|
1642
1642
|
|
@@ -1644,7 +1644,7 @@ init_module(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *
|
|
1644
1644
|
#ifdef RLIMIT_NPROC
|
1645
1645
|
getrlimit(RLIMIT_NPROC, &lim);
|
1646
1646
|
#else
|
1647
|
-
lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
|
1647
|
+
lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
|
1648
1648
|
#endif
|
1649
1649
|
|
1650
1650
|
#ifdef PTHREAD_THREADS_MAX
|
@@ -1652,7 +1652,7 @@ init_module(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *
|
|
1652
1652
|
#else
|
1653
1653
|
pthread_threads_max = "unknown";
|
1654
1654
|
#endif
|
1655
|
-
|
1655
|
+
|
1656
1656
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
1657
1657
|
"*** Passenger could not be initialize because a "
|
1658
1658
|
"threading resource could not be allocated or initialized. "
|
@@ -1666,19 +1666,19 @@ init_module(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *
|
|
1666
1666
|
e.what(),
|
1667
1667
|
(int) lim.rlim_cur, (int) lim.rlim_max,
|
1668
1668
|
pthread_threads_max.c_str());
|
1669
|
-
|
1669
|
+
|
1670
1670
|
fprintf(stderr, "Output of 'uname -a' follows:\n");
|
1671
1671
|
fflush(stderr);
|
1672
1672
|
ret = ::system("uname -a >&2");
|
1673
1673
|
(void) ret; // Ignore compiler warning.
|
1674
|
-
|
1674
|
+
|
1675
1675
|
fprintf(stderr, "\nOutput of 'ulimit -a' follows:\n");
|
1676
1676
|
fflush(stderr);
|
1677
1677
|
ret = ::system("ulimit -a >&2");
|
1678
1678
|
(void) ret; // Ignore compiler warning.
|
1679
|
-
|
1679
|
+
|
1680
1680
|
return DECLINED;
|
1681
|
-
|
1681
|
+
|
1682
1682
|
} catch (const std::exception &e) {
|
1683
1683
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
1684
1684
|
"*** Passenger could not be initialized because of this error: %s",
|
@@ -1725,21 +1725,21 @@ passenger_register_hooks(apr_pool_t *p) {
|
|
1725
1725
|
static const char * const rewrite_module[] = { "mod_rewrite.c", NULL };
|
1726
1726
|
static const char * const dir_module[] = { "mod_dir.c", NULL };
|
1727
1727
|
static const char * const autoindex_module[] = { "mod_autoindex.c", NULL };
|
1728
|
-
|
1728
|
+
|
1729
1729
|
ap_hook_post_config(init_module, NULL, NULL, APR_HOOK_MIDDLE);
|
1730
1730
|
ap_hook_child_init(child_init, NULL, NULL, APR_HOOK_MIDDLE);
|
1731
|
-
|
1731
|
+
|
1732
1732
|
// The hooks here are defined in the order that they're called.
|
1733
|
-
|
1733
|
+
|
1734
1734
|
ap_hook_map_to_storage(prepare_request_when_in_high_performance_mode, NULL, NULL, APR_HOOK_FIRST);
|
1735
1735
|
ap_hook_map_to_storage(save_original_filename, NULL, NULL, APR_HOOK_LAST);
|
1736
|
-
|
1736
|
+
|
1737
1737
|
ap_hook_fixups(prepare_request_when_not_in_high_performance_mode, NULL, rewrite_module, APR_HOOK_FIRST);
|
1738
1738
|
ap_hook_fixups(save_state_before_rewrite_rules, NULL, rewrite_module, APR_HOOK_LAST);
|
1739
1739
|
ap_hook_fixups(undo_redirection_to_dispatch_cgi, rewrite_module, NULL, APR_HOOK_FIRST);
|
1740
1740
|
ap_hook_fixups(start_blocking_mod_dir, NULL, dir_module, APR_HOOK_LAST);
|
1741
1741
|
ap_hook_fixups(end_blocking_mod_dir, dir_module, NULL, APR_HOOK_LAST);
|
1742
|
-
|
1742
|
+
|
1743
1743
|
ap_hook_handler(handle_request_when_in_high_performance_mode, NULL, NULL, APR_HOOK_FIRST);
|
1744
1744
|
ap_hook_handler(start_blocking_mod_autoindex, NULL, autoindex_module, APR_HOOK_LAST);
|
1745
1745
|
ap_hook_handler(end_blocking_mod_autoindex, autoindex_module, NULL, APR_HOOK_FIRST);
|