2021-03-13 18:48:03 -06:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
|
|
/*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2021-03-14 11:24:02 -05:00
|
|
|
#include <string>
|
2021-03-13 18:48:03 -06:00
|
|
|
|
|
|
|
#include <net/HttpRequest.hpp>
|
|
|
|
|
2021-09-26 18:50:17 -05:00
|
|
|
#include <test/lokassert.hpp>
|
|
|
|
|
2021-03-13 18:48:03 -06:00
|
|
|
#include <chrono>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
#include <cppunit/extensions/HelperMacros.h>
|
|
|
|
|
|
|
|
/// HTTP WhiteBox unit-tests.
|
|
|
|
class HttpWhiteBoxTests : public CPPUNIT_NS::TestFixture
|
|
|
|
{
|
|
|
|
CPPUNIT_TEST_SUITE(HttpWhiteBoxTests);
|
|
|
|
|
2021-03-14 17:59:33 -05:00
|
|
|
CPPUNIT_TEST(testStatusLineParserValidComplete);
|
2021-07-29 00:55:31 -05:00
|
|
|
CPPUNIT_TEST(testStatusLineParserValidComplete_NoReason);
|
2021-03-14 17:59:33 -05:00
|
|
|
CPPUNIT_TEST(testStatusLineParserValidIncomplete);
|
2021-03-20 09:14:39 -05:00
|
|
|
CPPUNIT_TEST(testStatusLineSerialize);
|
2021-03-14 17:59:33 -05:00
|
|
|
|
2021-04-21 11:10:03 -05:00
|
|
|
CPPUNIT_TEST(testHeader);
|
|
|
|
|
2021-03-13 18:48:03 -06:00
|
|
|
CPPUNIT_TEST(testRequestParserValidComplete);
|
|
|
|
CPPUNIT_TEST(testRequestParserValidIncomplete);
|
|
|
|
|
|
|
|
CPPUNIT_TEST_SUITE_END();
|
|
|
|
|
2021-03-14 17:59:33 -05:00
|
|
|
void testStatusLineParserValidComplete();
|
2021-07-29 00:55:31 -05:00
|
|
|
void testStatusLineParserValidComplete_NoReason();
|
2021-03-14 17:59:33 -05:00
|
|
|
void testStatusLineParserValidIncomplete();
|
2021-03-20 09:14:39 -05:00
|
|
|
void testStatusLineSerialize();
|
2021-04-21 11:10:03 -05:00
|
|
|
void testHeader();
|
2021-03-13 18:48:03 -06:00
|
|
|
void testRequestParserValidComplete();
|
|
|
|
void testRequestParserValidIncomplete();
|
|
|
|
};
|
|
|
|
|
2021-03-14 17:59:33 -05:00
|
|
|
void HttpWhiteBoxTests::testStatusLineParserValidComplete()
|
|
|
|
{
|
2022-02-16 16:22:18 -06:00
|
|
|
constexpr auto testname = __func__;
|
|
|
|
|
2021-03-20 09:14:39 -05:00
|
|
|
const unsigned expVersionMajor = 1;
|
|
|
|
const unsigned expVersionMinor = 1;
|
2021-03-14 17:59:33 -05:00
|
|
|
const std::string expVersion
|
|
|
|
= "HTTP/" + std::to_string(expVersionMajor) + '.' + std::to_string(expVersionMinor);
|
2021-03-20 09:14:39 -05:00
|
|
|
const unsigned expStatusCode = 101;
|
2021-03-14 17:59:33 -05:00
|
|
|
const std::string expReasonPhrase = "Something Something";
|
|
|
|
const std::string data
|
|
|
|
= expVersion + ' ' + std::to_string(expStatusCode) + ' ' + expReasonPhrase + "\r\n";
|
|
|
|
|
|
|
|
http::StatusLine statusLine;
|
|
|
|
|
|
|
|
int64_t len = data.size();
|
|
|
|
LOK_ASSERT_EQUAL(http::FieldParseState::Valid, statusLine.parse(data.c_str(), len));
|
|
|
|
LOK_ASSERT_EQUAL(expVersion, statusLine.httpVersion());
|
|
|
|
LOK_ASSERT_EQUAL(expVersionMajor, statusLine.versionMajor());
|
|
|
|
LOK_ASSERT_EQUAL(expVersionMinor, statusLine.versionMinor());
|
|
|
|
LOK_ASSERT_EQUAL(expStatusCode, statusLine.statusCode());
|
|
|
|
LOK_ASSERT_EQUAL(expReasonPhrase, statusLine.reasonPhrase());
|
|
|
|
}
|
|
|
|
|
2021-07-29 00:55:31 -05:00
|
|
|
void HttpWhiteBoxTests::testStatusLineParserValidComplete_NoReason()
|
|
|
|
{
|
2022-02-16 16:22:18 -06:00
|
|
|
constexpr auto testname = __func__;
|
|
|
|
|
2021-07-29 00:55:31 -05:00
|
|
|
const unsigned expVersionMajor = 1;
|
|
|
|
const unsigned expVersionMinor = 1;
|
|
|
|
const std::string expVersion
|
|
|
|
= "HTTP/" + std::to_string(expVersionMajor) + '.' + std::to_string(expVersionMinor);
|
|
|
|
const unsigned expStatusCode = 101;
|
|
|
|
const std::string expReasonPhrase;
|
|
|
|
const std::string data
|
|
|
|
= expVersion + ' ' + std::to_string(expStatusCode) + ' ' + expReasonPhrase + "\r\n";
|
|
|
|
|
|
|
|
http::StatusLine statusLine;
|
|
|
|
|
|
|
|
int64_t len = data.size();
|
|
|
|
LOK_ASSERT_EQUAL(http::FieldParseState::Valid, statusLine.parse(data.c_str(), len));
|
|
|
|
LOK_ASSERT_EQUAL(expVersion, statusLine.httpVersion());
|
|
|
|
LOK_ASSERT_EQUAL(expVersionMajor, statusLine.versionMajor());
|
|
|
|
LOK_ASSERT_EQUAL(expVersionMinor, statusLine.versionMinor());
|
|
|
|
LOK_ASSERT_EQUAL(expStatusCode, statusLine.statusCode());
|
|
|
|
LOK_ASSERT_EQUAL(expReasonPhrase, statusLine.reasonPhrase());
|
|
|
|
}
|
|
|
|
|
2021-03-14 17:59:33 -05:00
|
|
|
void HttpWhiteBoxTests::testStatusLineParserValidIncomplete()
|
|
|
|
{
|
2022-02-16 16:22:18 -06:00
|
|
|
constexpr auto testname = __func__;
|
|
|
|
|
2021-03-20 09:14:39 -05:00
|
|
|
const unsigned expVersionMajor = 1;
|
|
|
|
const unsigned expVersionMinor = 1;
|
2021-03-14 17:59:33 -05:00
|
|
|
const std::string expVersion
|
|
|
|
= "HTTP/" + std::to_string(expVersionMajor) + '.' + std::to_string(expVersionMinor);
|
2021-03-20 09:14:39 -05:00
|
|
|
const unsigned expStatusCode = 101;
|
2021-03-14 17:59:33 -05:00
|
|
|
const std::string expReasonPhrase = "Something Something";
|
|
|
|
const std::string data
|
2021-07-29 00:55:31 -05:00
|
|
|
= expVersion + ' ' + std::to_string(expStatusCode) + " " + expReasonPhrase + "\r\n";
|
2021-03-14 17:59:33 -05:00
|
|
|
|
|
|
|
http::StatusLine statusLine;
|
|
|
|
|
|
|
|
// Pass incomplete data to the reader.
|
|
|
|
for (std::size_t i = 0; i < data.size(); ++i)
|
|
|
|
{
|
|
|
|
// Should return 0 to signify data is incomplete.
|
|
|
|
int64_t len = i;
|
|
|
|
LOK_ASSERT_EQUAL_MESSAGE("i = " + std::to_string(i), http::FieldParseState::Incomplete,
|
|
|
|
statusLine.parse(data.c_str(), len));
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t len = data.size();
|
|
|
|
LOK_ASSERT_EQUAL(http::FieldParseState::Valid, statusLine.parse(data.c_str(), len));
|
|
|
|
LOK_ASSERT_EQUAL(expVersion, statusLine.httpVersion());
|
|
|
|
LOK_ASSERT_EQUAL(expVersionMajor, statusLine.versionMajor());
|
|
|
|
LOK_ASSERT_EQUAL(expVersionMinor, statusLine.versionMinor());
|
|
|
|
LOK_ASSERT_EQUAL(expStatusCode, statusLine.statusCode());
|
|
|
|
LOK_ASSERT_EQUAL(expReasonPhrase, statusLine.reasonPhrase());
|
|
|
|
}
|
|
|
|
|
2021-03-20 09:14:39 -05:00
|
|
|
void HttpWhiteBoxTests::testStatusLineSerialize()
|
|
|
|
{
|
2022-02-16 16:22:18 -06:00
|
|
|
constexpr auto testname = __func__;
|
|
|
|
|
2021-03-20 09:14:39 -05:00
|
|
|
http::StatusLine statusLine(200);
|
|
|
|
Buffer buf;
|
|
|
|
statusLine.writeData(buf);
|
|
|
|
const std::string out(buf.getBlock(), buf.getBlockSize());
|
|
|
|
LOK_ASSERT_EQUAL(std::string("HTTP/1.1 200 OK\r\n"), out);
|
|
|
|
}
|
|
|
|
|
2021-04-21 11:10:03 -05:00
|
|
|
void HttpWhiteBoxTests::testHeader()
|
|
|
|
{
|
2022-02-16 16:22:18 -06:00
|
|
|
constexpr auto testname = __func__;
|
|
|
|
|
2021-04-21 11:10:03 -05:00
|
|
|
http::Header header;
|
|
|
|
|
|
|
|
const std::string data = "\r\na=\r\n\r\n";
|
|
|
|
LOK_ASSERT_EQUAL(8L, header.parse(data.c_str(), data.size()));
|
|
|
|
}
|
|
|
|
|
2021-03-13 18:48:03 -06:00
|
|
|
void HttpWhiteBoxTests::testRequestParserValidComplete()
|
|
|
|
{
|
2022-02-16 16:22:18 -06:00
|
|
|
constexpr auto testname = __func__;
|
|
|
|
|
2021-03-13 18:48:03 -06:00
|
|
|
const std::string expVerb = "GET";
|
|
|
|
const std::string expUrl = "/path/to/data";
|
|
|
|
const std::string expVersion = "HTTP/1.1";
|
2021-04-21 11:10:03 -05:00
|
|
|
const std::string data = expVerb + ' ' + expUrl + ' ' + expVersion + "\r\n" + "EmptyKey:\r\n"
|
|
|
|
+ "Host: localhost.com\r\n\r\n";
|
2021-03-13 18:48:03 -06:00
|
|
|
|
|
|
|
http::Request req;
|
|
|
|
|
|
|
|
LOK_ASSERT(req.readData(data.c_str(), data.size()) > 0);
|
|
|
|
LOK_ASSERT_EQUAL(expVerb, req.getVerb());
|
|
|
|
LOK_ASSERT_EQUAL(expUrl, req.getUrl());
|
|
|
|
LOK_ASSERT_EQUAL(expVersion, req.getVersion());
|
2021-04-21 11:10:03 -05:00
|
|
|
LOK_ASSERT_EQUAL(std::string(), req.get("emptykey"));
|
|
|
|
LOK_ASSERT_EQUAL(std::string("localhost.com"), req.get("Host"));
|
2021-03-13 18:48:03 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void HttpWhiteBoxTests::testRequestParserValidIncomplete()
|
|
|
|
{
|
2022-02-16 16:22:18 -06:00
|
|
|
constexpr auto testname = __func__;
|
|
|
|
|
2021-03-13 18:48:03 -06:00
|
|
|
const std::string expVerb = "GET";
|
2021-03-15 20:23:05 -05:00
|
|
|
const std::string expUrl = "/long/path/to/data";
|
2021-03-13 18:48:03 -06:00
|
|
|
const std::string expVersion = "HTTP/1.1";
|
2021-03-15 20:23:05 -05:00
|
|
|
const std::string expHost = "localhost.com";
|
2021-03-14 11:24:02 -05:00
|
|
|
const std::string data
|
2021-03-15 20:23:05 -05:00
|
|
|
= expVerb + ' ' + expUrl + ' ' + expVersion + "\r\n" + "Host: " + expHost + "\r\n\r\n";
|
2021-03-13 18:48:03 -06:00
|
|
|
|
|
|
|
http::Request req;
|
|
|
|
|
|
|
|
// Pass incomplete data to the reader.
|
2021-03-15 20:23:05 -05:00
|
|
|
for (std::size_t i = 0; i < 33; ++i)
|
2021-03-13 18:48:03 -06:00
|
|
|
{
|
2021-03-15 20:23:05 -05:00
|
|
|
// Should return 0 to signify that data is incomplete.
|
|
|
|
LOK_ASSERT_EQUAL_MESSAGE("i = " << i << " of " << data.size() - 1, 0L,
|
|
|
|
req.readData(data.c_str(), i));
|
2021-03-13 18:48:03 -06:00
|
|
|
}
|
|
|
|
|
2021-03-15 20:23:05 -05:00
|
|
|
// Offset of the end of first line.
|
|
|
|
const int64_t off = 33;
|
|
|
|
|
|
|
|
// Parse the first line.
|
|
|
|
LOK_ASSERT_EQUAL_MESSAGE("Parsing the first line failed.", off,
|
|
|
|
req.readData(data.c_str(), off));
|
|
|
|
|
|
|
|
// Skip the first line and parse the header.
|
|
|
|
for (std::size_t i = off; i < data.size(); ++i)
|
|
|
|
{
|
|
|
|
// Should return 0 to signify that data is incomplete.
|
|
|
|
LOK_ASSERT_EQUAL_MESSAGE("i = " << i << " of " << data.size() - 1, 0L,
|
|
|
|
req.readData(data.c_str() + off, i - off));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the header.
|
|
|
|
LOK_ASSERT_EQUAL_MESSAGE("Parsing the header failed.",
|
|
|
|
static_cast<int64_t>(expHost.size() + 10),
|
|
|
|
req.readData(data.c_str() + off, data.size() - off));
|
|
|
|
|
2021-03-13 18:48:03 -06:00
|
|
|
LOK_ASSERT_EQUAL(expVerb, req.getVerb());
|
|
|
|
LOK_ASSERT_EQUAL(expUrl, req.getUrl());
|
|
|
|
LOK_ASSERT_EQUAL(expVersion, req.getVersion());
|
2021-03-15 20:23:05 -05:00
|
|
|
LOK_ASSERT_EQUAL(expHost, req.header().get("Host"));
|
2021-03-13 18:48:03 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
CPPUNIT_TEST_SUITE_REGISTRATION(HttpWhiteBoxTests);
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|