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
@@ -156,9 +156,9 @@ Client::onAppInputData(const EventedBufferedInputPtr &source, const StaticString
|
|
156
156
|
void
|
157
157
|
Client::onAppInputChunk(const char *data, size_t size, void *userData) {
|
158
158
|
Client *client = (Client *) userData;
|
159
|
-
|
160
|
-
|
161
|
-
|
159
|
+
if (client != NULL && client->connected()) {
|
160
|
+
client->requestHandler->onAppInputChunk(client->shared_from_this(), StaticString(data, size));
|
161
|
+
}
|
162
162
|
}
|
163
163
|
|
164
164
|
void
|
@@ -278,7 +278,7 @@ main() {
|
|
278
278
|
FileDescriptor requestSocket(createTcpServer("127.0.0.1", 3000));
|
279
279
|
setNonBlocking(requestSocket);
|
280
280
|
handler = new RequestHandler(libev, requestSocket, pool, options);
|
281
|
-
|
281
|
+
|
282
282
|
ev_signal_init(&sigquitwatcher, sigquit_cb, SIGQUIT);
|
283
283
|
ev_signal_start(loop, &sigquitwatcher);
|
284
284
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011-
|
3
|
+
* Copyright (c) 2011-2014 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -25,7 +25,7 @@
|
|
25
25
|
|
26
26
|
/*
|
27
27
|
STAGES
|
28
|
-
|
28
|
+
|
29
29
|
Accept connect password
|
30
30
|
|
|
31
31
|
\|/
|
@@ -113,6 +113,7 @@
|
|
113
113
|
#include <boost/weak_ptr.hpp>
|
114
114
|
#include <boost/make_shared.hpp>
|
115
115
|
#include <boost/regex.hpp>
|
116
|
+
#include <boost/cstdint.hpp>
|
116
117
|
#include <ev++.h>
|
117
118
|
|
118
119
|
#if defined(__GLIBCXX__) || defined(__APPLE__)
|
@@ -186,21 +187,21 @@ private:
|
|
186
187
|
static void onClientBodyBufferEnd(const FileBackedPipePtr &source);
|
187
188
|
static void onClientBodyBufferError(const FileBackedPipePtr &source, int errorCode);
|
188
189
|
static void onClientBodyBufferCommit(const FileBackedPipePtr &source);
|
189
|
-
|
190
|
+
|
190
191
|
static void onClientOutputPipeData(const FileBackedPipePtr &source,
|
191
192
|
const char *data, size_t size,
|
192
193
|
const FileBackedPipe::ConsumeCallback &callback);
|
193
194
|
static void onClientOutputPipeEnd(const FileBackedPipePtr &source);
|
194
195
|
static void onClientOutputPipeError(const FileBackedPipePtr &source, int errorCode);
|
195
196
|
static void onClientOutputPipeCommit(const FileBackedPipePtr &source);
|
196
|
-
|
197
|
+
|
197
198
|
void onClientOutputWritable(ev::io &io, int revents);
|
198
199
|
|
199
200
|
static size_t onAppInputData(const EventedBufferedInputPtr &source, const StaticString &data);
|
200
201
|
static void onAppInputChunk(const char *data, size_t size, void *userData);
|
201
202
|
static void onAppInputChunkEnd(void *userData);
|
202
203
|
static void onAppInputError(const EventedBufferedInputPtr &source, const char *message, int errnoCode);
|
203
|
-
|
204
|
+
|
204
205
|
void onAppOutputWritable(ev::io &io, int revents);
|
205
206
|
|
206
207
|
void onTimeout(ev::timer &timer, int revents);
|
@@ -313,7 +314,7 @@ public:
|
|
313
314
|
* socket (e.g. WebSocket data).
|
314
315
|
*
|
315
316
|
* Possible values:
|
316
|
-
*
|
317
|
+
*
|
317
318
|
* -1: infinite. Should keep forwarding client body until end of stream.
|
318
319
|
* 0: no client body. Should stop after sending headers to application.
|
319
320
|
* >0: Should forward exactly this many bytes of the client body.
|
@@ -366,7 +367,7 @@ public:
|
|
366
367
|
clientInput->onData = onClientInputData;
|
367
368
|
clientInput->onError = onClientInputError;
|
368
369
|
clientInput->userData = this;
|
369
|
-
|
370
|
+
|
370
371
|
clientBodyBuffer = boost::make_shared<FileBackedPipe>("/tmp");
|
371
372
|
clientBodyBuffer->userData = this;
|
372
373
|
clientBodyBuffer->onData = onClientBodyBufferData;
|
@@ -383,12 +384,12 @@ public:
|
|
383
384
|
|
384
385
|
clientOutputWatcher.set<Client, &Client::onClientOutputWritable>(this);
|
385
386
|
|
386
|
-
|
387
|
+
|
387
388
|
appInput = boost::make_shared< EventedBufferedInput<> >();
|
388
389
|
appInput->onData = onAppInputData;
|
389
390
|
appInput->onError = onAppInputError;
|
390
391
|
appInput->userData = this;
|
391
|
-
|
392
|
+
|
392
393
|
appOutputWatcher.set<Client, &Client::onAppOutputWritable>(this);
|
393
394
|
|
394
395
|
|
@@ -398,7 +399,7 @@ public:
|
|
398
399
|
responseDechunker.onData = onAppInputChunk;
|
399
400
|
responseDechunker.onEnd = onAppInputChunkEnd;
|
400
401
|
responseDechunker.userData = this;
|
401
|
-
|
402
|
+
|
402
403
|
|
403
404
|
bufferedConnectPassword.data = NULL;
|
404
405
|
bufferedConnectPassword.alreadyRead = 0;
|
@@ -453,7 +454,7 @@ public:
|
|
453
454
|
appInput->reset(NULL, FileDescriptor());
|
454
455
|
appOutputBuffer.resize(0);
|
455
456
|
appOutputWatcher.stop();
|
456
|
-
|
457
|
+
|
457
458
|
timeoutTimer.stop();
|
458
459
|
scgiParser.reset();
|
459
460
|
session.reset();
|
@@ -873,7 +874,7 @@ private:
|
|
873
874
|
* possibly modifies it, and forwards it to
|
874
875
|
* clientOutputPipe.
|
875
876
|
*****************************************************/
|
876
|
-
|
877
|
+
|
877
878
|
struct Header {
|
878
879
|
StaticString key;
|
879
880
|
StaticString value;
|
@@ -884,7 +885,7 @@ private:
|
|
884
885
|
: key(_key),
|
885
886
|
value(_value)
|
886
887
|
{ }
|
887
|
-
|
888
|
+
|
888
889
|
bool empty() const {
|
889
890
|
return key.empty();
|
890
891
|
}
|
@@ -915,11 +916,11 @@ private:
|
|
915
916
|
const char *start = data;
|
916
917
|
const char *end = data + size;
|
917
918
|
const char *terminator;
|
918
|
-
|
919
|
+
|
919
920
|
while (start < end && *start == ' ') {
|
920
921
|
start++;
|
921
922
|
}
|
922
|
-
|
923
|
+
|
923
924
|
terminator = (const char *) memchr(start, '\r', end - start);
|
924
925
|
if (terminator == NULL) {
|
925
926
|
return StaticString();
|
@@ -1054,7 +1055,7 @@ private:
|
|
1054
1055
|
headerData.reserve(origHeaderData.size() + 150);
|
1055
1056
|
// Strip trailing CRLF.
|
1056
1057
|
headerData.append(origHeaderData.data(), origHeaderData.size() - 2);
|
1057
|
-
|
1058
|
+
|
1058
1059
|
if (startsWith(headerData, "HTTP/1.")) {
|
1059
1060
|
Header status = lookupHeader(headerData, "Status", "status");
|
1060
1061
|
if (status.empty()) {
|
@@ -1144,7 +1145,7 @@ private:
|
|
1144
1145
|
headerData.append("\r\n");
|
1145
1146
|
|
1146
1147
|
// Invalidate all cookies with a different route.
|
1147
|
-
//
|
1148
|
+
//
|
1148
1149
|
// TODO: This is not entirely correct. Clients MAY send multiple Cookie
|
1149
1150
|
// headers, although this is in practice extremely rare.
|
1150
1151
|
// http://stackoverflow.com/questions/16305814/are-multiple-cookie-headers-allowed-in-an-http-request
|
@@ -1937,7 +1938,7 @@ private:
|
|
1937
1938
|
}
|
1938
1939
|
options.baseURI = scriptName;
|
1939
1940
|
}
|
1940
|
-
|
1941
|
+
|
1941
1942
|
options.ruby = this->options.defaultRubyCommand;
|
1942
1943
|
options.logLevel = getLogLevel();
|
1943
1944
|
options.loggingAgentAddress = this->options.loggingAgentAddress;
|
@@ -1969,7 +1970,7 @@ private:
|
|
1969
1970
|
fillPoolOption(client, options.raiseInternalError, "PASSENGER_RAISE_INTERNAL_ERROR");
|
1970
1971
|
setStickySessionId(client);
|
1971
1972
|
/******************/
|
1972
|
-
|
1973
|
+
|
1973
1974
|
for (it = client->scgiParser.begin(); it != end; it++) {
|
1974
1975
|
if (!startsWith(it->first, "PASSENGER_")
|
1975
1976
|
&& !startsWith(it->first, "HTTP_")
|
@@ -2001,7 +2002,7 @@ private:
|
|
2001
2002
|
client->options.analytics = true;
|
2002
2003
|
client->options.unionStationKey = key;
|
2003
2004
|
}
|
2004
|
-
|
2005
|
+
|
2005
2006
|
client->beginScopeLog(&client->scopeLogs.requestProcessing, "request processing");
|
2006
2007
|
|
2007
2008
|
StaticString staticRequestMethod = parser.getHeader("REQUEST_METHOD");
|
@@ -2301,7 +2302,7 @@ private:
|
|
2301
2302
|
|
2302
2303
|
void writeSpawnExceptionErrorResponse(const ClientPtr &client, const boost::shared_ptr<SpawnException> &e) {
|
2303
2304
|
RH_ERROR(client, "Cannot checkout session because a spawning error occurred. " <<
|
2304
|
-
"The identifier of the error is " << e->get("
|
2305
|
+
"The identifier of the error is " << e->get("error_id") << ". Please see earlier logs for " <<
|
2305
2306
|
"details about the error.");
|
2306
2307
|
writeErrorResponse(client, e->getErrorPage(), e.get());
|
2307
2308
|
}
|
@@ -2323,7 +2324,7 @@ private:
|
|
2323
2324
|
|
2324
2325
|
RH_WARN(client, "Cannot checkout session (exception type " <<
|
2325
2326
|
typeName << "): " << e->what());
|
2326
|
-
|
2327
|
+
|
2327
2328
|
string response = "An internal error occurred while trying to spawn the application.\n";
|
2328
2329
|
response.append("Exception type: ");
|
2329
2330
|
response.append(typeName);
|
@@ -2362,7 +2363,7 @@ private:
|
|
2362
2363
|
}
|
2363
2364
|
return;
|
2364
2365
|
}
|
2365
|
-
|
2366
|
+
|
2366
2367
|
if (client->useUnionStation()) {
|
2367
2368
|
client->endScopeLog(&client->scopeLogs.getFromPool);
|
2368
2369
|
client->logMessage("Application PID: " +
|
@@ -2370,7 +2371,7 @@ private:
|
|
2370
2371
|
" (GUPID: " + client->session->getGupid() + ")");
|
2371
2372
|
client->beginScopeLog(&client->scopeLogs.requestProxying, "request proxying");
|
2372
2373
|
}
|
2373
|
-
|
2374
|
+
|
2374
2375
|
RH_DEBUG(client, "Session initiated: fd=" << client->session->fd());
|
2375
2376
|
setNonBlocking(client->session->fd());
|
2376
2377
|
client->appInput->reset(libev.get(), client->session->fd());
|
@@ -2398,10 +2399,10 @@ private:
|
|
2398
2399
|
disconnectWithError(client,
|
2399
2400
|
"Application sent EOF before we were able to send headers to it");
|
2400
2401
|
} else if (client->session->getProtocol() == "session") {
|
2401
|
-
char sizeField[sizeof(uint32_t)];
|
2402
|
+
char sizeField[sizeof(boost::uint32_t)];
|
2402
2403
|
SmallVector<StaticString, 10> data;
|
2403
2404
|
|
2404
|
-
data.push_back(StaticString(sizeField, sizeof(uint32_t)));
|
2405
|
+
data.push_back(StaticString(sizeField, sizeof(boost::uint32_t)));
|
2405
2406
|
data.push_back(client->scgiParser.getHeaderData());
|
2406
2407
|
|
2407
2408
|
data.push_back(makeStaticStringWithNull("PASSENGER_CONNECT_PASSWORD"));
|
@@ -2412,9 +2413,9 @@ private:
|
|
2412
2413
|
data.push_back(makeStaticStringWithNull(client->options.transaction->getTxnId()));
|
2413
2414
|
}
|
2414
2415
|
|
2415
|
-
uint32_t dataSize = 0;
|
2416
|
+
boost::uint32_t dataSize = 0;
|
2416
2417
|
for (unsigned int i = 1; i < data.size(); i++) {
|
2417
|
-
dataSize += (uint32_t) data[i].size();
|
2418
|
+
dataSize += (boost::uint32_t) data[i].size();
|
2418
2419
|
}
|
2419
2420
|
Uint32Message::generate(sizeField, dataSize);
|
2420
2421
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010 Phusion
|
3
|
+
* Copyright (c) 2010-2014 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -55,12 +55,12 @@ using namespace std;
|
|
55
55
|
* char buf[1024 * 16];
|
56
56
|
* ssize_t size;
|
57
57
|
* unsigned in bytesAccepted;
|
58
|
-
*
|
58
|
+
*
|
59
59
|
* do {
|
60
60
|
* size = read(fd, buf, sizeof(buf));
|
61
61
|
* bytesAccepted = parser.feed(buf, size);
|
62
62
|
* } while (parser.acceptingInput());
|
63
|
-
*
|
63
|
+
*
|
64
64
|
* // Check whether a parse error occured.
|
65
65
|
* if (parser.getState() == ScgiRequestParser::ERROR) {
|
66
66
|
* bailOut();
|
@@ -68,7 +68,7 @@ using namespace std;
|
|
68
68
|
* // All good! Do something with the SCGI header that the parser parsed.
|
69
69
|
* processHeader(parser.getHeaderData());
|
70
70
|
* print(parser.getHeader("DOCUMENT_ROOT"));
|
71
|
-
*
|
71
|
+
*
|
72
72
|
* // If the last buffer passed to the parser also contains body data,
|
73
73
|
* // then the body data starts at 'buf + bytesAccepted'.
|
74
74
|
* if (bytesAccepted < size) {
|
@@ -115,53 +115,53 @@ public:
|
|
115
115
|
DONE,
|
116
116
|
ERROR
|
117
117
|
};
|
118
|
-
|
118
|
+
|
119
119
|
enum ErrorReason {
|
120
120
|
NONE,
|
121
|
-
|
121
|
+
|
122
122
|
/** The header has a length of 0 bytes. */
|
123
123
|
EMPTY_HEADER,
|
124
|
-
|
124
|
+
|
125
125
|
/** The length string is too large. */
|
126
126
|
LENGTH_STRING_TOO_LARGE,
|
127
|
-
|
127
|
+
|
128
128
|
/** The header is larger than the maxSize value provided to the constructor. */
|
129
129
|
LIMIT_REACHED,
|
130
|
-
|
130
|
+
|
131
131
|
/** The length string contains an invalid character. */
|
132
132
|
INVALID_LENGTH_STRING,
|
133
|
-
|
134
|
-
/** A header terminator character (",") was expected, but
|
133
|
+
|
134
|
+
/** A header terminator character (",") was expected, but something else
|
135
135
|
* was encountered instead. */
|
136
136
|
HEADER_TERMINATOR_EXPECTED,
|
137
|
-
|
137
|
+
|
138
138
|
/** The header data itself contains errors. */
|
139
139
|
INVALID_HEADER_DATA
|
140
140
|
};
|
141
|
-
|
141
|
+
|
142
142
|
private:
|
143
143
|
State state;
|
144
144
|
ErrorReason errorReason;
|
145
145
|
unsigned int lengthStringBufferSize;
|
146
146
|
size_t headerSize;
|
147
147
|
size_t maxSize;
|
148
|
-
|
148
|
+
|
149
149
|
StaticString headerData;
|
150
150
|
string headerBuffer;
|
151
151
|
HeaderMap headers;
|
152
152
|
char lengthStringBuffer[sizeof("4294967296")];
|
153
|
-
|
153
|
+
|
154
154
|
static inline bool isDigit(char byte) {
|
155
155
|
return byte >= '0' && byte <= '9';
|
156
156
|
}
|
157
|
-
|
157
|
+
|
158
158
|
/**
|
159
159
|
* Parse the given header data into key-value pairs, returns whether parsing succeeded.
|
160
160
|
*/
|
161
161
|
bool parseHeaderData(const StaticString &data, HeaderMap &output) {
|
162
162
|
const char *current = data.data();
|
163
163
|
const char *end = data.data() + data.size();
|
164
|
-
|
164
|
+
|
165
165
|
while (current < end) {
|
166
166
|
const char *keyEnd = (const char *) memchr(current, '\0', end - current);
|
167
167
|
if (OXT_UNLIKELY(
|
@@ -170,24 +170,24 @@ private:
|
|
170
170
|
) {
|
171
171
|
return false;
|
172
172
|
}
|
173
|
-
|
173
|
+
|
174
174
|
StaticString key(current, keyEnd - current);
|
175
175
|
current = keyEnd + 1;
|
176
176
|
if (OXT_UNLIKELY(current >= end)) {
|
177
177
|
return false;
|
178
178
|
}
|
179
|
-
|
179
|
+
|
180
180
|
const char *valueEnd = (const char *) memchr(current, '\0', end - current);
|
181
181
|
if (OXT_UNLIKELY(valueEnd == NULL)) {
|
182
182
|
return false;
|
183
183
|
}
|
184
|
-
|
184
|
+
|
185
185
|
output[key] = StaticString(current, valueEnd - current);
|
186
186
|
current = valueEnd + 1;
|
187
187
|
}
|
188
188
|
return true;
|
189
189
|
}
|
190
|
-
|
190
|
+
|
191
191
|
public:
|
192
192
|
/**
|
193
193
|
* Create a new ScgiRequestParser, ready to parse a request.
|
@@ -199,7 +199,7 @@ public:
|
|
199
199
|
this->maxSize = maxSize;
|
200
200
|
reset();
|
201
201
|
}
|
202
|
-
|
202
|
+
|
203
203
|
void reset() {
|
204
204
|
state = READING_LENGTH_STRING;
|
205
205
|
errorReason = NONE;
|
@@ -227,41 +227,47 @@ public:
|
|
227
227
|
*/
|
228
228
|
size_t feed(const char *data, size_t size) {
|
229
229
|
size_t consumed = 0;
|
230
|
-
|
230
|
+
|
231
231
|
while (acceptingInput() && consumed < size) {
|
232
232
|
switch (state) {
|
233
233
|
case READING_LENGTH_STRING:
|
234
234
|
while (consumed < size
|
235
|
-
&& lengthStringBufferSize < sizeof(lengthStringBuffer)
|
236
|
-
&& isDigit(data[consumed]))
|
235
|
+
&& lengthStringBufferSize < sizeof(lengthStringBuffer)
|
236
|
+
&& isDigit(data[consumed]))
|
237
|
+
{
|
237
238
|
lengthStringBuffer[lengthStringBufferSize] = data[consumed];
|
238
239
|
lengthStringBufferSize++;
|
239
240
|
consumed++;
|
240
241
|
}
|
241
242
|
if (consumed < size) {
|
242
|
-
if (
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
if (
|
247
|
-
state = ERROR;
|
248
|
-
errorReason = LIMIT_REACHED;
|
249
|
-
} else if (headerSize == 0) {
|
243
|
+
if (lengthStringBufferSize == sizeof(lengthStringBuffer)) {
|
244
|
+
state = ERROR;
|
245
|
+
errorReason = LENGTH_STRING_TOO_LARGE;
|
246
|
+
} else if (data[consumed] == ':') {
|
247
|
+
if (lengthStringBufferSize == 0) {
|
250
248
|
state = ERROR;
|
251
|
-
errorReason =
|
249
|
+
errorReason = INVALID_LENGTH_STRING;
|
252
250
|
} else {
|
253
|
-
|
251
|
+
consumed++;
|
252
|
+
lengthStringBuffer[lengthStringBufferSize] = '\0';
|
253
|
+
headerSize = atol(lengthStringBuffer);
|
254
|
+
if (maxSize > 0 && headerSize > maxSize) {
|
255
|
+
state = ERROR;
|
256
|
+
errorReason = LIMIT_REACHED;
|
257
|
+
} else if (headerSize == 0) {
|
258
|
+
state = ERROR;
|
259
|
+
errorReason = EMPTY_HEADER;
|
260
|
+
} else {
|
261
|
+
state = READING_HEADER_DATA;
|
262
|
+
}
|
254
263
|
}
|
255
|
-
} else if (lengthStringBufferSize >= sizeof(lengthStringBuffer) - 1) {
|
256
|
-
state = ERROR;
|
257
|
-
errorReason = LENGTH_STRING_TOO_LARGE;
|
258
264
|
} else {
|
259
265
|
state = ERROR;
|
260
266
|
errorReason = INVALID_LENGTH_STRING;
|
261
267
|
}
|
262
268
|
}
|
263
269
|
break;
|
264
|
-
|
270
|
+
|
265
271
|
case READING_HEADER_DATA: {
|
266
272
|
const char *localData = data + consumed;
|
267
273
|
size_t localSize = std::min(
|
@@ -283,7 +289,7 @@ public:
|
|
283
289
|
consumed += localSize;
|
284
290
|
break;
|
285
291
|
}
|
286
|
-
|
292
|
+
|
287
293
|
case EXPECTING_COMMA:
|
288
294
|
if (data[consumed] == ',') {
|
289
295
|
if (parseHeaderData(headerData, headers)) {
|
@@ -298,12 +304,12 @@ public:
|
|
298
304
|
errorReason = HEADER_TERMINATOR_EXPECTED;
|
299
305
|
}
|
300
306
|
break;
|
301
|
-
|
307
|
+
|
302
308
|
default:
|
303
309
|
abort(); // Never reached.
|
304
310
|
}
|
305
311
|
}
|
306
|
-
|
312
|
+
|
307
313
|
if (state == EXPECTING_COMMA && headerBuffer.empty()) {
|
308
314
|
/* We got all the header data in a single round, except
|
309
315
|
* for the closing comma. The static header data isn't
|
@@ -313,10 +319,10 @@ public:
|
|
313
319
|
headerBuffer.assign(headerData.c_str(), headerData.size());
|
314
320
|
headerData = headerBuffer;
|
315
321
|
}
|
316
|
-
|
322
|
+
|
317
323
|
return consumed;
|
318
324
|
}
|
319
|
-
|
325
|
+
|
320
326
|
/**
|
321
327
|
* Get the raw header data that has been processed so far.
|
322
328
|
* Please read the zero-copy notes in the class description for
|
@@ -330,7 +336,7 @@ public:
|
|
330
336
|
const_iterator getHeaderIterator(const StaticString &name) const {
|
331
337
|
return headers.find(name);
|
332
338
|
}
|
333
|
-
|
339
|
+
|
334
340
|
/**
|
335
341
|
* Get the value of the header with the given name.
|
336
342
|
* Lookup is case-sensitive.
|
@@ -350,7 +356,7 @@ public:
|
|
350
356
|
return it->second;
|
351
357
|
}
|
352
358
|
}
|
353
|
-
|
359
|
+
|
354
360
|
/**
|
355
361
|
* Checks whether there is a header with the given name.
|
356
362
|
* Lookup is case-sensitive.
|
@@ -364,7 +370,7 @@ public:
|
|
364
370
|
HeaderMap &getMap() {
|
365
371
|
return headers;
|
366
372
|
}
|
367
|
-
|
373
|
+
|
368
374
|
unsigned int size() const {
|
369
375
|
return headers.size();
|
370
376
|
}
|
@@ -376,14 +382,14 @@ public:
|
|
376
382
|
const_iterator end() const {
|
377
383
|
return headers.end();
|
378
384
|
}
|
379
|
-
|
385
|
+
|
380
386
|
/**
|
381
387
|
* Get the parser's current state.
|
382
388
|
*/
|
383
389
|
State getState() const {
|
384
390
|
return state;
|
385
391
|
}
|
386
|
-
|
392
|
+
|
387
393
|
/**
|
388
394
|
* Returns the reason why the parser entered the error state.
|
389
395
|
*
|
@@ -392,7 +398,7 @@ public:
|
|
392
398
|
ErrorReason getErrorReason() const {
|
393
399
|
return errorReason;
|
394
400
|
}
|
395
|
-
|
401
|
+
|
396
402
|
/**
|
397
403
|
* Checks whether this parser is still capable of accepting input (that
|
398
404
|
* is, that this parser is not in a final/error state).
|