2
0
mirror of https://github.com/boostorg/url.git synced 2026-01-19 16:52:14 +00:00
Files
url/test/unit/url_base.cpp
2025-08-29 12:01:50 -05:00

1849 lines
62 KiB
C++

//
// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/url
//
// Test that header file is self-contained.
#include <boost/url/url_base.hpp>
#include <boost/url/decode_view.hpp>
#include <boost/url/url.hpp>
#include "test_suite.hpp"
/* Legend
'#' 0x23 '=' 0x3d
'%' 0x25 '@' 0x40
'&' 0x26 '[' 0x5b
'.' 0x2e ']' 0x5d
':' 0x3a
*/
#ifdef BOOST_TEST_CSTR_EQ
#undef BOOST_TEST_CSTR_EQ
#define BOOST_TEST_CSTR_EQ(expr1,expr2) \
BOOST_TEST_EQ( boost::urls::detail::to_sv(expr1), boost::urls::detail::to_sv(expr2) )
#endif
namespace boost {
namespace urls {
struct url_base_test
{
template<class F>
static
void
modify(
core::string_view before,
core::string_view after,
F&& f)
{
url u(before);
f(u);
auto s = u.buffer();
BOOST_TEST_EQ(s, after);
}
//--------------------------------------------
//
// Scheme
//
//--------------------------------------------
void
testSetScheme()
{
auto const remove = [](
core::string_view s1, core::string_view s2)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST_EQ(u.remove_scheme().buffer(), s2);
BOOST_TEST_EQ(u.scheme_id(), scheme::none);
BOOST_TEST(u.scheme().empty());
};
auto const set = [](
scheme id, core::string_view s1,
core::string_view s2, core::string_view s3)
{
url u;
BOOST_TEST_NO_THROW(u = url(s2));
BOOST_TEST(u.set_scheme(s1).buffer() == s3);
BOOST_TEST_EQ(u.scheme(), s1);
BOOST_TEST_EQ(u.scheme_id(), id);
};
auto const setid = [](
scheme id, core::string_view s1, core::string_view s2)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST(u.set_scheme_id(id).buffer() == s2);
BOOST_TEST_EQ(u.scheme_id(), id);
};
remove("", "");
remove("x", "x");
remove("x:", "");
remove("x:/", "/");
remove("x:a", "a");
remove("x:a/", "a/");
remove("x:/a", "/a");
remove("x://a", "//a");
remove("x:///a", "///a");
remove("x://", "//");
remove("x:a:", "a%3A");
remove("x:a:/", "a%3A/");
remove("yabba:dabba:doo", "dabba%3Adoo");
remove("yabba:dabba:doo:doo", "dabba%3Adoo%3Adoo");
remove("x::::", "%3A%3A%3A");
remove("x://a.b/1/2", "//a.b/1/2");
remove("x://a:b@c.d/1/?#", "//a:b@c.d/1/?#");
set(scheme::ftp, "ftp", "", "ftp:");
set(scheme::ws, "ws", "/", "ws:/");
set(scheme::ws, "ws", "a", "ws:a");
set(scheme::ws, "ws", "a/", "ws:a/");
set(scheme::ws, "ws", "//", "ws://");
set(scheme::ws, "ws", "a:/", "ws:/");
set(scheme::http, "http", "./a:", "http:a:");
set(scheme::ws, "ws", "//a.b/1/2", "ws://a.b/1/2");
set(scheme::ws, "ws", "//a:b@c.d/1/?#", "ws://a:b@c.d/1/?#");
setid(scheme::ftp, "", "ftp:");
setid(scheme::ws, "/", "ws:/");
setid(scheme::ws, "a", "ws:a");
setid(scheme::ws, "a/", "ws:a/");
setid(scheme::ws, "//", "ws://");
setid(scheme::ws, "a:/", "ws:/");
setid(scheme::ws,
"//a.b/1/2", "ws://a.b/1/2");
setid(scheme::ws,
"//a:b@c.d/1/?#", "ws://a:b@c.d/1/?#");
setid(scheme::none, "a:/", "/");
BOOST_TEST_THROWS(
url().set_scheme(""),
system::system_error);
BOOST_TEST_THROWS(
url().set_scheme("http~"),
system::system_error);
BOOST_TEST_THROWS(
url().set_scheme_id(scheme::unknown),
system::system_error);
// self-intersection
modify(
"x://?mailto",
"mailto://?mailto",
[](url_base& u)
{
u.set_scheme(
u.encoded_query());
});
}
//--------------------------------------------
//
// Authority
//
//--------------------------------------------
void
testSetAuthority()
{
auto const remove = [](
core::string_view s1, core::string_view s2)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST_EQ(u.remove_authority().buffer(), s2);
BOOST_TEST(u.encoded_authority().empty());
BOOST_TEST(! u.has_authority());
BOOST_TEST(! u.has_userinfo());
BOOST_TEST(! u.has_password());
BOOST_TEST(! u.has_port());
BOOST_TEST(u.host_address().empty());
};
auto const set = [](core::string_view s1,
core::string_view s2, core::string_view s3)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST(u.set_encoded_authority(s2).buffer() == s3);
BOOST_TEST_EQ(u.encoded_authority(), s2);
BOOST_TEST(u.has_authority());
};
BOOST_TEST_THROWS(
url().set_encoded_authority("x:y"),
system::system_error);
BOOST_TEST_THROWS(
url().set_encoded_authority("%2"),
system::system_error);
remove("", "");
remove("/", "/");
remove("/x", "/x");
remove("/x/", "/x/");
remove("/x/y", "/x/y");
remove("x/", "x/");
remove("x/y", "x/y");
remove("x/y/", "x/y/");
remove("x/y/?#", "x/y/?#");
remove("x/y/?#", "x/y/?#");
remove("z:", "z:");
remove("z:/", "z:/");
remove("z:/x", "z:/x");
remove("z:/x/", "z:/x/");
remove("z:/x/y", "z:/x/y");
remove("z:x/", "z:x/");
remove("z:x/y", "z:x/y");
remove("z:x/y/", "z:x/y/");
remove("z:x/y/?#", "z:x/y/?#");
remove("z:x:/y/?#", "z:x:/y/?#");
remove("//", "");
remove("///", "/");
remove("///x", "/x");
remove("///x/", "/x/");
remove("///x/y", "/x/y");
remove("//x/", "/");
remove("//x/y", "/y");
remove("//x/y/", "/y/");
remove("//x/y/?#", "/y/?#");
remove("z://", "z:");
remove("z:///", "z:/");
remove("z:///x", "z:/x");
remove("z:///x/", "z:/x/");
remove("z:///x/y", "z:/x/y");
remove("z://x/", "z:/");
remove("z://x/y", "z:/y");
remove("z://x/y/", "z:/y/");
remove("z://x/y/?#", "z:/y/?#");
remove("z://x:/y/?#", "z:/y/?#");
remove("z://x//y/?q#f", "z:/.//y/?q#f");
set("", "", "//");
set("", "x@", "//x@");
set("", ":x@", "//:x@");
set("", "x:y@", "//x:y@");
set("", "x", "//x");
set("", "x.y", "//x.y");
set("", "x:", "//x:");
set("", ":", "//:");
set("", ":0", "//:0");
set("", ":443", "//:443");
set("", ":65536", "//:65536");
set("", "1.2.3.4", "//1.2.3.4");
set("", "[v1.0]", "//[v1.0]");
set("", "[::]", "//[::]");
set("", "[::ffff:127.0.0.1]",
"//[::ffff:127.0.0.1]");
set("", "[::ffff:127.0.0.1]:80",
"//[::ffff:127.0.0.1]:80");
set("", "user:pass@example.com:80",
"//user:pass@example.com:80");
set("ws:",
"user:pass@example.com:80",
"ws://user:pass@example.com:80");
set("///a", "", "///a");
set("///a", "x@", "//x@/a");
set("///a", ":x@", "//:x@/a");
set("///a", "x:y@", "//x:y@/a");
set("///a", "x", "//x/a");
set("///a", "x.y", "//x.y/a");
set("///a", "x:", "//x:/a");
set("///a", ":", "//:/a");
set("///a", ":0", "//:0/a");
set("///a", ":443", "//:443/a");
set("///a", ":65536", "//:65536/a");
set("///a", "1.2.3.4", "//1.2.3.4/a");
set("///a", "[v1.0]", "//[v1.0]/a");
set("///a", "[::]", "//[::]/a");
set("///a", "[::ffff:127.0.0.1]",
"//[::ffff:127.0.0.1]/a");
set("///a", "[::ffff:127.0.0.1]:80",
"//[::ffff:127.0.0.1]:80/a");
set("///a", "user:pass@example.com:80",
"//user:pass@example.com:80/a");
set("ws:///a",
"user:pass@example.com:80",
"ws://user:pass@example.com:80/a");
// self-intersection
modify(
"x://@?user:pass@example.com:8080",
"x://user:pass@example.com:8080?user:pass@example.com:8080",
[](url_base& u)
{
u.set_encoded_authority(
u.encoded_query());
});
}
//--------------------------------------------
//
// Userinfo
//
//--------------------------------------------
void
testSetUserinfo()
{
auto const remove = [](
core::string_view s1, core::string_view s2)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST_EQ(u.remove_userinfo().buffer(), s2);
BOOST_TEST(u.encoded_userinfo().empty());
BOOST_TEST(u.userinfo().empty());
BOOST_TEST(! u.has_userinfo());
};
auto const set = [](core::string_view s1,
core::string_view s2, core::string_view s3)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST_EQ(u.set_userinfo(s2).buffer(), s3);
};
auto const enc = [](core::string_view s1,
core::string_view s2, core::string_view s3)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST_EQ(u.set_encoded_userinfo(s2).buffer(), s3);
BOOST_TEST_EQ(u.encoded_userinfo(), s2);
BOOST_TEST(u.has_userinfo());
};
BOOST_TEST_THROWS(url().set_encoded_userinfo("%2"), std::exception);
remove("", "");
remove("/", "/");
remove("//", "//");
remove("//@", "//");
remove("//a@", "//");
remove("//a:@", "//");
remove("//a:b@", "//");
remove("//@x", "//x");
remove("//a@x", "//x");
remove("//a:b@x", "//x");
remove("//a:b@x/", "//x/");
remove("z:", "z:");
remove("z:/", "z:/");
remove("z://", "z://");
remove("z://@", "z://");
remove("z://a@", "z://");
remove("z://a:@", "z://");
remove("z://a:b@", "z://");
remove("z://@x", "z://x");
remove("z://a@x", "z://x");
remove("z://a:b@x", "z://x");
set("", "", "//@");
set("/", "", "//@/");
set("//", "", "//@");
set("//@", "", "//@");
set("//a@", "", "//@");
set("//a:@", "", "//@");
set("//a:b@", "", "//@");
set("//@x", "", "//@x");
set("//a@x", "", "//@x");
set("//a:b@x", "", "//@x");
set("//a:b@x/", "", "//@x/");
set("w:", "", "w://@");
set("w:/", "", "w://@/");
set("w://", "", "w://@");
set("w://@", "", "w://@");
set("w://a@", "", "w://@");
set("w://a:@", "", "w://@");
set("w://a:b@", "", "w://@");
set("w://@x", "", "w://@x");
set("w://a@x", "", "w://@x");
set("w://a:b@x", "", "w://@x");
set("w://a:b@x/", "", "w://@x/");
set("", ":", "//:@");
set("/", "a", "//a@/");
set("//", "@", "//%40@");
set("//@", "xyz", "//xyz@");
set("//a@", ":@", "//:%40@");
set("//a:@", "x", "//x@");
set("//a:b@", "p:q", "//p:q@");
set("//@x", "z", "//z@x");
set("//a@x", "42", "//42@x");
set("//a:b@x", "UV", "//UV@x");
set("//a:b@x/", "NR", "//NR@x/");
set("w:", ":", "w://:@");
set("w:/", "a", "w://a@/");
set("w://", "@", "w://%40@");
set("w://@", "xyz", "w://xyz@");
set("w://a@", ":@", "w://:%40@");
set("w://a:@", "x", "w://x@");
set("w://a:b@", "p:q", "w://p:q@");
set("w://@x", "z", "w://z@x");
set("w://a@x", "42", "w://42@x");
set("w://a:b@x", "UV", "w://UV@x");
set("w://a:b@x/", "NR", "w://NR@x/");
enc("", "", "//@");
enc("/", "", "//@/");
enc("//", "", "//@");
enc("//@", "", "//@");
enc("//a@", "", "//@");
enc("//a:@", "", "//@");
enc("//a:b@", "", "//@");
enc("//@x", "", "//@x");
enc("//a@x", "", "//@x");
enc("//a:b@x", "", "//@x");
enc("//a:b@x/", "", "//@x/");
enc("w:", "", "w://@");
enc("w:/", "", "w://@/");
enc("w://", "", "w://@");
enc("w://@", "", "w://@");
enc("w://a@", "", "w://@");
enc("w://a:@", "", "w://@");
enc("w://a:b@", "", "w://@");
enc("w://@x", "", "w://@x");
enc("w://a@x", "", "w://@x");
enc("w://a:b@x", "", "w://@x");
enc("w://a:b@x/", "", "w://@x/");
enc("", ":", "//:@");
enc("", "%3a", "//%3a@");
enc("/", "%41", "//%41@/");
enc("//", "x", "//x@");
enc("//@", "xyz", "//xyz@");
enc("//a@", "%3a%40", "//%3a%40@");
enc("//a:@", "x", "//x@");
enc("//a:b@", "p:q", "//p:q@");
enc("//@x", "z", "//z@x");
enc("//a@x", "42", "//42@x");
enc("//a:b@x", "UV", "//UV@x");
enc("//a:b@x/", "NR", "//NR@x/");
enc("w:", ":", "w://:@");
enc("w:", "%3a", "w://%3a@");
enc("w:/", "%41", "w://%41@/");
enc("w://", "x", "w://x@");
enc("w://@", "xyz", "w://xyz@");
enc("w://a@", "%3a%40", "w://%3a%40@");
enc("w://a:@", "x", "w://x@");
enc("w://a:b@", "p:q", "w://p:q@");
enc("w://@x", "z", "w://z@x");
enc("w://a@x", "42", "w://42@x");
enc("w://a:b@x", "UV", "w://UV@x");
enc("w://a:b@x/", "NR", "w://NR@x/");
// self-intersection
modify(
"x://?user:pass",
"x://user:pass@?user:pass",
[](url_base& u)
{
u.set_encoded_userinfo(u.encoded_query());
});
modify(
"x://?user:pass",
"x://user:pass@?user:pass",
[](url_base& u)
{
u.set_userinfo(
u.encoded_query());
});
modify(
"x://?user:pass",
"x://user:pass@?user:pass",
[](url_base& u)
{
u.set_userinfo(
u.query());
});
}
void
testSetUser()
{
auto const set = [](
core::string_view s0,
core::string_view s,
core::string_view s1)
{
modify(s0, s1,
[s](url_base& u)
{
u.set_user(s);
BOOST_TEST(u.user() == s);
BOOST_TEST(u.has_userinfo());
});
};
auto const enc = [](
core::string_view s0,
core::string_view s,
core::string_view s1)
{
modify(s0, s1,
[s](url_base& u)
{
BOOST_TEST_NO_THROW(u.set_encoded_user(s));
BOOST_TEST_EQ(
decode_view(s),
decode_view(u.encoded_user()));
BOOST_TEST(u.has_userinfo());
});
};
BOOST_TEST_THROWS(
url().set_encoded_user("%2"),
system::system_error);
set("", "", "//@");
set("/y", "", "//@/y");
set("//", "", "//@");
set("//y", "", "//@y");
set("//@", "", "//@");
set("//:@", "", "//:@");
set("//y@", "", "//@");
set("//y@z", "", "//@z");
set("//y:@", "", "//:@");
set("//y:z@", "", "//:z@");
set("//a:b@c", "", "//:b@c");
set("ws:", "", "ws://@");
set("ws:/y", "", "ws://@/y");
set("ws://", "", "ws://@");
set("ws://y", "", "ws://@y");
set("ws://@", "", "ws://@");
set("ws://:@", "", "ws://:@");
set("ws://y@", "", "ws://@");
set("ws://y@z", "", "ws://@z");
set("ws://y:@", "", "ws://:@");
set("ws://y:z@", "", "ws://:z@");
set("ws://a:b@c", "", "ws://:b@c");
set("", "", "//@");
set("", "x", "//x@");
set("/y", "x", "//x@/y");
set("//", "x", "//x@");
set("//y", "x", "//x@y");
set("//@", "x", "//x@");
set("//:@", "x", "//x:@");
set("//y@", "x", "//x@");
set("//y@z", "x", "//x@z");
set("//y:@", "x", "//x:@");
set("//y:z@", "x", "//x:z@");
set("//a:b@c", "x", "//x:b@c");
set("ws:", "x", "ws://x@");
set("ws:/y", "x", "ws://x@/y");
set("ws://", "x", "ws://x@");
set("ws://y", "x", "ws://x@y");
set("ws://@", "x", "ws://x@");
set("ws://:@", "x", "ws://x:@");
set("ws://y@", "x", "ws://x@");
set("ws://y@z", "x", "ws://x@z");
set("ws://y:@", "x", "ws://x:@");
set("ws://y:z@", "x", "ws://x:z@");
set("ws://a:b@c", "x", "ws://x:b@c");
set("ws://a:b@c", ":", "ws://%3A:b@c");
set("ws://a:b@c", "@", "ws://%40:b@c");
enc("", "", "//@");
enc("", "%41", "//%41@");
enc("/y", "%41", "//%41@/y");
enc("//", "%41", "//%41@");
enc("//y", "%41", "//%41@y");
enc("//@", "%41", "//%41@");
enc("//:@", "%41", "//%41:@");
enc("//y@", "%41", "//%41@");
enc("//y@z", "%41", "//%41@z");
enc("//y:@", "%41", "//%41:@");
enc("//y:z@", "%41", "//%41:z@");
enc("//a:b@c", "%41", "//%41:b@c");
enc("ws:", "%41", "ws://%41@");
enc("ws:/y", "%41", "ws://%41@/y");
enc("ws://", "%41", "ws://%41@");
enc("ws://y", "%41", "ws://%41@y");
enc("ws://@", "%41", "ws://%41@");
enc("ws://:@", "%41", "ws://%41:@");
enc("ws://y@", "%41", "ws://%41@");
enc("ws://y@z", "%41", "ws://%41@z");
enc("ws://y:@", "%41", "ws://%41:@");
enc("ws://y:z@", "%41", "ws://%41:z@");
enc("ws://a:b@c", "%41", "ws://%41:b@c");
enc("x:", "user%3apass", "x://user%3apass@");
enc("x:", "user@local", "x://user%40local@");
// self-intersection
modify(
"x://u@/?johndoe",
"x://johndoe@/?johndoe",
[](url_base& u)
{
u.set_encoded_user(
u.encoded_query());
});
modify(
"x://u@/?johndoe",
"x://johndoe@/?johndoe",
[](url_base& u)
{
u.set_user(
u.query());
});
modify(
"x://u@/?johndoe",
"x://johndoe@/?johndoe",
[](url_base& u)
{
u.set_user(
u.encoded_query());
});
// path doesn't become host
{
url u("mailto:example.net");
BOOST_TEST_NO_THROW(u.set_encoded_user("me"));
BOOST_TEST_CSTR_EQ(u, "mailto://me@/example.net");
BOOST_TEST_NOT(u.buffer() == "mailto://me@example.net");
BOOST_TEST_CSTR_EQ(u.encoded_user(), "me");
}
{
url u("mailto:you@example.net");
BOOST_TEST_NO_THROW(u.set_encoded_user("me"));
BOOST_TEST_CSTR_EQ(u, "mailto://me@/you@example.net");
BOOST_TEST_NOT(u.buffer() == "mailto://me@you@example.net");
BOOST_TEST_CSTR_EQ(u.encoded_user(), "me");
}
{
url u("mailto:a@b.c");
BOOST_TEST_NO_THROW(u.set_encoded_password("secret"));
BOOST_TEST_CSTR_EQ(u, "mailto://:secret@/a@b.c");
}
{
url u("mailto:a@b.c");
BOOST_TEST_NO_THROW(u.set_encoded_userinfo("u:p"));
BOOST_TEST_CSTR_EQ(u, "mailto://u:p@/a@b.c");
}
{
url u("mailto://h/a@b.c");
BOOST_TEST_NO_THROW(u.set_encoded_userinfo("u:p"));
BOOST_TEST_CSTR_EQ(u, "mailto://u:p@h/a@b.c");
}
{
url u("mailto:a@b.c");
BOOST_TEST_NO_THROW(u.set_encoded_userinfo("u"));
BOOST_TEST_CSTR_EQ(u, "mailto://u@/a@b.c");
}
{
url u("mailto://h/a@b.c");
BOOST_TEST_NO_THROW(u.set_encoded_userinfo("u"));
BOOST_TEST_CSTR_EQ(u, "mailto://u@h/a@b.c");
}
{
url u("mailto:a@b.c");
BOOST_TEST_NO_THROW(u.set_encoded_host("host"));
BOOST_TEST_CSTR_EQ(u, "mailto://host/a@b.c");
}
{
url u("mailto:a@b.c");
BOOST_TEST_NO_THROW(u.set_port("80"));
BOOST_TEST_CSTR_EQ(u, "mailto://:80/a@b.c");
}
}
void
testSetPassword()
{
auto const remove = [](
core::string_view s1, core::string_view s2)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST(u.remove_password().buffer() == s2);
BOOST_TEST_EQ(u.encoded_password(), "");
BOOST_TEST_EQ(u.password(), "");
};
auto const set = [](
core::string_view s1, core::string_view s2,
core::string_view s3)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST(u.set_password(s2).buffer() == s3);
};
auto const enc = [](
core::string_view s1, core::string_view s2,
core::string_view s3)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST(u.set_encoded_password(
s2).buffer() == s3);
BOOST_TEST_EQ(u.encoded_password(), s2);
BOOST_TEST(u.has_userinfo());
};
BOOST_TEST_THROWS(url().set_encoded_password(
"%2"), system::system_error);
remove("", "");
remove("/", "/");
remove("//", "//");
remove("//", "//");
remove("//@", "//@");
remove("//y@", "//y@");
remove("//:y@", "//@");
remove("//y:z@", "//y@");
remove("//y:z@a", "//y@a");
remove("x:", "x:");
remove("x:/", "x:/");
remove("x://", "x://");
remove("x://", "x://");
remove("x://@", "x://@");
remove("x://y@", "x://y@");
remove("x://:y@", "x://@");
remove("x://y:z@", "x://y@");
remove("x://y:z@a", "x://y@a");
set("", "", "//:@");
set("/", "", "//:@/");
set("//", "", "//:@");
set("//@", "", "//:@");
set("//y@", "", "//y:@");
set("//:y@", "", "//:@");
set("//y:z@", "", "//y:@");
set("//y:z@a", "", "//y:@a");
set("x:", "", "x://:@");
set("x:/", "", "x://:@/");
set("x://", "", "x://:@");
set("x://@", "", "x://:@");
set("x://y@", "", "x://y:@");
set("x://:y@", "", "x://:@");
set("x://y:z@", "", "x://y:@");
set("x://y:z@a", "", "x://y:@a");
set("", "x", "//:x@");
set("/", "x", "//:x@/");
set("//", "x", "//:x@");
set("//x", "y", "//:y@x");
set("//x@", "y", "//x:y@");
set("//x:y@", "z", "//x:z@");
set("//x:abc@", "z", "//x:z@");
set("//x:z@", "abc", "//x:abc@");
set("w:", "x", "w://:x@");
set("w:/", "x", "w://:x@/");
set("w://", "x", "w://:x@");
set("w://x", "y", "w://:y@x");
set("w://x@", "y", "w://x:y@");
set("w://x:y@", "z", "w://x:z@");
set("w://x:abc@", "z", "w://x:z@");
set("w://x:z@", "abc", "w://x:abc@");
set("w://x:z@", ":", "w://x::@");
set("w://x:z@", "@", "w://x:%40@");
enc("", "", "//:@");
enc("", "%41", "//:%41@");
enc("/y", "%41", "//:%41@/y");
enc("//", "%41", "//:%41@");
enc("//y", "%41", "//:%41@y");
enc("//@", "%41", "//:%41@");
enc("//:@", "%41", "//:%41@");
enc("//y@", "%41", "//y:%41@");
enc("//y@z", "%41", "//y:%41@z");
enc("//y:@", "%41", "//y:%41@");
enc("//y:z@", "%41", "//y:%41@");
enc("//a:b@c", "%41", "//a:%41@c");
enc("ws:", "%41", "ws://:%41@");
enc("ws:/y", "%41", "ws://:%41@/y");
enc("ws://", "%41", "ws://:%41@");
enc("ws://y", "%41", "ws://:%41@y");
enc("ws://@", "%41", "ws://:%41@");
enc("ws://:@", "%41", "ws://:%41@");
enc("ws://y@", "%41", "ws://y:%41@");
enc("ws://y@z", "%41", "ws://y:%41@z");
enc("ws://y:@", "%41", "ws://y:%41@");
enc("ws://y:z@", "%41", "ws://y:%41@");
enc("ws://a:b@c", "%41", "ws://a:%41@c");
// self-intersection
modify(
"x://:p@/?johndoe",
"x://:johndoe@/?johndoe",
[](url_base& u)
{
u.set_encoded_password(
u.encoded_query());
});
modify(
"x://:p@/?johndoe",
"x://:johndoe@/?johndoe",
[](url_base& u)
{
u.set_password(
u.query());
});
modify(
"x://:p@/?johndoe",
"x://:johndoe@/?johndoe",
[](url_base& u)
{
u.set_password(
u.encoded_query());
});
}
//--------------------------------------------
//
// Host
//
//--------------------------------------------
static
std::string
bracketed(
std::string s)
{
return
std::string("[") + s +
std::string("]");
}
void
testSetHost()
{
auto const set_host = [](
core::string_view s,
core::string_view s1,
host_type ht)
{
url u;
BOOST_TEST_NO_THROW(u.set_host(s));
BOOST_TEST_EQ(u.host_type(), ht);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
switch(ht)
{
case host_type::none:
BOOST_TEST_FAIL();
break;
case host_type::ipv4:
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address(s));
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::ipv6:
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(bracketed(u.host_address()), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(u.host_address()));
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::ipvfuture:
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(bracketed(u.host_address()), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), u.host_address());
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::name:
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), s);
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
}
};
auto const set_encoded_host = [](
core::string_view s,
core::string_view s1,
host_type ht)
{
url u;
BOOST_TEST_NO_THROW(u.set_encoded_host(s));
BOOST_TEST_EQ(u.host_type(), ht);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
switch(ht)
{
case host_type::none:
BOOST_TEST_FAIL();
break;
case host_type::ipv4:
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address(s));
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::ipv6:
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(bracketed(u.host_address()), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(u.host_address()));
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::ipvfuture:
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(bracketed(u.host_address()), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), u.host_address());
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::name:
BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode());
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode());
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
}
};
auto const set_host_address = [](
core::string_view s,
core::string_view s1,
host_type ht)
{
url u;
BOOST_TEST_NO_THROW(u.set_host_address(s));
BOOST_TEST_EQ(u.host_type(), ht);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
switch(ht)
{
case host_type::none:
BOOST_TEST_FAIL();
break;
case host_type::ipv4:
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address(s));
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::ipv6:
BOOST_TEST_EQ(u.encoded_host(), bracketed(s));
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(s));
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::ipvfuture:
BOOST_TEST_EQ(u.encoded_host(), bracketed(s));
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), s);
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::name:
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), s);
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
}
};
auto const set_encoded_host_address = [](
core::string_view s,
core::string_view s1,
host_type ht)
{
url u;
BOOST_TEST_NO_THROW(u.set_encoded_host_address(s));
BOOST_TEST_EQ(u.host_type(), ht);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
switch(ht)
{
case host_type::none:
BOOST_TEST_FAIL();
break;
case host_type::ipv4:
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address(s));
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::ipv6:
BOOST_TEST_EQ(u.encoded_host(), bracketed(s));
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(s));
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::ipvfuture:
BOOST_TEST_EQ(u.encoded_host(), bracketed(s));
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), s);
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
case host_type::name:
BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode());
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode());
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
break;
}
};
auto const set_host_ipv4 = [](
core::string_view s,
core::string_view s1)
{
url u;
BOOST_TEST_NO_THROW(u.set_host_ipv4(ipv4_address(s)));
BOOST_TEST_EQ(u.host_type(), host_type::ipv4);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
BOOST_TEST_EQ(u.encoded_host(), s);
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address(s));
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
};
auto const set_host_ipv6 = [](
core::string_view s,
core::string_view s1)
{
url u;
BOOST_TEST_NO_THROW(u.set_host_ipv6(ipv6_address(s)));
BOOST_TEST_EQ(u.host_type(), host_type::ipv6);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
BOOST_TEST_EQ(u.encoded_host(), bracketed(s));
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address(s));
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
};
auto const set_host_ipvfuture = [](
core::string_view s,
core::string_view s1)
{
url u;
BOOST_TEST_NO_THROW(u.set_host_ipvfuture(s))
BOOST_TEST_EQ(u.host_type(), host_type::ipvfuture);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
BOOST_TEST_EQ(u.encoded_host(), bracketed(s));
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), s);
BOOST_TEST_EQ(u.host_name(), "");
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
};
auto const set_host_name = [](
core::string_view s,
core::string_view s1)
{
url u;
BOOST_TEST_NO_THROW(u.set_host_name(s))
BOOST_TEST_EQ(u.host_type(), host_type::name);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), s);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
BOOST_TEST_EQ(u.host_address(), s);
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), s);
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
};
auto const set_encoded_host_name = [](
core::string_view s,
core::string_view s1)
{
url u;
BOOST_TEST_NO_THROW(u.set_encoded_host_name(s))
BOOST_TEST_EQ(u.host_type(), host_type::name);
BOOST_TEST_EQ(u.buffer(), s1);
BOOST_TEST_EQ(u.host(), u.encoded_host().decode());
auto rv = parse_ipv4_address(s);
if(! rv)
BOOST_TEST_EQ(u.encoded_host(), s);
else
BOOST_TEST_EQ(u.host(), rv->to_string());
BOOST_TEST_EQ(u.host_address(), pct_string_view(s).decode());
BOOST_TEST_EQ(u.host_ipv4_address(), ipv4_address());
BOOST_TEST_EQ(u.host_ipv6_address(), ipv6_address());
BOOST_TEST_EQ(u.host_ipvfuture(), "");
BOOST_TEST_EQ(u.host_name(), pct_string_view(s).decode());
BOOST_TEST_EQ(u.host_name(), u.encoded_host_name().decode());
};
set_host("", "//", host_type::name);
set_host("127.0.0.1", "//127.0.0.1", host_type::ipv4);
set_host("[1::6:c0a8:1]", "//[1::6:c0a8:1]", host_type::ipv6 );
set_host("[v42.69]", "//[v42.69]", host_type::ipvfuture );
set_host("www.example.com", "//www.example.com", host_type::name);
set_host("%5b%3a", "//%255b%253a", host_type::name);
set_encoded_host("", "//", host_type::name);
set_encoded_host("127.0.0.1", "//127.0.0.1", host_type::ipv4);
set_encoded_host("10.2.201.1", "//10.2.201.1", host_type::ipv4);
set_encoded_host("0.5.15.20", "//0.5.15.20", host_type::ipv4);
set_encoded_host("100.101.110.115", "//100.101.110.115", host_type::ipv4);
set_encoded_host("200.205.210.255", "//200.205.210.255", host_type::ipv4);
set_encoded_host("[1::6:c0a8:1]", "//[1::6:c0a8:1]", host_type::ipv6 );
set_encoded_host("[::ffff:192.168.102.0]", "//[::ffff:192.168.102.0]", host_type::ipv6 );
set_encoded_host("[v42.69]", "//[v42.69]", host_type::ipvfuture );
set_encoded_host("www.example.com", "//www.example.com", host_type::name);
set_encoded_host("%5b%3a", "//%5b%3a", host_type::name);
set_encoded_host("%00", "//%00", host_type::name);
set_host_address("", "//", host_type::name);
set_host_address("127.0.0.1", "//127.0.0.1", host_type::ipv4);
set_host_address("1::6:c0a8:1", "//[1::6:c0a8:1]", host_type::ipv6 );
set_host_address("v42.69", "//[v42.69]", host_type::ipvfuture );
set_host_address("www.example.com", "//www.example.com", host_type::name);
set_host_address("%5b%3a", "//%255b%253a", host_type::name);
set_encoded_host_address("", "//", host_type::name);
set_encoded_host_address("127.0.0.1", "//127.0.0.1", host_type::ipv4);
set_encoded_host_address("127%2e0.0.1", "//127%2e0.0.1", host_type::name);
set_encoded_host_address("1::6:c0a8:1", "//[1::6:c0a8:1]", host_type::ipv6 );
set_encoded_host_address("v42.69", "//[v42.69]", host_type::ipvfuture );
set_encoded_host_address("www.example.com", "//www.example.com", host_type::name);
set_encoded_host_address("%5b%3a", "//%5b%3a", host_type::name);
set_host_ipv4("0.0.0.0", "//0.0.0.0");
set_host_ipv4("127.0.0.1", "//127.0.0.1");
set_host_ipv4("255.255.255.255", "//255.255.255.255");
set_host_ipv6("1::6:c0a8:1", "//[1::6:c0a8:1]");
// set_zone_id
{
// Round-trip: set and get zone id
url u;
BOOST_TEST_NO_THROW(u.set_host_ipv6(ipv6_address("fe80::1")));
BOOST_TEST_NO_THROW(u.set_zone_id("eth0"));
BOOST_TEST_EQ(u.host_ipv6_address().to_string(), "fe80::1");
BOOST_TEST_EQ(u.zone_id(), "eth0");
BOOST_TEST_EQ(u.buffer(), "//[fe80::1%25eth0]");
// set_zone_id when no IPv6 host: should create default
// constructed IPv6
url u2;
BOOST_TEST_NO_THROW(u2.set_zone_id("zone42"));
BOOST_TEST_EQ(u2.host_type(), host_type::ipv6);
BOOST_TEST_EQ(u2.zone_id(), "zone42");
BOOST_TEST_EQ(u2.buffer(), "//[::%25zone42]");
// set_encoded_zone_id: round-trip
url u3;
BOOST_TEST_NO_THROW(u3.set_host_ipv6(ipv6_address("fe80::2")));
BOOST_TEST_NO_THROW(u3.set_encoded_zone_id("en%30"));
BOOST_TEST_EQ(u3.zone_id(), "en0");
BOOST_TEST_EQ(u3.encoded_zone_id(), "en%30");
BOOST_TEST_EQ(u3.buffer(), "//[fe80::2%25en%30]");
// set_encoded_zone_id when no IPv6 host: should create default
// constructed IPv6
url u4;
BOOST_TEST_NO_THROW(u4.set_encoded_zone_id("zone%34"));
BOOST_TEST_EQ(u4.host_type(), host_type::ipv6);
BOOST_TEST_EQ(u4.zone_id(), "zone4");
BOOST_TEST_EQ(u4.buffer(), "//[::%25zone%34]");
}
set_host_ipvfuture("v42.69", "//[v42.69]");
BOOST_TEST_THROWS(url().set_host_ipvfuture("127.0.0.1"), system::system_error);
set_host_name("www.example.com", "//www.example.com");
set_host_name("%5b%3a", "//%255b%253a");
set_host_name("127.0.0.1", "//127%2E0%2E0%2E1");
set_encoded_host_name("www.example.com", "//www.example.com");
set_encoded_host_name("%5b%3a", "//%5b%3a");
set_encoded_host_name("127.0.0.1", "//127%2E0%2E0%2E1");
BOOST_TEST_THROWS(url().set_encoded_host_name("%go"), system::system_error);
// self-intersection
modify(
"x://@?www.example.com",
"x://@www.example.com?www.example.com",
[](url_base& u)
{
u.set_encoded_host(
u.encoded_query());
});
modify(
"x://@?www.example.com",
"x://@www.example.com?www.example.com",
[](url_base& u)
{
u.set_host(
u.encoded_query());
});
modify(
"x://@?www.example.com",
"x://@www.example.com?www.example.com",
[](url_base& u)
{
u.set_host(
u.query());
});
{
// issue #755
url u1;
u1.set_scheme("http");
u1.set_host("127.0.0.1.org");
BOOST_TEST_EQ(u1.buffer(), "http://127.0.0.1.org");
BOOST_TEST_EQ(u1.host_type(), host_type::name);
url u2(u1.buffer());
BOOST_TEST_EQ(u2.host_type(), u1.host_type());
BOOST_TEST_EQ(u2.host_type(), host_type::name);
}
}
void
testSetPort()
{
auto const remove = [](
core::string_view s1, core::string_view s2)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST(u.remove_port().buffer() == s2);
BOOST_TEST(! u.has_port());
BOOST_TEST(u.port().empty());
BOOST_TEST_EQ(u.port_number(), 0);
};
auto const setn = [](core::string_view s1,
std::uint16_t n, core::string_view s2)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST(u.set_port_number(n).buffer() == s2);
BOOST_TEST(u.has_port());
BOOST_TEST_EQ(u.port_number(), n);
};
auto const set = [](core::string_view s1,
std::uint16_t n, core::string_view s2,
core::string_view s3)
{
url u;
BOOST_TEST_NO_THROW(u = url(s1));
BOOST_TEST(u.set_port(s2).buffer() == s3);
BOOST_TEST(u.has_port());
BOOST_TEST_EQ(u.port_number(), n);
BOOST_TEST_EQ(u.port(), s2);
};
BOOST_TEST_THROWS(
url().set_port("x"),
std::exception);
remove("", "");
remove("/", "/");
remove("//", "//");
remove("//:0", "//");
remove("//:80", "//");
remove("//:65535", "//");
remove("//:999999", "//");
remove("//:999999/", "///");
remove("//x:999999/", "//x/");
remove("//a:b@x.y:8080/path/to/file.txt?#",
"//a:b@x.y/path/to/file.txt?#");
remove("x:", "x:");
remove("x:/", "x:/");
remove("x://", "x://");
remove("x://:0", "x://");
remove("x://:80", "x://");
remove("x://:65535", "x://");
remove("x://:999999", "x://");
remove("x://:999999/", "x:///");
remove("x://x:999999/", "x://x/");
remove("x://a:b@x.y:8080/path/to/file.txt?#",
"x://a:b@x.y/path/to/file.txt?#");
setn("", 0, "//:0");
setn("", 443, "//:443");
setn("", 65535, "//:65535");
setn("/", 0, "//:0/");
setn("//", 0, "//:0");
setn("///", 0, "//:0/");
setn("//x/", 0, "//x:0/");
setn("//x/y", 0, "//x:0/y");
setn("//a:b@/y", 0, "//a:b@:0/y");
setn("//a:b@c/y", 0, "//a:b@c:0/y");
setn("//a:b@x.y/path/to/file.txt?#", 8080,
"//a:b@x.y:8080/path/to/file.txt?#");
setn("g:", 0, "g://:0");
setn("g:", 443, "g://:443");
setn("g:", 65535, "g://:65535");
setn("g:/", 0, "g://:0/");
setn("g://", 0, "g://:0");
setn("g:///", 0, "g://:0/");
setn("g://x/", 0, "g://x:0/");
setn("g://x/y", 0, "g://x:0/y");
setn("g://a:b@/y", 0, "g://a:b@:0/y");
setn("g://a:b@c/y", 0, "g://a:b@c:0/y");
setn("g://a:b@x.y/path/to/file.txt?#", 8080,
"g://a:b@x.y:8080/path/to/file.txt?#");
set("", 0, "", "//:");
set("/", 0, "", "//:/");
set("//", 0, "", "//:");
set("///", 0, "", "//:/");
set("//x/", 0, "", "//x:/");
set("//x/y", 0, "", "//x:/y");
set("//a:b@/y", 0, "", "//a:b@:/y");
set("//a:b@c/y", 0, "", "//a:b@c:/y");
set("//a:b@x.y/path/to/file.txt?#", 0, "",
"//a:b@x.y:/path/to/file.txt?#");
set("g:", 0, "", "g://:");
set("g:/", 0, "", "g://:/");
set("g://", 0, "", "g://:");
set("g:///", 0, "", "g://:/");
set("g://x/", 0, "", "g://x:/");
set("g://x/y", 0, "", "g://x:/y");
set("g://a:b@/y", 0, "", "g://a:b@:/y");
set("g://a:b@c/y", 0, "", "g://a:b@c:/y");
set("g://a:b@x.y/path/to/file.txt?#", 0, "",
"g://a:b@x.y:/path/to/file.txt?#");
set("", 0, "0", "//:0");
set("", 443, "443", "//:443");
set("", 65535, "65535", "//:65535");
set("/", 0, "0", "//:0/");
set("//", 0, "0", "//:0");
set("///", 0, "0", "//:0/");
set("//x/", 0, "0", "//x:0/");
set("//x/y", 0, "0", "//x:0/y");
set("//a:b@/y", 0, "0", "//a:b@:0/y");
set("//a:b@c/y", 0, "0", "//a:b@c:0/y");
set("//a:b@x.y/path/to/file.txt?#", 8080, "8080",
"//a:b@x.y:8080/path/to/file.txt?#");
set("g:", 0, "0", "g://:0");
set("g:", 443, "443", "g://:443");
set("g:", 65535, "65535", "g://:65535");
set("g:/", 0, "0", "g://:0/");
set("g://", 0, "0", "g://:0");
set("g:///", 0, "0", "g://:0/");
set("g://x/", 0, "0", "g://x:0/");
set("g://x/y", 0, "0", "g://x:0/y");
set("g://a:b@/y", 0, "0", "g://a:b@:0/y");
set("g://a:b@c/y", 0, "0", "g://a:b@c:0/y");
set("g://a:b@x.y/path/to/file.txt?#", 8080, "8080",
"g://a:b@x.y:8080/path/to/file.txt?#");
// self-intersection
modify(
"x://@?65535",
"x://@:65535?65535",
[](url_base& u)
{
u.set_port(u.encoded_query());
});
}
//--------------------------------------------
void
testQuery()
{
// has_query
{
{
url u;
BOOST_TEST(! u.has_query());
}
{
url u("?");
BOOST_TEST(u.has_query());
}
{
url u("?x");
BOOST_TEST(u.has_query());
}
}
// set_encoded_query
{
{
url u;
u.set_encoded_query("");
BOOST_TEST(u.has_query());
BOOST_TEST_EQ(u.buffer(), "?");
BOOST_TEST_EQ(u.encoded_query(), "");
}
{
url u;
u.set_encoded_query("x");
BOOST_TEST(u.has_query());
BOOST_TEST_EQ(u.buffer(), "?x");
BOOST_TEST_EQ(u.encoded_query(), "x");
}
{
url u;
u.set_encoded_query("%41");
BOOST_TEST(u.has_query());
BOOST_TEST_EQ(u.buffer(), "?%41");
BOOST_TEST_EQ(u.encoded_query(), "%41");
BOOST_TEST_EQ(u.query(), "A");
}
{
url u;
BOOST_TEST_THROWS(
u.set_encoded_query("%%"),
system::system_error);
BOOST_TEST_THROWS(
u.set_encoded_query("%fg"),
system::system_error);
}
}
// set_query
{
auto good = [](
core::string_view q, core::string_view us)
{
url u;
u.set_query(q);
BOOST_TEST(u.has_query());
BOOST_TEST_EQ(u.buffer(), us);
BOOST_TEST_EQ(u.query(), q);
};
good("", "?");
good("x", "?x");
good("%41", "?%2541");
good("%%fg", "?%25%25fg");
good("{}", "?%7B%7D");
// issue #245
{
url u;
u.set_query("");
u.set_query("");
BOOST_TEST_EQ(u.buffer(), "?");
}
}
// has_query
{
url u;
BOOST_TEST_NO_THROW(u = url("?query"));
BOOST_TEST(u.has_query());
u.clear();
BOOST_TEST(! u.has_query());
BOOST_TEST_NO_THROW(u = url("?"));
BOOST_TEST(u.has_query());
}
// remove_query
{
url u;
BOOST_TEST_NO_THROW(u = url("?query"));
BOOST_TEST(u.has_query());
BOOST_TEST_EQ(u.encoded_query(), "query");
BOOST_TEST_EQ(u.params().size(), 1u);
BOOST_TEST_EQ(u.remove_query().has_query(), false);
BOOST_TEST_EQ(u.encoded_query(), "");
BOOST_TEST_EQ(u.query(), "");
BOOST_TEST_EQ(u.params().size(), 0u);
BOOST_TEST_EQ(u.encoded_params().size(), 0u);
}
// set_encoded_query
{
url u;
BOOST_TEST(! u.has_query());
u.set_encoded_query("k1=v1&k2=#v2");
BOOST_TEST(u.has_query());
BOOST_TEST_EQ(u.params().size(), 2u);
BOOST_TEST_EQ((*u.params().begin()).key, "k1");
BOOST_TEST_EQ((*u.params().begin()).value, "v1");
BOOST_TEST_EQ((*std::next(u.params().begin())).key, "k2");
BOOST_TEST_EQ((*std::next(u.params().begin())).value, "#v2");
u.set_encoded_query("");
BOOST_TEST(u.has_query());
BOOST_TEST(u.encoded_query().empty());
BOOST_TEST_EQ(u.params().size(), 1);
}
// set_query
{
url u;
BOOST_TEST(! u.has_query());
u.set_query("!@#$%^&*()_+=-;:'{}[]|\\?/>.<,");
BOOST_TEST(u.has_query());
BOOST_TEST(u.encoded_query() ==
"!@%23$%25%5E&*()_+=-;:'%7B%7D[]%7C%5C?/%3E.%3C,");
BOOST_TEST_EQ(u.params().size(), 2u);
BOOST_TEST_EQ((*u.params().begin()).key, "!@#$%^");
BOOST_TEST_EQ((*u.params().begin()).value, "");
BOOST_TEST_EQ((*std::next(u.params().begin())).key, "*()_ ");
BOOST_TEST_EQ((*std::next(u.params().begin())).value,
"-;:'{}[]|\\?/>.<,");
}
// remove_query
{
{
url u;
u.remove_query();
BOOST_TEST(! u.has_query());
}
{
url u("?");
u.remove_query();
BOOST_TEST(! u.has_query());
}
{
url u("?x");
u.remove_query();
BOOST_TEST(! u.has_query());
}
}
// self-intersection
modify(
"#abracadabra",
"?abracadabra#abracadabra",
[](url_base& u)
{
u.set_encoded_query(
u.encoded_fragment());
});
modify(
"#abracadabra",
"?abracadabra#abracadabra",
[](url_base& u)
{
u.set_query(
u.encoded_fragment());
});
}
void
testJavadocs()
{
//----------------------------------------
//
// Scheme
//
//----------------------------------------
// set_scheme
assert( url( "http://www.example.com" ).set_scheme( "https" ).scheme_id() == scheme::https );
// set_scheme_id
assert( url( "http://example.com/echo.cgi" ).set_scheme_id( scheme::wss ).buffer() == "wss://example.com/echo.cgi" );
// remove_scheme
assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" );
//----------------------------------------
//
// Authority
//
//----------------------------------------
// set_encoded_authority
assert( url().set_encoded_authority( "My%20Computer" ).has_authority() );
// remove_authority
assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" );
//----------------------------------------
//
// Userinfo
//
//----------------------------------------
// set_userinfo
assert( url( "http://example.com" ).set_userinfo( "user:pass" ).encoded_user() == "user" );
// set_encoded_userinfo
assert( url( "http://example.com" ).set_encoded_userinfo( "john%20doe" ).user() == "john doe" );
// remove_userinfo
assert( url( "http://user@example.com" ).remove_userinfo().has_userinfo() == false );
//----------------------------------------
// set_user
assert( url().set_user("john doe").encoded_userinfo() == "john%20doe" );
// set_encoded_user
assert( url().set_encoded_user("john%20doe").userinfo() == "john doe" );
// set_password
assert( url("http://user@example.com").set_password( "pass" ).encoded_userinfo() == "user:pass" );
// set_encoded_password
assert( url("http://user@example.com").set_encoded_password( "pass" ).encoded_userinfo() == "user:pass" );
// remove_password
assert( url( "http://user:pass@example.com" ).remove_password().encoded_authority() == "user@example.com" );
//----------------------------------------
//
// Host
//
//----------------------------------------
// set_host
assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
// set_encoded_host
assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
// set_host_address
assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
// set_encoded_host_address
assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
// set_host_ipv4
assert( url("http://www.example.com").set_host_ipv4( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" );
// set_host_ipv6
assert( url().set_host_ipv6( ipv6_address( "1::6:c0a8:1" ) ).encoded_authority() == "[1::6:c0a8:1]" );
// set_host_ipvfuture
assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" );
// set_host_name
assert( url( "http://www.example.com/index.htm").set_host_name( "localhost" ).host_address() == "localhost" );
// set_encoded_host_name
assert( url( "http://www.example.com/index.htm").set_encoded_host_name( "localhost" ).host_address() == "localhost" );
//----------------------------------------
//
// Port
//
//----------------------------------------
// set_port
assert( url( "http://www.example.com" ).set_port_number( 8080 ).encoded_authority() == "www.example.com:8080" );
// set_port
assert( url( "http://www.example.com" ).set_port( "8080" ).encoded_authority() == "www.example.com:8080" );
// remove_port
assert( url( "http://www.example.com:80" ).remove_port().encoded_authority() == "www.example.com" );
//----------------------------------------
//
// Path
//
//----------------------------------------
// set_path_absolute
{
url u( "path/to/file.txt" );
assert( u.set_path_absolute( true ) );
assert( u.buffer() == "/path/to/file.txt" );
}
// set_path
{
url u( "http://www.example.com" );
u.set_path( "path/to/file.txt" );
assert( u.path() == "/path/to/file.txt" );
}
// set_encoded_path
{
url u( "http://www.example.com" );
u.set_encoded_path( "path/to/file.txt" );
assert( u.encoded_path() == "/path/to/file.txt" );
}
// segments
{
url u( "http://example.com/path/to/file.txt" );
segments_ref sv = u.segments();
(void)sv;
}
// encoded_segments
{
url u( "http://example.com/path/to/file.txt" );
segments_encoded_ref sv = u.encoded_segments();
(void)sv;
}
//----------------------------------------
//
// Query
//
//----------------------------------------
// set_query
assert( url( "http://example.com" ).set_query( "id=42" ).query() == "id=42" );
// set_encoded_query
assert( url( "http://example.com" ).set_encoded_query( "id=42" ).encoded_query() == "id=42" );
// params
{
params_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
(void)pv;
}
// encoded_params
{
params_encoded_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
(void)pv;
}
// set_params
assert( url( "http://example.com" ).set_params( {{"id", "42"}} ).encoded_query() == "id=42" );
// set_encoded_params
assert( url( "http://example.com" ).set_encoded_params( {{"id", "42"}} ).encoded_query() == "id=42" );
// remove_query
assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" );
//----------------------------------------
//
// Fragment
//
//----------------------------------------
// remove_fragment
assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" );
// set_fragment
assert( url("?first=john&last=doe" ).set_encoded_fragment( "john doe" ).encoded_fragment() == "john%20doe" );
// set_encoded_fragment
assert( url("?first=john&last=doe" ).set_encoded_fragment( "john%2Ddoe" ).fragment() == "john-doe" );
//----------------------------------------
//
// Compound Fields
//
//----------------------------------------
// remove_origin
assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" );
}
void
run()
{
testSetScheme();
testSetAuthority();
testSetUserinfo();
testSetUser();
testSetPassword();
testSetHost();
testSetPort();
testQuery();
testJavadocs();
}
};
TEST_SUITE(
url_base_test,
"boost.url.url_base");
} // urls
} // boost