Skip to content

Commit

Permalink
Redirects: fix root redirect (/ -> <anything>) (#11265)
Browse files Browse the repository at this point in the history
The rstrip call was removing the whole path for `/`,
we need to preserve the leading `/` in the path.
  • Loading branch information
stsewd committed Apr 4, 2024
1 parent 72fe35d commit 0c600a6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
45 changes: 45 additions & 0 deletions readthedocs/proxito/tests/test_old_redirects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,51 @@ def test_redirect_with_301_status(self):
"http://project.dev.readthedocs.io/en/latest/tutorial/install.html",
)

def test_page_root_redirect(self):
fixture.get(
Redirect,
project=self.project,
redirect_type=PAGE_REDIRECT,
from_url="/",
to_url="https://example.com/",
force=True,
)
r = self.client.get(
"/en/latest/", headers={"host": "project.dev.readthedocs.io"}
)
self.assertEqual(r.status_code, 302)
self.assertEqual(r["Location"], "https://example.com/")

def test_exact_root_redirect_single_version(self):
self.project.versioning_scheme = SINGLE_VERSION_WITHOUT_TRANSLATIONS
self.project.save()
fixture.get(
Redirect,
project=self.project,
redirect_type=EXACT_REDIRECT,
from_url="/",
to_url="https://example.com/",
force=True,
)
r = self.client.get("/", headers={"host": "project.dev.readthedocs.io"})
self.assertEqual(r.status_code, 302)
self.assertEqual(r["Location"], "https://example.com/")

def test_page_root_redirect_single_version(self):
self.project.versioning_scheme = SINGLE_VERSION_WITHOUT_TRANSLATIONS
self.project.save()
fixture.get(
Redirect,
project=self.project,
redirect_type=PAGE_REDIRECT,
from_url="/",
to_url="https://example.com/",
force=True,
)
r = self.client.get("/", headers={"host": "project.dev.readthedocs.io"})
self.assertEqual(r.status_code, 302)
self.assertEqual(r["Location"], "https://example.com/")


@override_settings(
PYTHON_MEDIA=True,
Expand Down
13 changes: 11 additions & 2 deletions readthedocs/redirects/querysets.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ def get_matching_redirect_with_path(

# Useful to allow redirects to match paths with or without trailling slash.
# For example, ``/docs`` will match ``/docs/`` and ``/docs``.
filename_without_trailling_slash = normalized_filename.rstrip("/")
path_without_trailling_slash = normalized_path.rstrip("/")
filename_without_trailling_slash = self._strip_trailling_slash(
normalized_filename
)
path_without_trailling_slash = self._strip_trailling_slash(normalized_path)

# Add extra fields with the ``filename`` and ``path`` to perform a
# filter at db level instead with Python.
Expand Down Expand Up @@ -154,3 +156,10 @@ def _normalize_path(self, path):
normalized_path = parsed_path._replace(query="").geturl()
normalized_path = "/" + normalized_path.lstrip("/")
return normalized_path

def _strip_trailling_slash(self, path):
"""Stripe the trailling slash from the path, making sure the root path is always ``/``."""
path = path.rstrip("/")
if path == "":
return "/"
return path

0 comments on commit 0c600a6

Please sign in to comment.