5 #include <glog/logging.h>
7 #include <fmt/format.h>
8 #include <fmt/ostream.h>
11 struct fmt::formatter
<Domain
> : ostream_formatter
{};
13 using namespace std::string_literals
;
15 int main(int argc
, char const* argv
[])
19 auto const raw_ips
= "123.123.123.123";
20 auto const add_lit
= "[123.123.123.123]";
21 CHECK_EQ(Domain
{raw_ips
}, Domain
{add_lit
});
23 Domain d0
{"EXAMPLE.COM"};
24 Domain d1
{"example.com."};
31 Domain
const dom2
{"黒川.日本"};
32 Domain
const dom3
{"xn--5rtw95l.xn--wgv71a"};
35 Domain
const poop1
{"💩.la"};
36 Domain
const poop2
{"xn--ls8h.la"};
37 CHECK_EQ(poop1
, poop2
);
39 Domain
const norm0
{"hi⒌com"}; // non-ascii "dot" before "com"
40 Domain
const norm1
{"hi5.com"};
41 CHECK_EQ(norm0
, norm1
);
44 CHECK(Domain::validate("hi⒌com", msg
, dom
));
45 CHECK(Domain::validate("hi5.com", msg
, dom
));
47 CHECK(!Domain::validate("$?%^&*(", msg
, dom
));
48 CHECK_EQ(msg
, "failed to parse domain «$?%^&*(»"s
);
50 CHECK(!Domain::validate("email@123.123.123.123", msg
, dom
));
51 CHECK_EQ(msg
, "failed to parse domain «email@123.123.123.123»"s
);
53 CHECK(!Domain::validate("email@[123.123.123.123]", msg
, dom
));
54 CHECK_EQ(msg
, "failed to parse domain «email@[123.123.123.123]»"s
);
56 auto constexpr long_dom
=
57 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
58 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
59 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
60 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
61 CHECK(Domain::validate(long_dom
, msg
, dom
)) << msg
;
63 CHECK(!Domain::validate(
64 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
65 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
66 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
67 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com",
71 "«xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
72 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
73 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
74 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com» "
77 CHECK(!Domain::validate(
78 "a.b.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
83 "domain label «xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx» too long"s
);
85 CHECK(!Domain::validate(
86 "💩.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com",
90 "domain label «💩.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com» too long"s
);
92 CHECK(!Domain::validate(
94 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
95 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
96 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
97 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
103 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
104 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
105 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."
106 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx» too long"s
);
109 Domain
const junk
{"$?%^&*("};
111 LOG(FATAL
) << "should have thrown";
113 catch (std::exception
const& ex
) {
114 CHECK_EQ(0, strcmp(ex
.what(), "failed to parse domain"));
118 Domain
const ip_addr
{"[127.0.0.1]"};
119 CHECK(ip_addr
.is_address_literal());
121 catch (std::exception
const& ex
) {
122 LOG(FATAL
) << "should not throw " << ex
.what();
126 Domain
const ip_addr
{"127.0.0.1"};
127 CHECK(ip_addr
.is_address_literal());
129 catch (std::exception
const& ex
) {
130 LOG(FATAL
) << "should not throw " << ex
.what();
133 CHECK_EQ(Domain
{"127.0.0.1"}, Domain
{"[127.0.0.1]"});
135 Domain
const mixed_case
{"ExAmPle.COM"};
136 CHECK_EQ(mixed_case
.ascii(), "example.com");
138 CHECK(domain::is_fully_qualified(Domain
{"foo.bar"}, msg
));
140 CHECK(!domain::is_fully_qualified(Domain
{"foo.b"}, msg
));
141 CHECK_EQ(msg
, "TLD «b» must be two or more octets");
143 CHECK(!domain::is_fully_qualified(Domain
{"foo"}, msg
));
144 CHECK_EQ(msg
, "domain «foo» must have two or more labels");
146 for (auto arg
{1}; arg
< argc
; ++arg
) {
147 Domain
const a
{argv
[arg
]};
148 std::cout
<< a
<< '\n';