// // 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 #include #include #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 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