Index: django/middleware/common.py
===================================================================
--- django/middleware/common.py	(revision 6941)
+++ django/middleware/common.py	(working copy)
@@ -40,54 +40,18 @@
                 if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                     return http.HttpResponseForbidden('<h1>Forbidden</h1>')
 
-        # Check for a redirect based on settings.APPEND_SLASH
-        # and settings.PREPEND_WWW
-        host = request.get_host()
-        old_url = [host, request.path]
-        new_url = old_url[:]
+        _response = _handle_redirects(request)
+        if _response:
+            return _response
 
-        if (settings.PREPEND_WWW and old_url[0] and
-                not old_url[0].startswith('www.')):
-            new_url[0] = 'www.' + old_url[0]
-
-        # Append a slash if APPEND_SLASH is set and the URL doesn't have a
-        # trailing slash and there is no pattern for the current path
-        if settings.APPEND_SLASH and (not old_url[1].endswith('/')):
-            try:
-                urlresolvers.resolve(request.path)
-            except urlresolvers.Resolver404:
-                new_url[1] = new_url[1] + '/'
-                if settings.DEBUG and request.method == 'POST':
-                    raise RuntimeError, (""
-                    "You called this URL via POST, but the URL doesn't end "
-                    "in a slash and you have APPEND_SLASH set. Django can't "
-                    "redirect to the slash URL while maintaining POST data. "
-                    "Change your form to point to %s%s (note the trailing "
-                    "slash), or set APPEND_SLASH=False in your Django "
-                    "settings.") % (new_url[0], new_url[1])
-
-        if new_url != old_url:
-            # Redirect if the target url exists
-            try:
-                urlresolvers.resolve(new_url[1])
-            except urlresolvers.Resolver404:
-                pass
-            else:
-                if new_url[0]:
-                    newurl = "%s://%s%s" % (
-                        request.is_secure() and 'https' or 'http',
-                        new_url[0], urlquote(new_url[1]))
-                else:
-                    newurl = urlquote(new_url[1])
-                if request.GET:
-                    newurl += '?' + request.GET.urlencode()
-                return http.HttpResponsePermanentRedirect(newurl)
-
         return None
 
     def process_response(self, request, response):
         "Check for a flat page (for 404s) and calculate the Etag, if needed."
         if response.status_code == 404:
+            _response = _handle_redirects(request, resolve=False)
+            if _response:
+                return _response
             if settings.SEND_BROKEN_LINK_EMAILS:
                 # If the referrer was from an internal link or a non-search-engine site,
                 # send a note to the managers.
@@ -118,6 +82,52 @@
 
         return response
 
+def _handle_redirects(request, resolve=True):
+    host = request.get_host()
+    old_url = [host, request.path]
+    new_url = old_url[:]
+
+    if (settings.PREPEND_WWW and old_url[0] and
+            not old_url[0].startswith('www.')):
+        new_url[0] = 'www.' + old_url[0]
+
+    # Append a slash if APPEND_SLASH is set and the URL doesn't have a
+    # trailing slash and there is no pattern for the current path
+    if settings.APPEND_SLASH and (not old_url[1].endswith('/')):
+        if resolve:
+            try:
+                urlresolvers.resolve(request.path)
+            except urlresolvers.Resolver404:
+                new_url[1] = new_url[1] + '/'
+        else:
+            new_url[1] = new_url[1] + '/'
+
+    if new_url != old_url:
+        # Redirect if the target url exists
+        try:
+            if resolve and new_url[0] == new_url[0] and new_url[1] != old_url[1]:
+                urlresolvers.resolve(new_url[1])
+        except urlresolvers.Resolver404:
+            pass
+        else:
+            if new_url[0]:
+                newurl = "%s://%s%s" % (
+                    request.is_secure() and 'https' or 'http',
+                    new_url[0], urlquote(new_url[1]))
+            else:
+                newurl = urlquote(new_url[1])
+            if request.GET:
+                newurl += '?' + request.GET.urlencode()
+            if settings.DEBUG and request.method == 'POST':
+                raise RuntimeError, (""
+                "You called this URL via POST, but the URL doesn't end "
+                "in a slash and you have APPEND_SLASH set. Django can't "
+                "redirect to the slash URL while maintaining POST data. "
+                "Change your form to point to %s%s (note the trailing "
+                "slash), or set APPEND_SLASH=False in your Django "
+                "settings.") % (new_url[0], new_url[1])
+            return http.HttpResponsePermanentRedirect(newurl)
+
 def _is_ignorable_404(uri):
     "Returns True if a 404 at the given URL *shouldn't* notify the site managers"
     for start in settings.IGNORABLE_404_STARTS:
