1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/*
* (C) 2019 Nuno Goncalves <nunojpg@gmail.com>
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include "tests.h"
#if defined(BOTAN_HAS_SOCKETS) && (defined(BOTAN_TARGET_OS_HAS_SOCKETS) || defined(BOTAN_TARGET_OS_HAS_WINSOCK2))
#include <botan/internal/uri.h>
namespace Botan_Tests {
class URI_Tests final : public Test
{
void test_uri_ctor(std::vector<Test::Result>& results)
{
Test::Result result("uri constructors");
Botan::URI uri(Botan::URI::Type::Domain, "localhost", 80);
result.confirm("type", uri.type == Botan::URI::Type::Domain);
result.test_eq("host", uri.host, "localhost");
result.confirm("post", uri.port == 80);
results.push_back(result);
}
void test_uri_tostring(std::vector<Test::Result>& results)
{
Test::Result result("uri to_string");
result.test_eq("domain", Botan::URI(Botan::URI::Type::Domain, "localhost", 80).to_string(), "localhost:80");
result.test_eq("IPv4", Botan::URI(Botan::URI::Type::IPv4, "192.168.1.1", 80).to_string(), "192.168.1.1:80");
result.test_eq("IPv6", Botan::URI(Botan::URI::Type::IPv6, "::1", 80).to_string(), "[::1]:80");
result.test_eq("IPv6 no port", Botan::URI(Botan::URI::Type::IPv6, "::1", 0).to_string(), "::1");
result.test_throws("invalid", []() {Botan::URI(Botan::URI::Type::NotSet, "", 0).to_string();});
results.push_back(result);
}
void test_uri_factories(std::vector<Test::Result>& results)
{
Test::Result result("uri factories");
struct
{
std::string uri;
Botan::URI::Type type;
std::string host;
unsigned port;
} tests []
{
{"localhost::80", Botan::URI::Type::NotSet, {}, 0},
{"localhost:70000", Botan::URI::Type::NotSet, {}, 0},
{"[::1]:a", Botan::URI::Type::NotSet, {}, 0},
{"[::1]:70000", Botan::URI::Type::NotSet, {}, 0},
{"localhost:80", Botan::URI::Type::Domain, "localhost", 80},
{"www.example.com", Botan::URI::Type::Domain, "www.example.com", 0},
{"192.168.1.1", Botan::URI::Type::IPv4, "192.168.1.1", 0},
{"192.168.1.1:34567", Botan::URI::Type::IPv4, "192.168.1.1", 34567},
{"[::1]:61234", Botan::URI::Type::IPv6, "::1", 61234},
};
for(const auto t : tests)
{
auto test_URI = [&result](const Botan::URI& uri, const std::string& host, const unsigned port)
{
result.test_eq("host", uri.host, host);
result.confirm("port", uri.port==port);
};
if(t.type!=Botan::URI::Type::IPv4)
result.test_throws("invalid", [&t]() {Botan::URI::fromIPv4(t.uri);});
if(t.type!=Botan::URI::Type::IPv6)
result.test_throws("invalid", [&t]() {Botan::URI::fromIPv6(t.uri);});
if(t.type!=Botan::URI::Type::Domain)
result.test_throws("invalid", [&t]() {Botan::URI::fromDomain(t.uri);});
if(t.type==Botan::URI::Type::NotSet)
{
result.test_throws("invalid", [&t]() {Botan::URI::fromAny(t.uri);});
}
else
{
const auto any = Botan::URI::fromAny(t.uri);
result.confirm("type any", any.type == t.type);
test_URI(any, t.host, t.port);
if(t.type == Botan::URI::Type::Domain)
{ test_URI(Botan::URI::fromDomain(t.uri), t.host, t.port); }
else if(t.type == Botan::URI::Type::IPv4)
{ test_URI(Botan::URI::fromIPv4(t.uri), t.host, t.port); }
else if(t.type == Botan::URI::Type::IPv6)
{ test_URI(Botan::URI::fromIPv6(t.uri), t.host, t.port); }
}
}
//since GCC 4.8 does not support regex this would possibly be acceped as valid domains,
//but we just want to test IPv6 parsing, so the test needs to be individual
result.test_throws("invalid IPv6", [](){ Botan::URI::fromIPv6("]"); });
result.test_throws("invalid IPv6", [](){ Botan::URI::fromIPv6("[::1]1"); });
results.push_back(result);
}
public:
std::vector<Test::Result> run() override
{
std::vector<Test::Result> results;
test_uri_ctor(results);
test_uri_tostring(results);
test_uri_factories(results);
return results;
}
};
BOTAN_REGISTER_TEST("uri", URI_Tests);
} // namespace Botan_Tests
#endif
|