Repository: readthedocs/readthedocs.org
Issue: Project domains starting with a number are broken

## Details
Every project domain starting with a number (eg. 54street) doesn't show the documentation but instead `SORRY This page does not exist yet`.

It even happens for projects that do not exist. For example, look at the different behaviour of this two urls where both projects are not existent:

https://street54.readthedocs.io/en/latest/ (returns `Not Found`)
https://54street.readthedocs.io/en/latest/ (returns `SORRY This page does not exist yet`)

## Expected Result
The documentation should be visible at the project's url.

## Actual Result
The error `SORRY This page does not exist yet.` is always returned, even when build is successfull.


Changed files:
readthedocs/proxito/views/serve.py, readthedocs/proxito/tests/test_old_redirects.py, readthedocs/proxito/views/utils.py, readthedocs/proxito/urls.py

diff --git a/readthedocs/proxito/tests/test_old_redirects.py b/readthedocs/proxito/tests/test_old_redirects.py
index 517ee571a..6ef80bad3 100644
--- a/readthedocs/proxito/tests/test_old_redirects.py
+++ b/readthedocs/proxito/tests/test_old_redirects.py
@@ -11,6 +11,7 @@ and adapted to use:
 
 import django_dynamic_fixture as fixture
 import pytest
+from django.http import Http404
 from django.urls import reverse
 from django.test.utils import override_settings
 
@@ -201,11 +202,11 @@ class UserRedirectTests(MockStorageMixin, BaseDocServing):
             'http://project.dev.readthedocs.io/en/latest/redirect/',
         )
 
-        r = self.client.get(
-            '/en/latest/redirect/',
-            HTTP_HOST='project.dev.readthedocs.io',
-        )
-        self.assertEqual(r.status_code, 404)
+        with self.assertRaises(Http404):
+            r = self.client.get(
+                '/en/latest/redirect/',
+                HTTP_HOST='project.dev.readthedocs.io',
+            )
 
 
     def test_redirect_root(self):
@@ -461,12 +462,12 @@ class UserRedirectTests(MockStorageMixin, BaseDocServing):
             )
 
         with override_settings(PYTHON_MEDIA=True):
-            # File does not exist in storage media
-            r = self.client.get(
-                '/en/latest/',
-                HTTP_HOST='project.dev.readthedocs.io',
-            )
-            self.assertEqual(r.status_code, 404)
+            with self.assertRaises(Http404):
+                # File does not exist in storage media
+                r = self.client.get(
+                    '/en/latest/',
+                    HTTP_HOST='project.dev.readthedocs.io',
+                )
 
     def test_redirect_html_index(self):
         fixture.get(
@@ -526,20 +527,12 @@ class UserRedirectTests(MockStorageMixin, BaseDocServing):
             from_url='/',
         )
 
-        # Use ``proxito_404_handler`` URL here to emulate the internal redirect
-        # that happens on NGINX (URL path will be
-        # http://project.dev.readthedocs.io/_proxito_404_/en/latest/section/file-not-found
-        # when the view receives it)
-        r = self.client.get(
-            reverse(
-                'proxito_404_handler',
-                kwargs={
-                    'proxito_path': '/en/latest/section/file-not-found',
-                }),
-            HTTP_HOST='project.dev.readthedocs.io',
-        )
-        # Avoid infinite redirect
-        self.assertEqual(r.status_code, 404)
+        with self.assertRaises(Http404):
+            # Avoid infinite redirect
+            r = self.client.get(
+                '/en/latest/section/file-not-found',
+                HTTP_HOST='project.dev.readthedocs.io',
+            )
 
 
 # FIXME: these tests are valid, but the problem I'm facing is that the request
diff --git a/readthedocs/proxito/urls.py b/readthedocs/proxito/urls.py
index 04fe87371..354e7934b 100644
--- a/readthedocs/proxito/urls.py
+++ b/readthedocs/proxito/urls.py
@@ -42,7 +42,7 @@ from readthedocs.proxito.views.serve import (
     ServeRobotsTXT,
     ServeSitemapXML,
 )
-from readthedocs.proxito.views.utils import fast_404
+from readthedocs.proxito.views.utils import proxito_404_page_handler, fast_404
 
 DOC_PATH_PREFIX = getattr(settings, 'DOC_PATH_PREFIX', '')
 
@@ -144,5 +144,5 @@ urlpatterns = [
 ]
 
 # Use Django default error handlers to make things simpler
-handler404 = fast_404
+handler404 = proxito_404_page_handler
 handler500 = defaults.server_error
diff --git a/readthedocs/proxito/views/serve.py b/readthedocs/proxito/views/serve.py
index 43d0af31c..c105ecf3d 100644
--- a/readthedocs/proxito/views/serve.py
+++ b/readthedocs/proxito/views/serve.py
@@ -277,10 +277,7 @@ class ServeError404Base(ServeRedirectMixin, ServeDocsMixin, View):
                     resp.status_code = 404
                     return resp
 
-        # Finally, return the default 404 page generated by Read the Docs
-        resp = render(request, template_name)
-        resp.status_code = 404
-        return resp
+        raise Http404('No custom 404 page found.')
 
 
 class ServeError404(SettingsOverrideObject):
diff --git a/readthedocs/proxito/views/utils.py b/readthedocs/proxito/views/utils.py
index 087f5d570..b4c1d10a6 100644
--- a/readthedocs/proxito/views/utils.py
+++ b/readthedocs/proxito/views/utils.py
@@ -2,7 +2,7 @@ import os
 import logging
 
 from django.http import HttpResponse
-from django.shortcuts import get_object_or_404
+from django.shortcuts import get_object_or_404, render
 
 from .decorators import map_project_slug, map_subproject_slug
 
@@ -19,6 +19,24 @@ def fast_404(request, *args, **kwargs):
     return HttpResponse('Not Found.', status=404)
 
 
+def proxito_404_page_handler(request, exception=None, template_name='404.html'):
+    """
+    Decide what 404 page return depending if it's an internal NGINX redirect.
+
+    We want to return fast when the 404 is used as an internal NGINX redirect to
+    reach our ``ServeError404`` view. However, if the 404 exception was risen
+    inside ``ServeError404`` view, we want to render the default Read the Docs
+    Maze page.
+    """
+
+    if request.resolver_match.url_name != 'proxito_404_handler':
+        return fast_404(request, exception, template_name)
+
+    resp = render(request, template_name)
+    resp.status_code = 404
+    return resp
+
+
 @map_project_slug
 @map_subproject_slug
 def _get_project_data_from_request(