Allow URLs where username or password contains unescaped '@'. (#2986)

* Add test cases for userinfo in URL

* Resolve failing test cases

* Update CHANGELOG.md

* Update CHANGELOG.md
This commit is contained in:
Tom Christie 2023-12-07 10:08:14 +00:00 committed by GitHub
parent 5b5f6d8e17
commit b471f01d66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 2 deletions

View File

@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased
### Fixed
* Allow URLs where username or password contains unescaped '@'. (#2986)
## 0.25.2 (24th November, 2023)
### Added

View File

@ -62,8 +62,8 @@ AUTHORITY_REGEX = re.compile(
(
r"(?:(?P<userinfo>{userinfo})@)?" r"(?P<host>{host})" r":?(?P<port>{port})?"
).format(
userinfo="[^@]*", # Any character sequence not including '@'.
host="(\\[.*\\]|[^:]*)", # Either any character sequence not including ':',
userinfo=".*", # Any character sequence.
host="(\\[.*\\]|[^:@]*)", # Either any character sequence excluding ':' or '@',
# or an IPv6 address enclosed within square brackets.
port=".*", # Any character sequence.
)

View File

@ -132,6 +132,54 @@ def test_url_params():
assert url.params == httpx.QueryParams({"a": "123"})
# Tests for username and password
@pytest.mark.parametrize(
"url,userinfo,username,password",
[
# username and password in URL.
(
"https://username:password@example.com",
b"username:password",
"username",
"password",
),
# username and password in URL with percent escape sequences.
(
"https://username%40gmail.com:pa%20ssword@example.com",
b"username%40gmail.com:pa%20ssword",
"username@gmail.com",
"pa ssword",
),
(
"https://user%20name:p%40ssword@example.com",
b"user%20name:p%40ssword",
"user name",
"p@ssword",
),
# username and password in URL without percent escape sequences.
(
"https://username@gmail.com:pa ssword@example.com",
b"username%40gmail.com:pa%20ssword",
"username@gmail.com",
"pa ssword",
),
(
"https://user name:p@ssword@example.com",
b"user%20name:p%40ssword",
"user name",
"p@ssword",
),
],
)
def test_url_username_and_password(url, userinfo, username, password):
url = httpx.URL(url)
assert url.userinfo == userinfo
assert url.username == username
assert url.password == password
# Tests for different host types