2
0
mirror of https://github.com/boostorg/url.git synced 2026-02-01 09:02:11 +00:00

userinfo work

This commit is contained in:
Vinnie Falco
2021-09-06 08:31:13 -07:00
parent 43640403ac
commit b774bdbaba
7 changed files with 142 additions and 74 deletions

View File

@@ -165,7 +165,7 @@ has_userinfo() const noexcept
bool
url_view::
has_user() const noexcept
has_username() const noexcept
{
auto const n = len(
detail::id_user);
@@ -209,7 +209,7 @@ encoded_userinfo() const noexcept
string_view
url_view::
encoded_user() const noexcept
encoded_username() const noexcept
{
auto s = pt_.get(
detail::id_user,
@@ -819,11 +819,11 @@ apply_authority(parts& p,
{
p.resize(
part::id_user,
u->user.str.size() + 2);
if(u->pass.has_value())
u->username.str.size() + 2);
if(u->password.has_value())
p.resize(
part::id_password,
u->pass->str.size() + 2);
u->password->str.size() + 2);
else
p.resize(
part::id_password, 1);

View File

@@ -45,11 +45,11 @@ parse(
return false;
t.str = string_view(
start, it - start);
t.user = user;
t.username = user;
if(colon.has_value())
t.pass = pass;
t.password = pass;
else
t.pass.reset();
t.password.reset();
return true;
}

View File

@@ -24,9 +24,9 @@ namespace rfc {
@par BNF
@code
userinfo = user [ ":" [ password ] ]
userinfo = username [ ":" [ password ] ]
user = *( unreserved / pct-encoded / sub-delims )
username = *( unreserved / pct-encoded / sub-delims )
password = *( unreserved / pct-encoded / sub-delims / ":" )
@endcode
@@ -36,9 +36,8 @@ namespace rfc {
struct userinfo_bnf
{
string_view str;
pct_encoded_str user;
optional<
pct_encoded_str> pass;
pct_encoded_str username;
optional<pct_encoded_str> password;
BOOST_URL_DECL
friend

View File

@@ -133,7 +133,7 @@ public:
/** Return the userinfo if present, or an empty string
Returns the userinfo of the URL as an encoded
string. The userinfo includes the user and
string. The userinfo includes the username and
password, with a colon separating the components
if the password is not empty.
@@ -145,17 +145,46 @@ public:
string_view
encoded_userinfo() const noexcept;
/** Return true if the URL contains a user
/** Return the userinfo if present, or an empty string
This function returns the userinfo part
of the URL if present, as a decoded string.
@par Exception Safety
Strong guarantee.
Calls to allocate may throw.
@param a An optional allocator the returned
string will use. If this parameter is omitted,
the default allocator is used, and the return
type of the function becomes `std::string`.
@return A `std::basic_string` using the
specified allocator.
*/
template<
class Allocator =
std::allocator<char>>
string_type<Allocator>
userinfo(
Allocator const& a = {}) const
{
return detail::decode(
encoded_userinfo(), a);
}
/** Return true if the URL contains a username
*/
BOOST_URL_DECL
bool
has_user() const noexcept;
has_username() const noexcept;
/** Return the user if present, or an empty string
/** Return the username if present, or an empty string
This function returns the user portion of
This function returns the username portion of
the userinfo if present, as an encoded string.
The user portion is defined by all of the
The username portion is defined by all of the
characters in the userinfo up to but not
including the first colon (':"), or the
entire userinfo if no colon is present.
@@ -166,13 +195,13 @@ public:
*/
BOOST_URL_DECL
string_view
encoded_user() const noexcept;
encoded_username() const noexcept;
/** Return the user if present, or an empty string
/** Return the username if present, or an empty string
This function returns the user portion of
This function returns the username portion of
the userinfo if present, as a decoded string.
The user portion is defined by all of the
The username portion is defined by all of the
characters in the userinfo up to but not
including the first colon (':"), or the
entire userinfo if no colon is present.
@@ -194,11 +223,11 @@ public:
class Allocator =
std::allocator<char>>
string_type<Allocator>
user(
username(
Allocator const& a = {}) const
{
return detail::decode(
encoded_user(), a);
encoded_username(), a);
}
/** Return true if the URL contains a password
@@ -226,6 +255,8 @@ public:
encoded_password(), a);
}
//--------------------------------------------
/** Return the type of host present, if any.
@par Exception Safety

View File

@@ -55,9 +55,9 @@ public:
if(BOOST_TEST(p.userinfo.has_value()))
{
BOOST_TEST(p.userinfo->str == "x:y");
BOOST_TEST(p.userinfo->user.str == "x");
if(BOOST_TEST(p.userinfo->pass.has_value()))
BOOST_TEST(p.userinfo->pass->str == "y");
BOOST_TEST(p.userinfo->username.str == "x");
if(BOOST_TEST(p.userinfo->password.has_value()))
BOOST_TEST(p.userinfo->password->str == "y");
}
}
}

View File

@@ -38,13 +38,13 @@ public:
if(! BOOST_TEST(! ec))
return;
BOOST_TEST(p.str == s);
BOOST_TEST(p.user.str == s1);
BOOST_TEST(p.username.str == s1);
if(s2.has_value())
BOOST_TEST(
p.pass.has_value() &&
p.pass->str == *s2);
p.password.has_value() &&
p.password->str == *s2);
else
BOOST_TEST(! p.pass.has_value());
BOOST_TEST(! p.password.has_value());
}
void

View File

@@ -36,14 +36,14 @@ public:
BOOST_TEST(url_view("//example.com").host_type() == host_type::name);
BOOST_TEST(url_view("//127.0.0.1.9").host_type() == host_type::name);
url_view const v("http://user:pass@example.com:80/path/to/file.txt?k1=v1&k2=v2");
BOOST_TEST(v.encoded_url() == "http://user:pass@example.com:80/path/to/file.txt?k1=v1&k2=v2");
BOOST_TEST(v.encoded_origin() == "http://user:pass@example.com:80");
BOOST_TEST(v.encoded_authority() == "user:pass@example.com:80");
url_view const v("http://username:pass@example.com:80/path/to/file.txt?k1=v1&k2=v2");
BOOST_TEST(v.encoded_url() == "http://username:pass@example.com:80/path/to/file.txt?k1=v1&k2=v2");
BOOST_TEST(v.encoded_origin() == "http://username:pass@example.com:80");
BOOST_TEST(v.encoded_authority() == "username:pass@example.com:80");
BOOST_TEST(v.scheme() == "http");
BOOST_TEST(v.encoded_user() == "user");
BOOST_TEST(v.encoded_username() == "username");
BOOST_TEST(v.encoded_password() == "pass");
BOOST_TEST(v.encoded_userinfo() == "user:pass");
BOOST_TEST(v.encoded_userinfo() == "username:pass");
BOOST_TEST(v.encoded_host() == "example.com");
BOOST_TEST(v.has_port());
BOOST_TEST(v.port() == "80");
@@ -52,7 +52,7 @@ public:
BOOST_TEST(v.encoded_query() == "k1=v1&k2=v2");
BOOST_TEST(v.encoded_fragment() == "");
BOOST_TEST(v.user() == "user");
BOOST_TEST(v.username() == "username");
BOOST_TEST(v.password() == "pass");
BOOST_TEST(v.host() == "example.com");
BOOST_TEST(v.query() == "k1=v1&k2=v2");
@@ -64,25 +64,25 @@ public:
void
testUser()
{
BOOST_TEST(url_view().user() == "");
BOOST_TEST(url_view("//x/").user() == "");
BOOST_TEST(url_view("//x@/").user() == "x");
BOOST_TEST(url_view("//x:@/").user() == "x");
BOOST_TEST(url_view("//x:y@/").user() == "x");
BOOST_TEST(url_view("//:y@/").user() == "");
BOOST_TEST(url_view("//:@/").user() == "");
BOOST_TEST(url_view("//@/").user() == "");
BOOST_TEST(url_view("//%3A@/").user() == ":");
BOOST_TEST(url_view().username() == "");
BOOST_TEST(url_view("//x/").username() == "");
BOOST_TEST(url_view("//x@/").username() == "x");
BOOST_TEST(url_view("//x:@/").username() == "x");
BOOST_TEST(url_view("//x:y@/").username() == "x");
BOOST_TEST(url_view("//:y@/").username() == "");
BOOST_TEST(url_view("//:@/").username() == "");
BOOST_TEST(url_view("//@/").username() == "");
BOOST_TEST(url_view("//%3A@/").username() == ":");
BOOST_TEST(url_view().encoded_user() == "");
BOOST_TEST(url_view("//x/").encoded_user() == "");
BOOST_TEST(url_view("//x@/").encoded_user() == "x");
BOOST_TEST(url_view("//x:@/").encoded_user() == "x");
BOOST_TEST(url_view("//x:y@/").encoded_user() == "x");
BOOST_TEST(url_view("//:y@/").encoded_user() == "");
BOOST_TEST(url_view("//:@/").encoded_user() == "");
BOOST_TEST(url_view("//@/").encoded_user() == "");
BOOST_TEST(url_view("//%3A@/").encoded_user() == "%3A");
BOOST_TEST(url_view().encoded_username() == "");
BOOST_TEST(url_view("//x/").encoded_username() == "");
BOOST_TEST(url_view("//x@/").encoded_username() == "x");
BOOST_TEST(url_view("//x:@/").encoded_username() == "x");
BOOST_TEST(url_view("//x:y@/").encoded_username() == "x");
BOOST_TEST(url_view("//:y@/").encoded_username() == "");
BOOST_TEST(url_view("//:@/").encoded_username() == "");
BOOST_TEST(url_view("//@/").encoded_username() == "");
BOOST_TEST(url_view("//%3A@/").encoded_username() == "%3A");
}
//------------------------------------------------------
@@ -432,61 +432,99 @@ public:
auto u = parse_uri("x://@");
BOOST_TEST(u.has_userinfo());
BOOST_TEST(u.encoded_userinfo() == "");
BOOST_TEST(u.has_user() == false);
BOOST_TEST(u.encoded_user() == "");
BOOST_TEST(u.userinfo() == "");
BOOST_TEST(u.has_username() == false);
BOOST_TEST(u.encoded_username() == "");
BOOST_TEST(u.username() == "");
BOOST_TEST(u.has_password() == false);
BOOST_TEST(u.encoded_password() == "");
BOOST_TEST(u.password() == "");
}
{
auto u = parse_uri("x://:@");
BOOST_TEST(u.has_userinfo());
BOOST_TEST(u.encoded_userinfo() == ":");
BOOST_TEST(u.has_user() == false);
BOOST_TEST(u.encoded_user() == "");
BOOST_TEST(u.userinfo() == ":");
BOOST_TEST(u.has_username() == false);
BOOST_TEST(u.encoded_username() == "");
BOOST_TEST(u.username() == "");
BOOST_TEST(u.has_password() == true);
BOOST_TEST(u.encoded_password() == "");
BOOST_TEST(u.password() == "");
}
{
auto u = parse_uri("x://a:@");
auto u = parse_uri("x://a%41:@");
BOOST_TEST(u.has_userinfo());
BOOST_TEST(u.encoded_userinfo() == "a:");
BOOST_TEST(u.has_user() == true);
BOOST_TEST(u.encoded_user() == "a");
BOOST_TEST(u.encoded_userinfo() == "a%41:");
BOOST_TEST(u.has_username() == true);
BOOST_TEST(u.encoded_username() == "a%41");
BOOST_TEST(u.username() == "aA");
BOOST_TEST(u.has_password() == true);
BOOST_TEST(u.encoded_password() == "");
BOOST_TEST(u.password() == "");
}
{
auto u = parse_uri("x://:b@");
auto u = parse_uri("x://:b%42@");
BOOST_TEST(u.has_userinfo());
BOOST_TEST(u.encoded_userinfo() == ":b");
BOOST_TEST(u.has_user() == false);
BOOST_TEST(u.encoded_user() == "");
BOOST_TEST(u.encoded_userinfo() == ":b%42");
BOOST_TEST(u.has_username() == false);
BOOST_TEST(u.encoded_username() == "");
BOOST_TEST(u.username() == "");
BOOST_TEST(u.has_password() == true);
BOOST_TEST(u.encoded_password() == "b");
BOOST_TEST(u.encoded_password() == "b%42");
BOOST_TEST(u.password() == "bB");
}
{
auto u = parse_uri("x://a:b@");
BOOST_TEST(u.has_userinfo());
BOOST_TEST(u.encoded_userinfo() == "a:b");
BOOST_TEST(u.has_user() == true);
BOOST_TEST(u.encoded_user() == "a");
BOOST_TEST(u.has_username() == true);
BOOST_TEST(u.encoded_username() == "a");
BOOST_TEST(u.has_password() == true);
BOOST_TEST(u.encoded_password() == "b");
}
{
auto u = parse_uri("x://%3a:%3a@");
BOOST_TEST(u.has_userinfo());
BOOST_TEST(u.encoded_userinfo() == "%3a:%3a");
BOOST_TEST(u.userinfo() == ":::");
BOOST_TEST(u.has_username() == true);
BOOST_TEST(u.encoded_username() == "%3a");
BOOST_TEST(u.username() == ":");
BOOST_TEST(u.has_password() == true);
BOOST_TEST(u.encoded_password() == "%3a");
BOOST_TEST(u.password() == ":");
}
{
auto u = parse_uri("x://%2525@");
BOOST_TEST(u.has_userinfo());
BOOST_TEST(u.encoded_userinfo() == "%2525");
BOOST_TEST(u.userinfo() == "%25");
BOOST_TEST(u.has_username() == true);
BOOST_TEST(u.encoded_username() == "%2525");
BOOST_TEST(u.username() == "%25");
BOOST_TEST(u.has_password() == false);
BOOST_TEST(u.encoded_password() == "");
BOOST_TEST(u.password() == "");
}
}
//--------------------------------------------
//--------------------------------------------
void
testParseUri()
{
error_code ec;
auto const u = urls::parse_uri(
"http://user:pass@www.boost.org:8080/x/y/z?a=b&c=3#frag",
"http://username:pass@www.boost.org:8080/x/y/z?a=b&c=3#frag",
ec);
if(! BOOST_TEST(! ec))
return;
BOOST_TEST(u.has_value());
BOOST_TEST(u->scheme() == "http");
BOOST_TEST(u->user() == "user");
BOOST_TEST(u->username() == "username");
BOOST_TEST(u->password() == "pass");
BOOST_TEST(u->host() == "www.boost.org");
BOOST_TEST(u->port() == "8080");