wsd: add utility to parse URIs into primary components

With unit-tests.

Change-Id: Ie6ae1a4fee4863e27ea90af1cf476a72300fa10e
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
This commit is contained in:
Ashod Nakashian 2021-03-24 12:47:50 -04:00 committed by Ashod Nakashian
parent 0118ed6459
commit e9c5c0f812
3 changed files with 91 additions and 0 deletions

View file

@ -8,6 +8,7 @@
#include <config.h>
#include "NetUtil.hpp"
#include <common/Util.hpp>
#include "Socket.hpp"
#if ENABLE_SSL && !MOBILEAPP
@ -90,4 +91,41 @@ connect(const std::string& host, const std::string& port, const bool isSSL,
return socket;
}
bool parseUri(std::string uri, std::string& scheme, std::string& host, std::string& port)
{
const auto itScheme = uri.find("://");
if (itScheme != uri.npos)
{
scheme = uri.substr(0, itScheme + 3); // Include the last slash.
uri = uri.substr(scheme.size()); // Remove the scheme.
}
else
{
// No scheme.
scheme.clear();
}
const auto itUrl = uri.find('/');
if (itUrl != uri.npos)
{
// Remove the URL.
uri = uri.substr(0, itUrl);
}
const auto itPort = uri.find(':');
if (itPort != uri.npos)
{
host = uri.substr(0, itPort);
port = uri.substr(itPort + 1); // Skip the colon.
}
else
{
// No port, just hostname.
host = uri;
port.clear();
}
return !host.empty();
}
} // namespace net

View file

@ -23,4 +23,9 @@ namespace net
std::shared_ptr<StreamSocket>
connect(const std::string& host, const std::string& port, const bool isSSL,
const std::shared_ptr<ProtocolHandlerInterface>& protocolHandler);
/// Decomposes a URI into its components.
/// Returns true if parsing was successful.
bool parseUri(std::string uri, std::string& scheme, std::string& host, std::string& port);
} // namespace net

View file

@ -24,6 +24,7 @@
#include <common/Authorization.hpp>
#include <wsd/FileServer.hpp>
#include <net/Buffer.hpp>
#include <net/NetUtil.hpp>
#include <chrono>
#include <fstream>
@ -59,6 +60,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(testCSSVars);
CPPUNIT_TEST(testStat);
CPPUNIT_TEST(testStringCompare);
CPPUNIT_TEST(testParseUri);
CPPUNIT_TEST_SUITE_END();
@ -86,6 +88,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture
void testCSSVars();
void testStat();
void testStringCompare();
void testParseUri();
};
void WhiteBoxTests::testLOOLProtocolFunctions()
@ -1788,6 +1791,51 @@ void WhiteBoxTests::testStringCompare()
LOK_ASSERT(!Util::iequal("abc", 3, "abcd", 4));
}
void WhiteBoxTests::testParseUri()
{
std::string scheme;
std::string host;
std::string port;
scheme = "***";
host = "***";
port = "***";
LOK_ASSERT(!net::parseUri(std::string(), scheme, host, port));
LOK_ASSERT(scheme.empty());
LOK_ASSERT(host.empty());
LOK_ASSERT(port.empty());
LOK_ASSERT(net::parseUri("domain.com", scheme, host, port));
LOK_ASSERT(scheme.empty());
LOK_ASSERT_EQUAL(std::string("domain.com"), host);
LOK_ASSERT(port.empty());
LOK_ASSERT(net::parseUri("domain.com:88", scheme, host, port));
LOK_ASSERT(scheme.empty());
LOK_ASSERT_EQUAL(std::string("domain.com"), host);
LOK_ASSERT_EQUAL(std::string("88"), port);
LOK_ASSERT(net::parseUri("http://domain.com", scheme, host, port));
LOK_ASSERT_EQUAL(std::string("http://"), scheme);
LOK_ASSERT_EQUAL(std::string("domain.com"), host);
LOK_ASSERT(port.empty());
LOK_ASSERT(net::parseUri("https://domain.com:88", scheme, host, port));
LOK_ASSERT_EQUAL(std::string("https://"), scheme);
LOK_ASSERT_EQUAL(std::string("domain.com"), host);
LOK_ASSERT_EQUAL(std::string("88"), port);
LOK_ASSERT(net::parseUri("http://domain.com/path/to/file", scheme, host, port));
LOK_ASSERT_EQUAL(std::string("http://"), scheme);
LOK_ASSERT_EQUAL(std::string("domain.com"), host);
LOK_ASSERT(port.empty());
LOK_ASSERT(net::parseUri("https://domain.com:88/path/to/file", scheme, host, port));
LOK_ASSERT_EQUAL(std::string("https://"), scheme);
LOK_ASSERT_EQUAL(std::string("domain.com"), host);
LOK_ASSERT_EQUAL(std::string("88"), port);
}
CPPUNIT_TEST_SUITE_REGISTRATION(WhiteBoxTests);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */