Index: django/middleware/common.py
===================================================================
--- django/middleware/common.py	(revision 6453)
+++ django/middleware/common.py	(working copy)
@@ -57,37 +57,62 @@
 
     def process_response(self, request, response):
         "Check for a flat page (for 404s) and calculate the Etag, if needed."
-        if response.status_code == 404:
-            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.
-                domain = request.get_host()
-                referer = request.META.get('HTTP_REFERER', None)
-                is_internal = _is_internal_request(domain, referer)
-                path = request.get_full_path()
-                if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer):
-                    ua = request.META.get('HTTP_USER_AGENT', '<none>')
-                    ip = request.META.get('REMOTE_ADDR', '<none>')
-                    mail_managers("Broken %slink on %s" % ((is_internal and 'INTERNAL ' or ''), domain),
-                        "Referrer: %s\nRequested URL: %s\nUser agent: %s\nIP address: %s\n" \
-                                  % (referer, request.get_full_path(), ua, ip))
-                return response
+        if response.status_code == 404 and settings.SEND_BROKEN_LINK_EMAILS:
+            return self.process_response_404(request, response)
 
         # Use ETags, if requested.
         if settings.USE_ETAGS:
-            if response.has_header('ETag'):
-                etag = response['ETag']
-            else:
-                etag = md5.new(response.content).hexdigest()
-            if response.status_code >= 200 and response.status_code < 300 and request.META.get('HTTP_IF_NONE_MATCH') == etag:
-                cookies = response.cookies
-                response = http.HttpResponseNotModified()
-                response.cookies = cookies
-            else:
-                response['ETag'] = etag
+            return self.process_response_etags(request, response)
 
         return response
 
+
+    @staticmethod
+    def process_response_404(request, response):
+        """Sends mail to managers.
+
+        Respects settings IGONRABLE_404_STARTS and IGNORABLE_404_ENDS.
+        Requests without referrers and those with search engine
+        referrers (i.e. those with '?' in them) are excluded.
+        """
+        domain = request.get_host()
+        referer = request.META.get('HTTP_REFERER', None)
+        is_internal = _is_internal_request(domain, referer)
+        path = request.get_full_path()
+        if (referer
+            and not _is_ignorable_404(path)
+            and (is_internal or '?' not in referer)):
+            ua = request.META.get('HTTP_USER_AGENT', '<none>')
+            ip = request.META.get('REMOTE_ADDR', '<none>')
+            mail_managers(
+                "Broken %slink on %s" % ((is_internal and 'INTERNAL ' or ''),
+                                         domain),
+                "Referrer: %s\nRequested URL: %s\n"
+                "User agent: %s\nIP address: %s\n"
+                % (referer, path, ua, ip))
+        return response
+
+
+    @staticmethod
+    def process_response_etags(request, response):
+        """Adds ETags to responses that do not have them,
+        and sends ResponseNotModified when appropriate.
+        """
+        if response.has_header('ETag'):
+            etag = response['ETag']
+        else:
+            etag = md5.new(response.content).hexdigest()
+        if (response.status_code >= 200
+            and response.status_code < 300
+            and request.META.get('HTTP_IF_NONE_MATCH') == etag):
+            cookies = response.cookies
+            response = http.HttpResponseNotModified()
+            response.cookies = cookies
+        else:
+            response['ETag'] = etag
+        return response
+
+
 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:
