Skip to content
Snippets Groups Projects
Commit 7c4450fd authored by Seva's avatar Seva Committed by Adrien Béraud
Browse files

http: add url with tests, handle prefix

parent 9b8358cd
Branches
Tags
No related merge requests found
...@@ -362,6 +362,8 @@ if (OPENDHT_TESTS) ...@@ -362,6 +362,8 @@ if (OPENDHT_TESTS)
) )
if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT) if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT)
list (APPEND test_FILES list (APPEND test_FILES
tests/httptester.h
tests/httptester.cpp
tests/dhtproxytester.h tests/dhtproxytester.h
tests/dhtproxytester.cpp tests/dhtproxytester.cpp
) )
......
...@@ -57,6 +57,19 @@ using ConnectHandlerCb = std::function<void(const asio::error_code& ec, ...@@ -57,6 +57,19 @@ using ConnectHandlerCb = std::function<void(const asio::error_code& ec,
using ssl_socket_t = restinio::impl::tls_socket_t; using ssl_socket_t = restinio::impl::tls_socket_t;
using socket_t = asio::ip::tcp::socket; using socket_t = asio::ip::tcp::socket;
class OPENDHT_PUBLIC Url
{
public:
Url(){};
Url(const std::string& url);
std::string url;
std::string protocol {"http"};
std::string host;
std::string service {"80"};
std::string target {"/"};
std::string query;
};
class OPENDHT_PUBLIC Connection class OPENDHT_PUBLIC Connection
{ {
public: public:
...@@ -126,6 +139,7 @@ public: ...@@ -126,6 +139,7 @@ public:
using ResolverCb = std::function<void(const asio::error_code& ec, using ResolverCb = std::function<void(const asio::error_code& ec,
std::vector<asio::ip::tcp::endpoint> endpoints)>; std::vector<asio::ip::tcp::endpoint> endpoints)>;
Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger = {});
Resolver(asio::io_context& ctx, const std::string& host, const std::string& service = "80", Resolver(asio::io_context& ctx, const std::string& host, const std::string& service = "80",
std::shared_ptr<dht::Logger> logger = {}); std::shared_ptr<dht::Logger> logger = {});
......
...@@ -34,6 +34,36 @@ constexpr char HTTP_HEADER_CONTENT_TYPE_JSON[] = "application/json"; ...@@ -34,6 +34,36 @@ constexpr char HTTP_HEADER_CONTENT_TYPE_JSON[] = "application/json";
constexpr char HTTP_HEADER_DELIM[] = "\r\n\r\n"; constexpr char HTTP_HEADER_DELIM[] = "\r\n\r\n";
constexpr char JSON_VALUE_DELIM[] = "\n"; constexpr char JSON_VALUE_DELIM[] = "\n";
Url::Url(const std::string& url): url(url)
{
size_t addr_begin = 0;
// protocol
const size_t proto_end = url.find("://");
if (proto_end != std::string::npos){
addr_begin = proto_end + 3;
if (url.substr(0, proto_end) == "https")
protocol = "https";
}
// host and service
size_t addr_size = url.substr(addr_begin).find("/");
if (addr_size == std::string::npos)
addr_size = url.size() - addr_begin;
auto host_service = splitPort(url.substr(addr_begin, addr_size));
host = host_service.first;
if (!host_service.second.empty())
service = host_service.second;
// target, query
size_t query_begin = url.find("?");
auto addr_end = addr_begin + addr_size;
if (addr_end < url.size()){
if (query_begin == std::string::npos)
target = url.substr(addr_end);
else
target = url.substr(addr_end, query_begin - addr_end);
}
query = url.substr(query_begin + 1);
}
// connection // connection
unsigned int Connection::ids_ = 1; unsigned int Connection::ids_ = 1;
...@@ -269,6 +299,14 @@ Connection::timeout(const std::chrono::seconds timeout, HandlerCb cb) ...@@ -269,6 +299,14 @@ Connection::timeout(const std::chrono::seconds timeout, HandlerCb cb)
// Resolver // Resolver
Resolver::Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger)
: resolver_(ctx), logger_(logger)
{
dht::http::Url http_url(url);
service_ = http_url.service;
resolve(http_url.host, http_url.service);
}
Resolver::Resolver(asio::io_context& ctx, const std::string& host, const std::string& service, Resolver::Resolver(asio::io_context& ctx, const std::string& host, const std::string& service,
std::shared_ptr<dht::Logger> logger) std::shared_ptr<dht::Logger> logger)
: resolver_(ctx), logger_(logger) : resolver_(ctx), logger_(logger)
......
...@@ -3,7 +3,7 @@ bin_PROGRAMS = opendht_unit_tests ...@@ -3,7 +3,7 @@ bin_PROGRAMS = opendht_unit_tests
AM_CPPFLAGS = -I../include AM_CPPFLAGS = -I../include
nobase_include_HEADERS = infohashtester.h valuetester.h cryptotester.h dhtrunnertester.h dhtproxytester.h nobase_include_HEADERS = infohashtester.h valuetester.h cryptotester.h dhtrunnertester.h httptester.h dhtproxytester.h
opendht_unit_tests_SOURCES = tests_runner.cpp cryptotester.cpp infohashtester.cpp valuetester.cpp dhtrunnertester.cpp dhtproxytester.cpp opendht_unit_tests_SOURCES = tests_runner.cpp cryptotester.cpp infohashtester.cpp valuetester.cpp dhtrunnertester.cpp httptester.cpp dhtproxytester.cpp
opendht_unit_tests_LDFLAGS = -lopendht -lcppunit -L@top_builddir@/src/.libs @GnuTLS_LIBS@ opendht_unit_tests_LDFLAGS = -lopendht -lcppunit -L@top_builddir@/src/.libs @GnuTLS_LIBS@
endif endif
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
*
* Author: Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "httptester.h"
// std
#include <iostream>
#include <string>
#include <chrono>
#include <condition_variable>
namespace test {
CPPUNIT_TEST_SUITE_REGISTRATION(HttpTester);
void
HttpTester::setUp() {
logger = dht::log::getStdLogger();
}
void
HttpTester::tearDown() {
}
void
HttpTester::test_parse_url() {
// Arrange
std::string url = "http://google.com/";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "http");
CPPUNIT_ASSERT(parsed.host == "google.com");
CPPUNIT_ASSERT(parsed.service == "80");
CPPUNIT_ASSERT(parsed.target == "/");
}
void
HttpTester::test_parse_url_no_prefix_no_target() {
// Arrange
std::string url = "google.com";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "http");
CPPUNIT_ASSERT(parsed.host == "google.com");
CPPUNIT_ASSERT(parsed.service == "80");
CPPUNIT_ASSERT(parsed.target == "/");
}
void
HttpTester::test_parse_url_target() {
// Arrange
std::string url = "https://www.google.com:666/going/under";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "https");
CPPUNIT_ASSERT(parsed.host == "www.google.com");
CPPUNIT_ASSERT(parsed.service == "666");
CPPUNIT_ASSERT(parsed.target == "/going/under");
}
void
HttpTester::test_parse_url_query() {
// Arrange
std::string url = "http://google.com/?key=1";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "http");
CPPUNIT_ASSERT(parsed.host == "google.com");
CPPUNIT_ASSERT(parsed.service == "80");
CPPUNIT_ASSERT(parsed.target == "/");
CPPUNIT_ASSERT(parsed.query == "key=1");
}
void
HttpTester::test_parse_url_ipv4() {
// Arrange
std::string url = "http://172.217.13.132/";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "http");
CPPUNIT_ASSERT(parsed.host == "172.217.13.132");
CPPUNIT_ASSERT(parsed.service == "80");
CPPUNIT_ASSERT(parsed.target == "/");
}
void
HttpTester::test_parse_url_no_prefix_no_target_ipv4() {
// Arrange
std::string url = "172.217.13.132";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "http");
CPPUNIT_ASSERT(parsed.host == "172.217.13.132");
CPPUNIT_ASSERT(parsed.service == "80");
CPPUNIT_ASSERT(parsed.target == "/");
}
void
HttpTester::test_parse_url_target_ipv4() {
// Arrange
std::string url = "https://172.217.13.132:666/going/under";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "https");
CPPUNIT_ASSERT(parsed.host == "172.217.13.132");
CPPUNIT_ASSERT(parsed.service == "666");
CPPUNIT_ASSERT(parsed.target == "/going/under");
}
void
HttpTester::test_parse_url_ipv6() {
// Arrange
std::string url = "http://[2607:f8b0:4006:804::2004]/";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "http");
CPPUNIT_ASSERT(parsed.host == "2607:f8b0:4006:804::2004");
CPPUNIT_ASSERT(parsed.service == "80");
CPPUNIT_ASSERT(parsed.target == "/");
}
void
HttpTester::test_parse_url_no_prefix_no_target_ipv6() {
// Arrange
std::string url = "2607:f8b0:4006:804::2004";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "http");
CPPUNIT_ASSERT(parsed.host == "2607:f8b0:4006:804::2004");
CPPUNIT_ASSERT(parsed.service == "80");
CPPUNIT_ASSERT(parsed.target == "/");
}
void
HttpTester::test_parse_url_target_ipv6() {
// Arrange
std::string url = "https://[2607:f8b0:4006:804::2004]:666/going/under";
// Act
dht::http::Url parsed (url);
// Assert
CPPUNIT_ASSERT(parsed.url == url);
CPPUNIT_ASSERT(parsed.protocol == "https");
CPPUNIT_ASSERT(parsed.host == "2607:f8b0:4006:804::2004");
CPPUNIT_ASSERT(parsed.service == "666");
CPPUNIT_ASSERT(parsed.target == "/going/under");
}
} // namespace test
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
*
* Author: Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
// cppunit
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <opendht/log.h>
#include <opendht/http.h>
namespace test {
class HttpTester : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(HttpTester);
CPPUNIT_TEST(test_parse_url);
CPPUNIT_TEST(test_parse_url_no_prefix_no_target);
CPPUNIT_TEST(test_parse_url_target);
CPPUNIT_TEST(test_parse_url_query);
CPPUNIT_TEST(test_parse_url_ipv4);
CPPUNIT_TEST(test_parse_url_no_prefix_no_target_ipv4);
CPPUNIT_TEST(test_parse_url_target_ipv4);
CPPUNIT_TEST(test_parse_url_ipv6);
CPPUNIT_TEST(test_parse_url_no_prefix_no_target_ipv6);
CPPUNIT_TEST(test_parse_url_target_ipv6);
CPPUNIT_TEST_SUITE_END();
public:
/**
* Method automatically called before each test by CppUnit
* Init nodes
*/
void setUp();
/**
* Method automatically called after each test CppUnit
*/
void tearDown();
/**
* Test parse urls
*/
void test_parse_url();
void test_parse_url_no_prefix_no_target();
void test_parse_url_target();
void test_parse_url_query();
/**
* Test parse urls (ipv4)
*/
void test_parse_url_ipv4();
void test_parse_url_no_prefix_no_target_ipv4();
void test_parse_url_target_ipv4();
/**
* Test parse urls (ipv6)
*/
void test_parse_url_ipv6();
void test_parse_url_no_prefix_no_target_ipv6();
void test_parse_url_target_ipv6();
private:
std::shared_ptr<dht::Logger> logger {};
};
} // namespace test
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment