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
@@ -13,39 +13,39 @@ namespace tut {
|
|
13
13
|
SocketPair adminSocket;
|
14
14
|
Pipe errorPipe;
|
15
15
|
FileDescriptor server1, server2, server3;
|
16
|
-
|
16
|
+
|
17
17
|
ApplicationPool2_ProcessTest() {
|
18
18
|
bg.start();
|
19
|
-
|
19
|
+
|
20
20
|
struct sockaddr_in addr;
|
21
21
|
socklen_t len = sizeof(addr);
|
22
22
|
sockets = boost::make_shared<SocketList>();
|
23
|
-
|
23
|
+
|
24
24
|
server1 = createTcpServer("127.0.0.1", 0);
|
25
25
|
getsockname(server1, (struct sockaddr *) &addr, &len);
|
26
26
|
sockets->add("main1",
|
27
27
|
"tcp://127.0.0.1:" + toString(addr.sin_port),
|
28
28
|
"session", 3);
|
29
|
-
|
29
|
+
|
30
30
|
server2 = createTcpServer("127.0.0.1", 0);
|
31
31
|
getsockname(server2, (struct sockaddr *) &addr, &len);
|
32
32
|
sockets->add("main2",
|
33
33
|
"tcp://127.0.0.1:" + toString(addr.sin_port),
|
34
34
|
"session", 3);
|
35
|
-
|
35
|
+
|
36
36
|
server3 = createTcpServer("127.0.0.1", 0);
|
37
37
|
getsockname(server3, (struct sockaddr *) &addr, &len);
|
38
38
|
sockets->add("main3",
|
39
39
|
"tcp://127.0.0.1:" + toString(addr.sin_port),
|
40
40
|
"session", 3);
|
41
|
-
|
41
|
+
|
42
42
|
adminSocket = createUnixSocketPair();
|
43
43
|
errorPipe = createPipe();
|
44
44
|
}
|
45
45
|
};
|
46
|
-
|
46
|
+
|
47
47
|
DEFINE_TEST_GROUP(ApplicationPool2_ProcessTest);
|
48
|
-
|
48
|
+
|
49
49
|
TEST_METHOD(1) {
|
50
50
|
// Test initial state.
|
51
51
|
ProcessPtr process = boost::make_shared<Process>(
|
@@ -56,7 +56,7 @@ namespace tut {
|
|
56
56
|
ensure_equals(process->busyness(), 0);
|
57
57
|
ensure(!process->isTotallyBusy());
|
58
58
|
}
|
59
|
-
|
59
|
+
|
60
60
|
TEST_METHOD(2) {
|
61
61
|
// Test opening and closing sessions.
|
62
62
|
ProcessPtr process = boost::make_shared<Process>(
|
@@ -72,7 +72,7 @@ namespace tut {
|
|
72
72
|
process->sessionClosed(session2.get());
|
73
73
|
ensure_equals(process->sessions, 0);
|
74
74
|
}
|
75
|
-
|
75
|
+
|
76
76
|
TEST_METHOD(3) {
|
77
77
|
// newSession() checks out the socket with the smallest busyness number
|
78
78
|
// and sessionClosed() restores the session busyness statistics.
|
@@ -81,7 +81,7 @@ namespace tut {
|
|
81
81
|
errorPipe[0], sockets, 0, 0);
|
82
82
|
process->dummy = true;
|
83
83
|
process->requiresShutdown = false;
|
84
|
-
|
84
|
+
|
85
85
|
// The first 3 newSession() commands check out an idle socket.
|
86
86
|
SessionPtr session1 = process->newSession();
|
87
87
|
SessionPtr session2 = process->newSession();
|
@@ -89,12 +89,12 @@ namespace tut {
|
|
89
89
|
ensure(session1->getSocket()->name != session2->getSocket()->name);
|
90
90
|
ensure(session1->getSocket()->name != session3->getSocket()->name);
|
91
91
|
ensure(session2->getSocket()->name != session3->getSocket()->name);
|
92
|
-
|
92
|
+
|
93
93
|
// The next 2 newSession() commands check out sockets with sessions == 1.
|
94
94
|
SessionPtr session4 = process->newSession();
|
95
95
|
SessionPtr session5 = process->newSession();
|
96
96
|
ensure(session4->getSocket()->name != session5->getSocket()->name);
|
97
|
-
|
97
|
+
|
98
98
|
// There should now be 1 process with 1 session
|
99
99
|
// and 2 processes with 2 sessions.
|
100
100
|
map<int, int> sessionCount;
|
@@ -105,7 +105,7 @@ namespace tut {
|
|
105
105
|
ensure_equals(sessionCount.size(), 2u);
|
106
106
|
ensure_equals(sessionCount[1], 1);
|
107
107
|
ensure_equals(sessionCount[2], 2);
|
108
|
-
|
108
|
+
|
109
109
|
// Closing the first 3 sessions will result in no processes having 1 session
|
110
110
|
// and 1 process having 2 sessions.
|
111
111
|
process->sessionClosed(session1.get());
|
@@ -118,7 +118,7 @@ namespace tut {
|
|
118
118
|
ensure_equals(sessionCount[0], 1);
|
119
119
|
ensure_equals(sessionCount[1], 2);
|
120
120
|
}
|
121
|
-
|
121
|
+
|
122
122
|
TEST_METHOD(4) {
|
123
123
|
// If all sockets are at their full capacity then newSession() will fail.
|
124
124
|
ProcessPtr process = boost::make_shared<Process>(
|
@@ -19,7 +19,7 @@ namespace tut {
|
|
19
19
|
PipeWatcher::DataCallback gatherOutput;
|
20
20
|
string gatheredOutput;
|
21
21
|
boost::mutex gatheredOutputSyncher;
|
22
|
-
|
22
|
+
|
23
23
|
ApplicationPool2_SmartSpawnerTest() {
|
24
24
|
createServerInstanceDirAndGeneration(serverInstanceDir, generation);
|
25
25
|
PipeWatcher::onData = PipeWatcher::DataCallback();
|
@@ -27,32 +27,32 @@ namespace tut {
|
|
27
27
|
setLogLevel(LVL_ERROR); // TODO: should be LVL_WARN
|
28
28
|
setPrintAppOutputAsDebuggingMessages(true);
|
29
29
|
}
|
30
|
-
|
30
|
+
|
31
31
|
~ApplicationPool2_SmartSpawnerTest() {
|
32
32
|
setLogLevel(DEFAULT_LOG_LEVEL);
|
33
33
|
setPrintAppOutputAsDebuggingMessages(false);
|
34
34
|
unlink("stub/wsgi/passenger_wsgi.pyc");
|
35
35
|
PipeWatcher::onData = PipeWatcher::DataCallback();
|
36
36
|
}
|
37
|
-
|
37
|
+
|
38
38
|
boost::shared_ptr<SmartSpawner> createSpawner(const Options &options, bool exitImmediately = false) {
|
39
39
|
char buf[PATH_MAX + 1];
|
40
40
|
getcwd(buf, PATH_MAX);
|
41
|
-
|
41
|
+
|
42
42
|
vector<string> command;
|
43
43
|
command.push_back("ruby");
|
44
44
|
command.push_back(string(buf) + "/support/placebo-preloader.rb");
|
45
45
|
if (exitImmediately) {
|
46
46
|
command.push_back("exit-immediately");
|
47
47
|
}
|
48
|
-
|
48
|
+
|
49
49
|
return boost::make_shared<SmartSpawner>(
|
50
50
|
generation,
|
51
51
|
command,
|
52
52
|
options,
|
53
53
|
make_shared<SpawnerConfig>(*resourceLocator));
|
54
54
|
}
|
55
|
-
|
55
|
+
|
56
56
|
Options createOptions() {
|
57
57
|
Options options;
|
58
58
|
options.spawnMethod = "smart";
|
@@ -65,11 +65,11 @@ namespace tut {
|
|
65
65
|
gatheredOutput.append(data, size);
|
66
66
|
}
|
67
67
|
};
|
68
|
-
|
68
|
+
|
69
69
|
DEFINE_TEST_GROUP_WITH_LIMIT(ApplicationPool2_SmartSpawnerTest, 90);
|
70
|
-
|
70
|
+
|
71
71
|
#include "SpawnerTestCases.cpp"
|
72
|
-
|
72
|
+
|
73
73
|
TEST_METHOD(80) {
|
74
74
|
// If the preloader has crashed then SmartSpawner will
|
75
75
|
// restart it and try again.
|
@@ -81,16 +81,16 @@ namespace tut {
|
|
81
81
|
setLogLevel(LVL_CRIT);
|
82
82
|
process = spawner->spawn(options);
|
83
83
|
process->requiresShutdown = false;
|
84
|
-
|
84
|
+
|
85
85
|
kill(spawner->getPreloaderPid(), SIGTERM);
|
86
86
|
// Give it some time to exit.
|
87
87
|
usleep(300000);
|
88
|
-
|
88
|
+
|
89
89
|
// No exception at next spawn.
|
90
90
|
process = spawner->spawn(options);
|
91
91
|
process->requiresShutdown = false;
|
92
92
|
}
|
93
|
-
|
93
|
+
|
94
94
|
TEST_METHOD(81) {
|
95
95
|
// If the preloader still crashes after the restart then
|
96
96
|
// SmartSpawner will throw an exception.
|
@@ -108,7 +108,7 @@ namespace tut {
|
|
108
108
|
// Pass.
|
109
109
|
}
|
110
110
|
}
|
111
|
-
|
111
|
+
|
112
112
|
TEST_METHOD(82) {
|
113
113
|
// If the preloader didn't start within the timeout
|
114
114
|
// then it's killed and an exception is thrown, with
|
@@ -118,7 +118,7 @@ namespace tut {
|
|
118
118
|
options.startCommand = "ruby\t" "start.rb";
|
119
119
|
options.startupFile = "start.rb";
|
120
120
|
options.startTimeout = 300;
|
121
|
-
|
121
|
+
|
122
122
|
vector<string> preloaderCommand;
|
123
123
|
preloaderCommand.push_back("bash");
|
124
124
|
preloaderCommand.push_back("-c");
|
@@ -129,7 +129,7 @@ namespace tut {
|
|
129
129
|
options,
|
130
130
|
make_shared<SpawnerConfig>(*resourceLocator));
|
131
131
|
setLogLevel(LVL_CRIT);
|
132
|
-
|
132
|
+
|
133
133
|
try {
|
134
134
|
process = spawner.spawn(options);
|
135
135
|
process->requiresShutdown = false;
|
@@ -140,7 +140,7 @@ namespace tut {
|
|
140
140
|
ensure(e.getErrorPage().find("hello world\n") != string::npos);
|
141
141
|
}
|
142
142
|
}
|
143
|
-
|
143
|
+
|
144
144
|
TEST_METHOD(83) {
|
145
145
|
// If the preloader crashed during startup without returning
|
146
146
|
// a proper error response, then its stderr output is used
|
@@ -149,7 +149,7 @@ namespace tut {
|
|
149
149
|
options.appRoot = "stub/rack";
|
150
150
|
options.startCommand = "ruby\t" "start.rb";
|
151
151
|
options.startupFile = "start.rb";
|
152
|
-
|
152
|
+
|
153
153
|
vector<string> preloaderCommand;
|
154
154
|
preloaderCommand.push_back("bash");
|
155
155
|
preloaderCommand.push_back("-c");
|
@@ -180,7 +180,7 @@ namespace tut {
|
|
180
180
|
options.startCommand = "ruby\t" "start.rb";
|
181
181
|
options.startupFile = "start.rb";
|
182
182
|
options.environmentVariables.push_back(make_pair("PASSENGER_FOO", "foo"));
|
183
|
-
|
183
|
+
|
184
184
|
vector<string> preloaderCommand;
|
185
185
|
preloaderCommand.push_back("bash");
|
186
186
|
preloaderCommand.push_back("-c");
|
@@ -191,7 +191,7 @@ namespace tut {
|
|
191
191
|
options,
|
192
192
|
make_shared<SpawnerConfig>(*resourceLocator));
|
193
193
|
setLogLevel(LVL_CRIT);
|
194
|
-
|
194
|
+
|
195
195
|
try {
|
196
196
|
process = spawner.spawn(options);
|
197
197
|
process->requiresShutdown = false;
|
@@ -208,7 +208,7 @@ namespace tut {
|
|
208
208
|
PipeWatcher::onData = gatherOutput;
|
209
209
|
Options options = createOptions();
|
210
210
|
options.appRoot = "stub/rack";
|
211
|
-
|
211
|
+
|
212
212
|
{
|
213
213
|
vector<string> preloaderCommand;
|
214
214
|
preloaderCommand.push_back("ruby");
|
@@ -221,10 +221,10 @@ namespace tut {
|
|
221
221
|
process = spawner.spawn(options);
|
222
222
|
process->requiresShutdown = false;
|
223
223
|
}
|
224
|
-
|
224
|
+
|
225
225
|
SessionPtr session = process->newSession();
|
226
226
|
session->initiate();
|
227
|
-
|
227
|
+
|
228
228
|
const char header[] =
|
229
229
|
"REQUEST_METHOD\0GET\0"
|
230
230
|
"PATH_INFO\0/print_stderr\0";
|
@@ -31,7 +31,7 @@
|
|
31
31
|
(void) uid; (void) gid; (void) groups
|
32
32
|
|
33
33
|
typedef boost::shared_ptr<Spawner> SpawnerPtr;
|
34
|
-
|
34
|
+
|
35
35
|
static void addUserSwitchingCode() {
|
36
36
|
FILE *f = fopen("tmp.wsgi/passenger_wsgi.py", "a");
|
37
37
|
fputs(
|
@@ -84,7 +84,7 @@
|
|
84
84
|
process = spawner->spawn(options);
|
85
85
|
process->requiresShutdown = false;
|
86
86
|
ensure_equals(process->sockets->size(), 1u);
|
87
|
-
|
87
|
+
|
88
88
|
Connection conn = process->sockets->front().checkoutConnection();
|
89
89
|
ScopeGuard guard(boost::bind(checkin, process, &conn));
|
90
90
|
writeExact(conn.fd, "ping\n");
|
@@ -181,13 +181,13 @@
|
|
181
181
|
process = spawner->spawn(options);
|
182
182
|
process->requiresShutdown = false;
|
183
183
|
ensure_equals(process->sockets->size(), 1u);
|
184
|
-
|
184
|
+
|
185
185
|
Connection conn = process->sockets->front().checkoutConnection();
|
186
186
|
ScopeGuard guard(boost::bind(checkin, process, &conn));
|
187
187
|
writeExact(conn.fd, "pid\n");
|
188
188
|
ensure_equals(readAll(conn.fd), toString(process->pid) + "\n");
|
189
189
|
}
|
190
|
-
|
190
|
+
|
191
191
|
TEST_METHOD(7) {
|
192
192
|
// Custom environment variables can be passed.
|
193
193
|
Options options = createOptions();
|
@@ -200,7 +200,7 @@
|
|
200
200
|
process = spawner->spawn(options);
|
201
201
|
process->requiresShutdown = false;
|
202
202
|
ensure_equals(process->sockets->size(), 1u);
|
203
|
-
|
203
|
+
|
204
204
|
Connection conn = process->sockets->front().checkoutConnection();
|
205
205
|
ScopeGuard guard(boost::bind(checkin, process, &conn));
|
206
206
|
writeExact(conn.fd, "envvars\n");
|
@@ -296,10 +296,10 @@
|
|
296
296
|
SpawnerPtr spawner = createSpawner(options);
|
297
297
|
process = spawner->spawn(options);
|
298
298
|
process->requiresShutdown = false;
|
299
|
-
|
299
|
+
|
300
300
|
SessionPtr session = process->newSession();
|
301
301
|
session->initiate();
|
302
|
-
|
302
|
+
|
303
303
|
setLogLevel(LVL_ERROR); // TODO: should be LVL_WARN
|
304
304
|
const char header[] =
|
305
305
|
"REQUEST_METHOD\0GET\0"
|
@@ -336,7 +336,7 @@
|
|
336
336
|
SpawnerPtr spawner = createSpawner(options);
|
337
337
|
process = spawner->spawn(options);
|
338
338
|
process->requiresShutdown = false;
|
339
|
-
|
339
|
+
|
340
340
|
ensure_equals(process->codeRevision, "hello");
|
341
341
|
}
|
342
342
|
|
@@ -354,10 +354,10 @@
|
|
354
354
|
SpawnerPtr spawner = createSpawner(options);
|
355
355
|
process = spawner->spawn(options);
|
356
356
|
process->requiresShutdown = false;
|
357
|
-
|
357
|
+
|
358
358
|
ensure_equals(process->codeRevision, "today");
|
359
359
|
}
|
360
|
-
|
360
|
+
|
361
361
|
// It raises an exception if getStartupCommand() is empty.
|
362
362
|
|
363
363
|
/******* User switching tests *******/
|
@@ -820,6 +820,6 @@
|
|
820
820
|
}
|
821
821
|
defaultGroups.erase(0, pos);
|
822
822
|
}
|
823
|
-
|
823
|
+
|
824
824
|
ensure_equals(groups, defaultGroups);
|
825
825
|
}
|
@@ -8,7 +8,7 @@ namespace tut {
|
|
8
8
|
struct ScgiRequestParserTest {
|
9
9
|
ScgiRequestParser parser;
|
10
10
|
};
|
11
|
-
|
11
|
+
|
12
12
|
DEFINE_TEST_GROUP(ScgiRequestParserTest);
|
13
13
|
|
14
14
|
TEST_METHOD(1) {
|
@@ -17,9 +17,9 @@ namespace tut {
|
|
17
17
|
ensure_equals(parser.getState(), ScgiRequestParser::READING_LENGTH_STRING);
|
18
18
|
ensure(parser.getHeaderData().empty());
|
19
19
|
}
|
20
|
-
|
20
|
+
|
21
21
|
/***** Test parsing a complete SCGI request in a single pass. *****/
|
22
|
-
|
22
|
+
|
23
23
|
TEST_METHOD(2) {
|
24
24
|
// Parsing a request with a single header and no body.
|
25
25
|
static const char data[] = "12:hello\0world\0,";
|
@@ -33,7 +33,7 @@ namespace tut {
|
|
33
33
|
string("hello\0world\0", 12));
|
34
34
|
ensure(parser.getHeader("hello") == "world");
|
35
35
|
}
|
36
|
-
|
36
|
+
|
37
37
|
TEST_METHOD(3) {
|
38
38
|
// Parsing a request with a single header and a body.
|
39
39
|
static const char data[] = "12:hello\0world\0,data";
|
@@ -47,7 +47,7 @@ namespace tut {
|
|
47
47
|
string("hello\0world\0", 12));
|
48
48
|
ensure(parser.getHeader("hello") == "world");
|
49
49
|
}
|
50
|
-
|
50
|
+
|
51
51
|
TEST_METHOD(4) {
|
52
52
|
// Parsing a request with multiple headers and no body.
|
53
53
|
static const char data[] = "19:hello\0world\0SCGI\0001\0,";
|
@@ -62,7 +62,7 @@ namespace tut {
|
|
62
62
|
ensure(parser.getHeader("hello") == "world");
|
63
63
|
ensure(parser.getHeader("SCGI") == "1");
|
64
64
|
}
|
65
|
-
|
65
|
+
|
66
66
|
TEST_METHOD(5) {
|
67
67
|
// Parsing a request with multiple headers and a body.
|
68
68
|
static const char data[] = "19:hello\0world\0SCGI\0001\0,body";
|
@@ -77,7 +77,7 @@ namespace tut {
|
|
77
77
|
ensure(parser.getHeader("hello") == "world");
|
78
78
|
ensure(parser.getHeader("SCGI") == "1");
|
79
79
|
}
|
80
|
-
|
80
|
+
|
81
81
|
TEST_METHOD(6) {
|
82
82
|
// Parsing a request that's larger than the limit.
|
83
83
|
parser = ScgiRequestParser(9);
|
@@ -87,9 +87,9 @@ namespace tut {
|
|
87
87
|
ensure_equals(parser.getErrorReason(),
|
88
88
|
ScgiRequestParser::LIMIT_REACHED);
|
89
89
|
}
|
90
|
-
|
90
|
+
|
91
91
|
/***** Test parsing a complete SCGI request in multiple passes. *****/
|
92
|
-
|
92
|
+
|
93
93
|
TEST_METHOD(8) {
|
94
94
|
// Parsing a request with multiple headers and a body.
|
95
95
|
// 1 byte per pass.
|
@@ -105,7 +105,7 @@ namespace tut {
|
|
105
105
|
ensure(parser.getHeader("hello") == "world");
|
106
106
|
ensure(parser.getHeader("foo") == "bar");
|
107
107
|
}
|
108
|
-
|
108
|
+
|
109
109
|
TEST_METHOD(9) {
|
110
110
|
// Parsing a request with multiple headers and a body.
|
111
111
|
// Half element per pass.
|
@@ -125,7 +125,7 @@ namespace tut {
|
|
125
125
|
ensure(parser.getHeader("hello") == "world");
|
126
126
|
ensure(parser.getHeader("foo") == "bar");
|
127
127
|
}
|
128
|
-
|
128
|
+
|
129
129
|
TEST_METHOD(10) {
|
130
130
|
// Parsing a request with multiple headers and a body.
|
131
131
|
// 1 element per pass.
|
@@ -142,7 +142,7 @@ namespace tut {
|
|
142
142
|
ensure(parser.getHeader("hello") == "world");
|
143
143
|
ensure(parser.getHeader("foo") == "bar");
|
144
144
|
}
|
145
|
-
|
145
|
+
|
146
146
|
TEST_METHOD(11) {
|
147
147
|
// Parsing a request with multiple headers and a body.
|
148
148
|
// 2 elements per pass.
|
@@ -157,7 +157,7 @@ namespace tut {
|
|
157
157
|
ensure(parser.getHeader("hello") == "world");
|
158
158
|
ensure(parser.getHeader("foo") == "bar");
|
159
159
|
}
|
160
|
-
|
160
|
+
|
161
161
|
TEST_METHOD(12) {
|
162
162
|
// Parsing a request with multiple headers and a body.
|
163
163
|
// Variable number of elements per pass.
|
@@ -185,9 +185,9 @@ namespace tut {
|
|
185
185
|
ensure(parser.getHeader("hello") == "world");
|
186
186
|
ensure(parser.getHeader("foo") == "bar");
|
187
187
|
}
|
188
|
-
|
188
|
+
|
189
189
|
/***** Test parsing invalid SCGI requests in one pass. *****/
|
190
|
-
|
190
|
+
|
191
191
|
TEST_METHOD(16) {
|
192
192
|
// Invalid first character for length string.
|
193
193
|
ensure_equals("Parser did not accept anything.",
|
@@ -195,56 +195,56 @@ namespace tut {
|
|
195
195
|
ensure_equals("Parser is in the error state.",
|
196
196
|
parser.getState(), ScgiRequestParser::ERROR);
|
197
197
|
}
|
198
|
-
|
198
|
+
|
199
199
|
TEST_METHOD(17) {
|
200
200
|
// Invalid character inside length string.
|
201
201
|
ensure_equals(parser.feed("12x:hello world!", 16), 2u);
|
202
202
|
ensure_equals("Parser is in the error state.",
|
203
203
|
parser.getState(), ScgiRequestParser::ERROR);
|
204
204
|
}
|
205
|
-
|
205
|
+
|
206
206
|
TEST_METHOD(18) {
|
207
207
|
// Invalid character in place of colon.
|
208
208
|
ensure_equals(parser.feed("12#hello world!", 15), 2u);
|
209
209
|
ensure_equals("Parser is in the error state.",
|
210
210
|
parser.getState(), ScgiRequestParser::ERROR);
|
211
211
|
}
|
212
|
-
|
212
|
+
|
213
213
|
TEST_METHOD(19) {
|
214
214
|
// Invalid character in place of comma.
|
215
215
|
ensure_equals(parser.feed("12:hello\0world\0!", 16), 15u);
|
216
216
|
ensure_equals("Parser is in the error state.",
|
217
217
|
parser.getState(), ScgiRequestParser::ERROR);
|
218
218
|
}
|
219
|
-
|
219
|
+
|
220
220
|
TEST_METHOD(20) {
|
221
221
|
// Only a header name, without even a null terminator.
|
222
222
|
ensure_equals(parser.feed("5:hello,", 8), (size_t) 8);
|
223
223
|
ensure_equals("Parser is in the error state.",
|
224
224
|
parser.getState(), ScgiRequestParser::ERROR);
|
225
225
|
}
|
226
|
-
|
226
|
+
|
227
227
|
TEST_METHOD(21) {
|
228
228
|
// Only a header name, with a null terminator.
|
229
229
|
ensure_equals(parser.feed("6:hello\0,", 9), (size_t) 9);
|
230
230
|
ensure_equals("Parser is in the error state.",
|
231
231
|
parser.getState(), ScgiRequestParser::ERROR);
|
232
232
|
}
|
233
|
-
|
233
|
+
|
234
234
|
TEST_METHOD(22) {
|
235
235
|
// A header name with its value not having a null terminator.
|
236
236
|
ensure_equals(parser.feed("7:foo\0bar,", 10), (size_t) 10);
|
237
237
|
ensure_equals("Parser is in the error state.",
|
238
238
|
parser.getState(), ScgiRequestParser::ERROR);
|
239
239
|
}
|
240
|
-
|
240
|
+
|
241
241
|
TEST_METHOD(23) {
|
242
242
|
// A header name without corresponding value.
|
243
243
|
ensure_equals(parser.feed("10:foo\0bar\0a\0,", 14), (size_t) 14);
|
244
244
|
ensure_equals("Parser is in the error state.",
|
245
245
|
parser.getState(), ScgiRequestParser::ERROR);
|
246
246
|
}
|
247
|
-
|
247
|
+
|
248
248
|
TEST_METHOD(24) {
|
249
249
|
// Length string is too large.
|
250
250
|
static const char data[] = "999999999999999999999";
|
@@ -252,88 +252,102 @@ namespace tut {
|
|
252
252
|
ensure_equals("Parser is in the error state.",
|
253
253
|
parser.getState(), ScgiRequestParser::ERROR);
|
254
254
|
}
|
255
|
-
|
255
|
+
|
256
256
|
TEST_METHOD(25) {
|
257
257
|
// An empty header name.
|
258
258
|
ensure_equals(parser.feed("5:\0bar\0,", 8), (size_t) 8);
|
259
259
|
ensure_equals("Parser is in the error state.",
|
260
260
|
parser.getState(), ScgiRequestParser::ERROR);
|
261
261
|
}
|
262
|
-
|
262
|
+
|
263
263
|
TEST_METHOD(26) {
|
264
264
|
// An empty header.
|
265
265
|
ensure_equals(parser.feed("0:,", 3), (size_t) 2);
|
266
266
|
ensure_equals("Parser is in the error state.",
|
267
267
|
parser.getState(), ScgiRequestParser::ERROR);
|
268
268
|
}
|
269
|
-
|
270
|
-
/***** Test parsing invalid SCGI requests in multiple passes. *****/
|
271
|
-
|
269
|
+
|
272
270
|
TEST_METHOD(27) {
|
271
|
+
// An empty length string.
|
272
|
+
ensure_equals(parser.feed(":", 1), (size_t) 0);
|
273
|
+
ensure_equals("Parser is in the error state.",
|
274
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
275
|
+
}
|
276
|
+
|
277
|
+
TEST_METHOD(28) {
|
278
|
+
// Empty header names.
|
279
|
+
ensure_equals(parser.feed("2:\0\0,", 5), (size_t) 5);
|
280
|
+
ensure_equals("Parser is in the error state.",
|
281
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
282
|
+
}
|
283
|
+
|
284
|
+
/***** Test parsing invalid SCGI requests in multiple passes. *****/
|
285
|
+
|
286
|
+
TEST_METHOD(30) {
|
273
287
|
// Once the parser has entered the error state, it stays there.
|
274
288
|
ensure_equals(parser.feed("hello world!", 12), 0u);
|
275
289
|
ensure_equals(parser.feed("1", 1), 0u);
|
276
290
|
ensure_equals("Parser is in the error state.",
|
277
291
|
parser.getState(), ScgiRequestParser::ERROR);
|
278
292
|
}
|
279
|
-
|
280
|
-
TEST_METHOD(
|
293
|
+
|
294
|
+
TEST_METHOD(31) {
|
281
295
|
// Invalid character inside length string.
|
282
296
|
ensure_equals(parser.feed("12", 2), 2u);
|
283
297
|
ensure_equals(parser.feed("x:", 2), 0u);
|
284
298
|
ensure_equals("Parser is in the error state.",
|
285
299
|
parser.getState(), ScgiRequestParser::ERROR);
|
286
300
|
}
|
287
|
-
|
288
|
-
TEST_METHOD(
|
301
|
+
|
302
|
+
TEST_METHOD(32) {
|
289
303
|
// Invalid character in place of colon.
|
290
304
|
ensure_equals(parser.feed("12", 2), 2u);
|
291
305
|
ensure_equals(parser.feed("#", 1), 0u);
|
292
306
|
ensure_equals("Parser is in the error state.",
|
293
307
|
parser.getState(), ScgiRequestParser::ERROR);
|
294
308
|
}
|
295
|
-
|
296
|
-
TEST_METHOD(
|
309
|
+
|
310
|
+
TEST_METHOD(33) {
|
297
311
|
// Invalid character in place of comma.
|
298
312
|
ensure_equals(parser.feed("12:hello\0world\0", 15), 15u);
|
299
313
|
ensure_equals(parser.feed("!", 1), 0u);
|
300
314
|
ensure_equals("Parser is in the error state.",
|
301
315
|
parser.getState(), ScgiRequestParser::ERROR);
|
302
316
|
}
|
303
|
-
|
304
|
-
TEST_METHOD(
|
317
|
+
|
318
|
+
TEST_METHOD(34) {
|
305
319
|
// Only a header name, without even a null terminator.
|
306
320
|
ensure_equals(parser.feed("5:hell", 6), (size_t) 6);
|
307
321
|
ensure_equals(parser.feed("o,", 2), (size_t) 2);
|
308
322
|
ensure_equals("Parser is in the error state.",
|
309
323
|
parser.getState(), ScgiRequestParser::ERROR);
|
310
324
|
}
|
311
|
-
|
312
|
-
TEST_METHOD(
|
325
|
+
|
326
|
+
TEST_METHOD(35) {
|
313
327
|
// Only a header name, with a null terminator.
|
314
328
|
ensure_equals(parser.feed("6:hello", 7), (size_t) 7);
|
315
329
|
ensure_equals(parser.feed("\0,", 2), (size_t) 2);
|
316
330
|
ensure_equals("Parser is in the error state.",
|
317
331
|
parser.getState(), ScgiRequestParser::ERROR);
|
318
332
|
}
|
319
|
-
|
320
|
-
TEST_METHOD(
|
333
|
+
|
334
|
+
TEST_METHOD(36) {
|
321
335
|
// A header name with its value not having a null terminator.
|
322
336
|
ensure_equals(parser.feed("7:foo\0ba", 8), (size_t) 8);
|
323
337
|
ensure_equals(parser.feed("r,", 2), (size_t) 2);
|
324
338
|
ensure_equals("Parser is in the error state.",
|
325
339
|
parser.getState(), ScgiRequestParser::ERROR);
|
326
340
|
}
|
327
|
-
|
328
|
-
TEST_METHOD(
|
341
|
+
|
342
|
+
TEST_METHOD(37) {
|
329
343
|
// A header name without corresponding value.
|
330
344
|
ensure_equals(parser.feed("10:foo\0bar\0a", 12), (size_t) 12);
|
331
345
|
ensure_equals(parser.feed("\0,", 2), (size_t) 2);
|
332
346
|
ensure_equals("Parser is in the error state.",
|
333
347
|
parser.getState(), ScgiRequestParser::ERROR);
|
334
348
|
}
|
335
|
-
|
336
|
-
TEST_METHOD(
|
349
|
+
|
350
|
+
TEST_METHOD(38) {
|
337
351
|
// Length string is too large.
|
338
352
|
static const char data[] = "999999999999999999999";
|
339
353
|
ensure_equals(parser.feed("99", 2), 2u);
|
@@ -341,8 +355,8 @@ namespace tut {
|
|
341
355
|
ensure_equals("Parser is in the error state.",
|
342
356
|
parser.getState(), ScgiRequestParser::ERROR);
|
343
357
|
}
|
344
|
-
|
345
|
-
TEST_METHOD(
|
358
|
+
|
359
|
+
TEST_METHOD(39) {
|
346
360
|
// Parsing a request that's larger than the limit.
|
347
361
|
parser = ScgiRequestParser(9);
|
348
362
|
parser.feed("1", 1);
|
@@ -353,54 +367,54 @@ namespace tut {
|
|
353
367
|
ensure_equals(parser.getErrorReason(),
|
354
368
|
ScgiRequestParser::LIMIT_REACHED);
|
355
369
|
}
|
356
|
-
|
357
|
-
TEST_METHOD(
|
370
|
+
|
371
|
+
TEST_METHOD(40) {
|
358
372
|
// An empty header name.
|
359
373
|
ensure_equals(parser.feed("5:\0", 3), (size_t) 3);
|
360
374
|
ensure_equals(parser.feed("bar\0,", 5), (size_t) 5);
|
361
375
|
ensure_equals("Parser is in the error state.",
|
362
376
|
parser.getState(), ScgiRequestParser::ERROR);
|
363
377
|
}
|
364
|
-
|
378
|
+
|
365
379
|
/***** Test parsing incomplete SCGI requests. *****/
|
366
|
-
|
367
|
-
TEST_METHOD(
|
380
|
+
|
381
|
+
TEST_METHOD(45) {
|
368
382
|
// Incomplete length string.
|
369
383
|
ensure_equals(parser.feed("2", 1), 1u);
|
370
384
|
ensure_equals("Parser is still waiting for length string input.",
|
371
385
|
parser.getState(), ScgiRequestParser::READING_LENGTH_STRING);
|
372
386
|
}
|
373
|
-
|
374
|
-
TEST_METHOD(
|
387
|
+
|
388
|
+
TEST_METHOD(46) {
|
375
389
|
// Incomplete header.
|
376
390
|
ensure_equals(parser.feed("21:", 3), 3u);
|
377
391
|
ensure_equals("Parser is waiting for header data input.",
|
378
392
|
parser.getState(), ScgiRequestParser::READING_HEADER_DATA);
|
379
393
|
}
|
380
|
-
|
381
|
-
TEST_METHOD(
|
394
|
+
|
395
|
+
TEST_METHOD(47) {
|
382
396
|
// Incomplete header.
|
383
397
|
ensure_equals(parser.feed("20:hel", 6), 6u);
|
384
398
|
ensure_equals("Parser is waiting for header data input.",
|
385
399
|
parser.getState(), ScgiRequestParser::READING_HEADER_DATA);
|
386
400
|
}
|
387
|
-
|
388
|
-
TEST_METHOD(
|
401
|
+
|
402
|
+
TEST_METHOD(48) {
|
389
403
|
// Complete header but no comma.
|
390
404
|
ensure_equals(parser.feed("8:foo\0bar\0", 10), 10u);
|
391
405
|
ensure_equals("Parser is waiting for comma.",
|
392
406
|
parser.getState(), ScgiRequestParser::EXPECTING_COMMA);
|
393
407
|
}
|
394
|
-
|
395
|
-
TEST_METHOD(
|
408
|
+
|
409
|
+
TEST_METHOD(49) {
|
396
410
|
// Parsing a request that's smaller than the limit.
|
397
411
|
static const char data[] = "10:";
|
398
|
-
|
412
|
+
|
399
413
|
parser = ScgiRequestParser(11);
|
400
414
|
parser.feed(data, sizeof(data) - 1);
|
401
415
|
ensure_equals("It accepted the data (9)",
|
402
416
|
parser.getState(), ScgiRequestParser::READING_HEADER_DATA);
|
403
|
-
|
417
|
+
|
404
418
|
parser = ScgiRequestParser(10);
|
405
419
|
parser.feed(data, sizeof(data) - 1);
|
406
420
|
ensure_equals("It accepted the data (10)",
|