d4b27f6643
We use our own status codes, which are type-safe and use streaming operators to serialize and log. Change-Id: I0eba7b16694866b5a79476a7ef4b1b78f7f9c176 Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
227 lines
7.9 KiB
C++
227 lines
7.9 KiB
C++
/* -*- 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>
|
|
|
|
#include <string>
|
|
|
|
#include <net/HttpRequest.hpp>
|
|
|
|
#include <test/lokassert.hpp>
|
|
|
|
#include <chrono>
|
|
#include <fstream>
|
|
|
|
#include <cppunit/extensions/HelperMacros.h>
|
|
|
|
/// HTTP WhiteBox unit-tests.
|
|
class HttpWhiteBoxTests : public CPPUNIT_NS::TestFixture
|
|
{
|
|
CPPUNIT_TEST_SUITE(HttpWhiteBoxTests);
|
|
|
|
CPPUNIT_TEST(testStatusLineParserValidComplete);
|
|
CPPUNIT_TEST(testStatusLineParserValidComplete_NoReason);
|
|
CPPUNIT_TEST(testStatusLineParserValidIncomplete);
|
|
CPPUNIT_TEST(testStatusLineSerialize);
|
|
|
|
CPPUNIT_TEST(testHeader);
|
|
|
|
CPPUNIT_TEST(testRequestParserValidComplete);
|
|
CPPUNIT_TEST(testRequestParserValidIncomplete);
|
|
|
|
CPPUNIT_TEST_SUITE_END();
|
|
|
|
void testStatusLineParserValidComplete();
|
|
void testStatusLineParserValidComplete_NoReason();
|
|
void testStatusLineParserValidIncomplete();
|
|
void testStatusLineSerialize();
|
|
void testHeader();
|
|
void testRequestParserValidComplete();
|
|
void testRequestParserValidIncomplete();
|
|
};
|
|
|
|
void HttpWhiteBoxTests::testStatusLineParserValidComplete()
|
|
{
|
|
constexpr auto testname = __func__;
|
|
|
|
const unsigned expVersionMajor = 1;
|
|
const unsigned expVersionMinor = 1;
|
|
const std::string expVersion
|
|
= "HTTP/" + std::to_string(expVersionMajor) + '.' + std::to_string(expVersionMinor);
|
|
const http::StatusCode expStatusCode = http::StatusCode::SwitchingProtocols;
|
|
const std::string expReasonPhrase = "Something Something";
|
|
|
|
std::ostringstream oss;
|
|
oss << expVersion << ' ' << static_cast<unsigned>(expStatusCode) << ' ' << expReasonPhrase
|
|
<< "\r\n";
|
|
const std::string data = oss.str();
|
|
|
|
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());
|
|
}
|
|
|
|
void HttpWhiteBoxTests::testStatusLineParserValidComplete_NoReason()
|
|
{
|
|
constexpr auto testname = __func__;
|
|
|
|
const unsigned expVersionMajor = 1;
|
|
const unsigned expVersionMinor = 1;
|
|
const std::string expVersion
|
|
= "HTTP/" + std::to_string(expVersionMajor) + '.' + std::to_string(expVersionMinor);
|
|
const http::StatusCode expStatusCode = http::StatusCode::SwitchingProtocols;
|
|
const std::string expReasonPhrase;
|
|
|
|
std::ostringstream oss;
|
|
oss << expVersion << ' ' << static_cast<unsigned>(expStatusCode) << ' ' << expReasonPhrase
|
|
<< "\r\n";
|
|
const std::string data = oss.str();
|
|
|
|
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());
|
|
}
|
|
|
|
void HttpWhiteBoxTests::testStatusLineParserValidIncomplete()
|
|
{
|
|
constexpr auto testname = __func__;
|
|
|
|
const unsigned expVersionMajor = 1;
|
|
const unsigned expVersionMinor = 1;
|
|
const std::string expVersion
|
|
= "HTTP/" + std::to_string(expVersionMajor) + '.' + std::to_string(expVersionMinor);
|
|
const http::StatusCode expStatusCode = http::StatusCode::SwitchingProtocols;
|
|
const std::string expReasonPhrase = "Something Something";
|
|
|
|
std::ostringstream oss;
|
|
oss << expVersion << ' ' << static_cast<unsigned>(expStatusCode) << ' ' << expReasonPhrase
|
|
<< "\r\n";
|
|
const std::string data = oss.str();
|
|
|
|
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());
|
|
}
|
|
|
|
void HttpWhiteBoxTests::testStatusLineSerialize()
|
|
{
|
|
constexpr auto testname = __func__;
|
|
|
|
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);
|
|
}
|
|
|
|
void HttpWhiteBoxTests::testHeader()
|
|
{
|
|
constexpr auto testname = __func__;
|
|
|
|
http::Header header;
|
|
|
|
const std::string data = "\r\na=\r\n\r\n";
|
|
LOK_ASSERT_EQUAL(8L, header.parse(data.c_str(), data.size()));
|
|
}
|
|
|
|
void HttpWhiteBoxTests::testRequestParserValidComplete()
|
|
{
|
|
constexpr auto testname = __func__;
|
|
|
|
const std::string expVerb = "GET";
|
|
const std::string expUrl = "/path/to/data";
|
|
const std::string expVersion = "HTTP/1.1";
|
|
const std::string data = expVerb + ' ' + expUrl + ' ' + expVersion + "\r\n" + "EmptyKey:\r\n"
|
|
+ "Host: localhost.com\r\n\r\n";
|
|
|
|
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());
|
|
LOK_ASSERT_EQUAL(std::string(), req.get("emptykey"));
|
|
LOK_ASSERT_EQUAL(std::string("localhost.com"), req.get("Host"));
|
|
}
|
|
|
|
void HttpWhiteBoxTests::testRequestParserValidIncomplete()
|
|
{
|
|
constexpr auto testname = __func__;
|
|
|
|
const std::string expVerb = "GET";
|
|
const std::string expUrl = "/long/path/to/data";
|
|
const std::string expVersion = "HTTP/1.1";
|
|
const std::string expHost = "localhost.com";
|
|
const std::string data
|
|
= expVerb + ' ' + expUrl + ' ' + expVersion + "\r\n" + "Host: " + expHost + "\r\n\r\n";
|
|
|
|
http::Request req;
|
|
|
|
// Pass incomplete data to the reader.
|
|
for (std::size_t i = 0; i < 33; ++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(), i));
|
|
}
|
|
|
|
// 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));
|
|
|
|
LOK_ASSERT_EQUAL(expVerb, req.getVerb());
|
|
LOK_ASSERT_EQUAL(expUrl, req.getUrl());
|
|
LOK_ASSERT_EQUAL(expVersion, req.getVersion());
|
|
LOK_ASSERT_EQUAL(expHost, req.header().get("Host"));
|
|
}
|
|
|
|
CPPUNIT_TEST_SUITE_REGISTRATION(HttpWhiteBoxTests);
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|