Repository: readthedocs/readthedocs.org
Issue: Cannot redirect from old version to new version if old version is marked inactive

## Details

* Read the Docs project URL: http://docs.couchdb.org/

## Expected Result

Pursuant to #2444 and #4501, I should be able to add a redirect from a now-obsolete version of our documentation (2.1.1) to our current stable version (stable) by adding an Exact redirect:

```
/en/2.1.1/$rest -> /en/stable/
```

This should redirect a page such as http://docs.couchdb.org/en/2.1.1/intro/overview.html to http://docs.couchdb.org/en/stable/intro/overview.html .

## Actual Result

Accessing http://docs.couchdb.org/en/2.1.1/intro/overview.html results in a Permission Denied error unless that actual version (2.1.1) is marked as an Active Version. Setting the version to be redirected as Inactive makes redirection impossible.

Setting these invalid versions to Active makes them appear in the valid version list, but clicking on them results in them being redirected to somewhere else (in our case, the `stable` tag) which is very confusing for end users.

@humitos I believe that redirection checks should occur before checking whether a version is marked as inactive, yes? This way, redirects for obsolete versions would not require those versions to continue to be marked as Active.

Changed files:
readthedocs/core/views/serve.py, readthedocs/rtd_tests/tests/test_redirects.py

diff --git a/readthedocs/core/views/serve.py b/readthedocs/core/views/serve.py
index 6c828dc50..245b0bba1 100644
--- a/readthedocs/core/views/serve.py
+++ b/readthedocs/core/views/serve.py
@@ -155,8 +155,9 @@ def serve_docs(
     try:
         version = project.versions.public(request.user).get(slug=version_slug)
     except Version.DoesNotExist:
-        # Properly raise a 404 if the version doesn't exist & a 401 if it does
-        if project.versions.filter(slug=version_slug).exists():
+        # Properly raise a 404 if the version doesn't exist (or is inactive) and
+        # a 401 if it does
+        if project.versions.filter(slug=version_slug, active=True).exists():
             return _serve_401(request, project)
         raise Http404('Version does not exist.')
     filename = resolve_path(
diff --git a/readthedocs/rtd_tests/tests/test_redirects.py b/readthedocs/rtd_tests/tests/test_redirects.py
index a4611b34f..7595d1475 100644
--- a/readthedocs/rtd_tests/tests/test_redirects.py
+++ b/readthedocs/rtd_tests/tests/test_redirects.py
@@ -1,5 +1,4 @@
 from __future__ import absolute_import
-from django.core.urlresolvers import reverse
 from django.http import Http404
 from django.test import TestCase
 from django.test.utils import override_settings
@@ -9,6 +8,7 @@ from django_dynamic_fixture import fixture
 from mock import patch
 
 from readthedocs.builds.constants import LATEST
+from readthedocs.builds.models import Version
 from readthedocs.projects.models import Project
 from readthedocs.redirects.models import Redirect
 
@@ -185,6 +185,31 @@ class RedirectAppTests(TestCase):
         self.assertEqual(
             r['Location'], 'http://pip.readthedocs.org/en/master/guides/install.html')
 
+    @override_settings(USE_SUBDOMAIN=True)
+    def test_redirect_inactive_version(self):
+        """
+        Inactive Version (``active=False``) should redirect properly.
+
+        The function that servers the page should return 404 when serving a page
+        of an inactive version and the redirect system should work.
+        """
+        version = get(
+            Version,
+            slug='oldversion',
+            project=self.pip,
+            active=False,
+        )
+        Redirect.objects.create(
+            project=self.pip,
+            redirect_type='exact',
+            from_url='/en/oldversion/',
+            to_url='/en/newversion/',
+        )
+        r = self.client.get('/en/oldversion/', HTTP_HOST='pip.readthedocs.org')
+        self.assertEqual(r.status_code, 302)
+        self.assertEqual(
+            r['Location'], 'http://pip.readthedocs.org/en/newversion/')
+
     @override_settings(USE_SUBDOMAIN=True)
     def test_redirect_keeps_version_number(self):
         Redirect.objects.create(