Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 50 additions & 19 deletions djangoproject/urls/docs.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from collections.abc import MutableMapping

from django.conf import settings
from django.contrib.sitemaps.views import sitemap
from django.http import HttpResponse
from django.urls import include, path
from django.http import HttpResponse, HttpResponsePermanentRedirect
from django.urls import include, path, re_path
from django.views import View

from docs.models import DocumentRelease
from docs.sitemaps import DocsSitemap
Expand Down Expand Up @@ -41,21 +43,50 @@ def __setitem__(key, value):

sitemaps = Sitemaps()

urlpatterns = docs_urlpatterns + [
path("sitemap.xml", sitemap_index, {"sitemaps": sitemaps}),
path(
"sitemap-<section>.xml",
sitemap,
{"sitemaps": sitemaps},
name="document-sitemap",
),
path(
"google79eabba6bf6fd6d3.html",
lambda req: HttpResponse(
"google-site-verification: google79eabba6bf6fd6d3.html"

class WwwRedirectView(View):
"""
Redirect requests to the www subdomain, preserving the path.

This is used to redirect non-documentation pages (like /foundation/ and
/community/) that are incorrectly accessible on docs.djangoproject.com
to their canonical location on www.djangoproject.com.
"""

def get(self, request, *args, **kwargs):
scheme = getattr(settings, "HOST_SCHEME", "https")
parent_host = getattr(settings, "PARENT_HOST", "djangoproject.com")
redirect_url = f"{scheme}://www.{parent_host}{request.path}"
if request.META.get("QUERY_STRING"):
redirect_url = f"{redirect_url}?{request.META['QUERY_STRING']}"
return HttpResponsePermanentRedirect(redirect_url)


urlpatterns = (
[
# Redirect non-documentation pages to the www subdomain.
# These pages should not be accessible on docs.djangoproject.com.
# See https://github.com/django/djangoproject.com/issues/878
re_path(r"^foundation(?:/(?P<path>.*))?$", WwwRedirectView.as_view()),
re_path(r"^community(?:/(?P<path>.*))?$", WwwRedirectView.as_view()),
]
+ docs_urlpatterns
+ [
path("sitemap.xml", sitemap_index, {"sitemaps": sitemaps}),
path(
"sitemap-<section>.xml",
sitemap,
{"sitemaps": sitemaps},
name="document-sitemap",
),
path(
"google79eabba6bf6fd6d3.html",
lambda req: HttpResponse(
"google-site-verification: google79eabba6bf6fd6d3.html"
),
),
),
# This just exists to make sure we can proof that the error pages work
# under both hostnames.
path("", include("legacy.urls")),
]
# This just exists to make sure we can proof that the error pages work
# under both hostnames.
path("", include("legacy.urls")),
]
)
66 changes: 66 additions & 0 deletions docs/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,72 @@ def test_internals_team(self):
fetch_redirect_response=False,
)

def test_foundation_redirects_to_www(self):
"""Foundation pages on docs subdomain should redirect to www."""
response = self.client.get(
"/foundation/",
headers={"host": "docs.djangoproject.localhost:8000"},
)
self.assertRedirects(
response,
"http://www.djangoproject.localhost:8000/foundation/",
status_code=HTTPStatus.MOVED_PERMANENTLY,
fetch_redirect_response=False,
)

def test_foundation_subpage_redirects_to_www(self):
"""Foundation subpages on docs subdomain should redirect to www."""
response = self.client.get(
"/foundation/records/minutes/2017-02-09/",
headers={"host": "docs.djangoproject.localhost:8000"},
)
self.assertRedirects(
response,
"http://www.djangoproject.localhost:8000"
"/foundation/records/minutes/2017-02-09/",
status_code=HTTPStatus.MOVED_PERMANENTLY,
fetch_redirect_response=False,
)

def test_community_redirects_to_www(self):
"""Community pages on docs subdomain should redirect to www."""
response = self.client.get(
"/community/",
headers={"host": "docs.djangoproject.localhost:8000"},
)
self.assertRedirects(
response,
"http://www.djangoproject.localhost:8000/community/",
status_code=HTTPStatus.MOVED_PERMANENTLY,
fetch_redirect_response=False,
)

def test_community_subpage_redirects_to_www(self):
"""Community subpages on docs subdomain should redirect to www."""
response = self.client.get(
"/community/logos/",
headers={"host": "docs.djangoproject.localhost:8000"},
)
self.assertRedirects(
response,
"http://www.djangoproject.localhost:8000/community/logos/",
status_code=HTTPStatus.MOVED_PERMANENTLY,
fetch_redirect_response=False,
)

def test_redirect_preserves_query_string(self):
"""Redirects should preserve query strings."""
response = self.client.get(
"/foundation/?page=2&sort=date",
headers={"host": "docs.djangoproject.localhost:8000"},
)
self.assertRedirects(
response,
"http://www.djangoproject.localhost:8000/foundation/?page=2&sort=date",
status_code=HTTPStatus.MOVED_PERMANENTLY,
fetch_redirect_response=False,
)


class SearchFormTestCase(TestCase):
fixtures = ["doc_test_fixtures"]
Expand Down