summaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2023-01-11 15:27:23 +0100
committerRoland Reichwein <mail@reichwein.it>2023-01-11 15:27:23 +0100
commite679b0241662ea7c1910b9fc02ed0cb8f59b0de6 (patch)
tree3ee941465c80f9331de48cb3230515fb27460305 /tests
parent478e9f340fe303f3171f4184f494947bf39e3dbf (diff)
Test CGI
Diffstat (limited to 'tests')
-rw-r--r--tests/test-webserver.cpp165
1 files changed, 161 insertions, 4 deletions
diff --git a/tests/test-webserver.cpp b/tests/test-webserver.cpp
index 602eb77..f23b8cd 100644
--- a/tests/test-webserver.cpp
+++ b/tests/test-webserver.cpp
@@ -399,10 +399,17 @@ std::pair<std::string,std::string> HTTPS(const std::string& target, bool ipv6 =
class Fixture
{
public:
- Fixture(){}
+ Fixture()
+ {
+ std::error_code ec;
+ fs::remove_all("testdir", ec);
+ fs::create_directory("testdir");
+ }
~Fixture()
{
- fs::remove("stats.db");
+ std::error_code ec;
+ fs::remove("stats.db", ec);
+ fs::remove_all("testdir", ec);
}
};
@@ -443,14 +450,15 @@ class WebsocketServerProcess
{
// shared data between Unix processes
struct shared_data_t {
- std::mutex mutex;
- char subprotocol[1024]{};
+ std::mutex mutex; // for synchronization between processes (!)
+ char subprotocol[1024]{}; // instead of std::string since std::string allocates data on heap
char target[1024]{};
};
public:
WebsocketServerProcess()
{
+ // RAII pattern for shared memory allocation/deallocation
m_shared = std::unique_ptr<shared_data_t, std::function<void(shared_data_t*)>>(
(shared_data_t*)mmap(NULL, sizeof(shared_data_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0),
[this](shared_data_t*){munmap(m_shared.get(), sizeof(shared_data_t));});
@@ -893,3 +901,152 @@ BOOST_FIXTURE_TEST_CASE(websocket_subprotocol, Fixture)
BOOST_REQUIRE(serverProcess.is_running());
}
+BOOST_FIXTURE_TEST_CASE(plugin_cgi, Fixture)
+{
+ std::string webserver_config{R"CONFIG(<webserver>
+ <user>www-data</user>
+ <group>www-data</group>
+ <threads>10</threads>
+ <statisticspath>stats.db</statisticspath>
+ <plugin-directory>../plugins</plugin-directory>
+ <sites>
+ <site>
+ <name>localhost</name>
+ <host>localhost</host>
+ <host>[::1]</host>
+ <path requested="/cgi-test">
+ <plugin>cgi</plugin>
+ <target>testdir</target>
+ </path>
+ </site>
+ </sites>
+ <sockets>
+ <socket>
+ <address>::1</address>
+ <port>8080</port>
+ <protocol>http</protocol>
+ <site>localhost</site>
+ </socket>
+ </sockets>
+</webserver>
+)CONFIG"};
+ WebserverProcess serverProcess{webserver_config};
+ BOOST_REQUIRE(serverProcess.is_running());
+
+ File::setFile("testdir/test1.sh", R"(#!/bin/bash
+
+echo -ne "Content-Type: text/plain\r\n"
+echo -ne "\r\n"
+echo -ne "Test 1:\r\n"
+echo -ne "HTTP_CONNECTION: $HTTP_CONNECTION\r\n"
+echo -ne "HTTP_HOST: $HTTP_HOST\r\n"
+echo -ne "HTTP_USER_AGENT: $HTTP_USER_AGENT\r\n"
+echo -ne "SERVER_PORT: $SERVER_PORT\r\n"
+echo -ne "QUERY_STRING: $QUERY_STRING\r\n"
+echo -ne "SCRIPT_NAME: $SCRIPT_NAME\r\n"
+echo -ne "PATH_INFO: $PATH_INFO\r\n"
+echo -ne "REQUEST_METHOD: $REQUEST_METHOD\r\n"
+echo -ne "SERVER_NAME: $SERVER_NAME\r\n"
+echo -ne "HTTP_HOST: $HTTP_HOST\r\n"
+)");
+
+ fs::permissions("testdir/test1.sh", fs::perms::owner_all | fs::perms::group_all, fs::perm_options::add);
+
+ auto result {HTTP("/cgi-test/test1.sh/path1?q=2")};
+
+ BOOST_CHECK_EQUAL(result.first, fmt::format(
+"HTTP/1.1 200 OK\r\n"
+"Server: Reichwein.IT Webserver {}\r\n"
+"Content-Type: text/plain\r\n"
+"Content-Length: {}\r\n"
+"\r\n"
+ , VERSION, result.second.size()));
+ BOOST_CHECK_EQUAL(result.second,
+"Test 1:\r\n"
+"HTTP_CONNECTION: \r\n"
+"HTTP_HOST: [::1]\r\n"
+"HTTP_USER_AGENT: Webserver Testsuite\r\n"
+"SERVER_PORT: 8080\r\n"
+"QUERY_STRING: q=2\r\n"
+"SCRIPT_NAME: /cgi-test/test1.sh\r\n"
+"PATH_INFO: /path1\r\n"
+"REQUEST_METHOD: GET\r\n"
+"SERVER_NAME: [::1]\r\n"
+"HTTP_HOST: [::1]\r\n"
+ );
+}
+
+BOOST_FIXTURE_TEST_CASE(plugin_cgi_missing_exe, Fixture)
+{
+ std::string webserver_config{R"CONFIG(<webserver>
+ <user>www-data</user>
+ <group>www-data</group>
+ <threads>10</threads>
+ <statisticspath>stats.db</statisticspath>
+ <plugin-directory>../plugins</plugin-directory>
+ <sites>
+ <site>
+ <name>localhost</name>
+ <host>localhost</host>
+ <host>[::1]</host>
+ <path requested="/cgi-test">
+ <plugin>cgi</plugin>
+ <target>testdir</target>
+ </path>
+ </site>
+ </sites>
+ <sockets>
+ <socket>
+ <address>::1</address>
+ <port>8080</port>
+ <protocol>http</protocol>
+ <site>localhost</site>
+ </socket>
+ </sockets>
+</webserver>
+)CONFIG"};
+ WebserverProcess serverProcess{webserver_config};
+ BOOST_REQUIRE(serverProcess.is_running());
+
+ File::setFile("testdir/test1.sh", R"(#!/bin/bash
+
+echo -ne "Content-Type: text/plain\r\n"
+echo -ne "\r\n"
+echo -ne "Test 1:\r\n"
+echo -ne "HTTP_CONNECTION: $HTTP_CONNECTION\r\n"
+echo -ne "HTTP_HOST: $HTTP_HOST\r\n"
+echo -ne "HTTP_USER_AGENT: $HTTP_USER_AGENT\r\n"
+echo -ne "SERVER_PORT: $SERVER_PORT\r\n"
+echo -ne "QUERY_STRING: $QUERY_STRING\r\n"
+echo -ne "SCRIPT_NAME: $SCRIPT_NAME\r\n"
+echo -ne "PATH_INFO: $PATH_INFO\r\n"
+echo -ne "REQUEST_METHOD: $REQUEST_METHOD\r\n"
+echo -ne "SERVER_NAME: $SERVER_NAME\r\n"
+echo -ne "HTTP_HOST: $HTTP_HOST\r\n"
+)");
+
+ fs::permissions("testdir/test1.sh", fs::perms::owner_all | fs::perms::group_all, fs::perm_options::add);
+
+ auto result {HTTP("/cgi-test/test2.sh")};
+
+ BOOST_CHECK_EQUAL(result.first, fmt::format(
+"HTTP/1.1 500 Internal Server Error\r\n"
+"Server: Reichwein.IT Webserver {}\r\n"
+"Content-Type: text/plain\r\n"
+"Content-Length: {}\r\n"
+"\r\n"
+ , VERSION, result.second.size()));
+ BOOST_CHECK_EQUAL(result.second, "500 Bad Script: test2.sh");
+
+ result = HTTP("/cgi-test/test2.sh/path1?q=2");
+
+ BOOST_CHECK_EQUAL(result.first, fmt::format(
+"HTTP/1.1 500 Internal Server Error\r\n"
+"Server: Reichwein.IT Webserver {}\r\n"
+"Content-Type: text/plain\r\n"
+"Content-Length: {}\r\n"
+"\r\n"
+ , VERSION, result.second.size()));
+ BOOST_CHECK_EQUAL(result.second, "500 Bad Script: test2.sh/path1");
+}
+