Skip to content

Commit bbe0343

Browse files
committed
Unresolver: allow a full URL when un-resolving a domain
This also checks that the URL has a valid protocol.
1 parent 794b58b commit bbe0343

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

readthedocs/core/unresolver.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def unresolve_url(self, url, append_indexhtml=True):
208208
parsed_url = urlparse(url)
209209
if parsed_url.scheme not in ["http", "https"]:
210210
raise InvalidSchemeError(parsed_url.scheme)
211-
domain = self.get_domain_from_host(parsed_url.netloc)
211+
domain = parsed_url.hostname
212212
unresolved_domain = self.unresolve_domain(domain)
213213
return self._unresolve(
214214
unresolved_domain=unresolved_domain,
@@ -551,8 +551,15 @@ def unresolve_domain(self, domain):
551551
Unresolve domain by extracting relevant information from it.
552552
553553
:param str domain: Domain to extract the information from.
554+
It can be a full URL, in that case, only the domain is used.
554555
:returns: A UnresolvedDomain object.
555556
"""
557+
parsed_domain = urlparse(domain)
558+
if parsed_domain.scheme:
559+
if parsed_domain.scheme not in ["http", "https"]:
560+
raise InvalidSchemeError(parsed_domain.scheme)
561+
domain = parsed_domain.hostname
562+
556563
public_domain = self.get_domain_from_host(settings.PUBLIC_DOMAIN)
557564
external_domain = self.get_domain_from_host(
558565
settings.RTD_EXTERNAL_VERSION_DOMAIN

readthedocs/rtd_tests/tests/test_unresolver.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
TranslationWithoutVersionError,
1717
VersionNotFoundError,
1818
unresolve,
19+
unresolver,
1920
)
2021
from readthedocs.projects.constants import SINGLE_VERSION_WITHOUT_TRANSLATIONS
2122
from readthedocs.projects.models import Domain
@@ -372,8 +373,29 @@ def test_unresolve_invalid_scheme(self):
372373
"fttp://pip.readthedocs.io/en/latest/",
373374
"fttps://pip.readthedocs.io/en/latest/",
374375
"ssh://pip.readthedocs.io/en/latest/",
376+
"javascript://pip.readthedocs.io/en/latest/",
375377
"://pip.readthedocs.io/en/latest/",
376378
]
377379
for url in invalid_urls:
378380
with pytest.raises(InvalidSchemeError):
379381
unresolve(url)
382+
383+
def test_unresolve_domain_with_full_url(self):
384+
result = unresolver.unresolve_domain("https://pip.readthedocs.io/en/latest/")
385+
self.assertIsNone(result.domain)
386+
self.assertEqual(result.project, self.pip)
387+
self.assertTrue(result.is_from_public_domain)
388+
self.assertEqual(result.source_domain, "pip.readthedocs.io")
389+
390+
def test_unresolve_domain_with_full_url_invalid_protocol(self):
391+
invalid_protocols = [
392+
"fttp",
393+
"fttps",
394+
"ssh",
395+
"javascript",
396+
]
397+
for protocol in invalid_protocols:
398+
with pytest.raises(InvalidSchemeError):
399+
unresolver.unresolve_domain(
400+
f"{protocol}://pip.readthedocs.io/en/latest/"
401+
)

0 commit comments

Comments
 (0)