Loading django/conf/global_settings.py +2 −2 Original line number Diff line number Diff line Loading @@ -146,7 +146,7 @@ FILE_CHARSET = 'utf-8' # Email address that error messages come from. SERVER_EMAIL = 'root@localhost' # Whether to send broken-link emails. # Whether to send broken-link emails. Deprecated, must be removed in 1.8. SEND_BROKEN_LINK_EMAILS = False # Database connection info. If left empty, will default to the dummy backend. Loading Loading @@ -245,7 +245,7 @@ ALLOWED_INCLUDE_ROOTS = () ADMIN_FOR = () # List of compiled regular expression objects representing URLs that need not # be reported when SEND_BROKEN_LINK_EMAILS is True. Here are a few examples: # be reported by BrokenLinkEmailsMiddleware. Here are a few examples: # import re # IGNORABLE_404_URLS = ( # re.compile(r'^/apple-touch-icon.*\.png$'), Loading django/middleware/common.py +46 −32 Original line number Diff line number Diff line import hashlib import logging import re import warnings from django.conf import settings from django import http from django.core.mail import mail_managers from django.core import urlresolvers from django import http from django.utils.http import urlquote from django.utils import six from django.core import urlresolvers logger = logging.getLogger('django.request') Loading Loading @@ -102,25 +103,15 @@ class CommonMiddleware(object): return http.HttpResponsePermanentRedirect(newurl) def process_response(self, request, response): "Send broken link emails and calculate the Etag, if needed." if response.status_code == 404: if settings.SEND_BROKEN_LINK_EMAILS and not settings.DEBUG: # 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), fail_silently=True) return response """ Calculate the ETag, if needed. """ if settings.SEND_BROKEN_LINK_EMAILS: warnings.warn("SEND_BROKEN_LINK_EMAILS is deprecated. " "Use BrokenLinkEmailsMiddleware instead.", PendingDeprecationWarning, stacklevel=2) BrokenLinkEmailsMiddleware().process_response(request, response) # Use ETags, if requested. if settings.USE_ETAGS: if response.has_header('ETag'): etag = response['ETag'] Loading @@ -139,15 +130,38 @@ class CommonMiddleware(object): return response def _is_ignorable_404(uri): class BrokenLinkEmailsMiddleware(object): def process_response(self, request, response): """ Returns True if a 404 at the given URL *shouldn't* notify the site managers. Send broken link emails for relevant 404 NOT FOUND responses. """ return any(pattern.search(uri) for pattern in settings.IGNORABLE_404_URLS) if response.status_code == 404 and not settings.DEBUG: domain = request.get_host() path = request.get_full_path() referer = request.META.get('HTTP_REFERER', '') is_internal = self.is_internal_request(domain, referer) is_not_search_engine = '?' not in referer is_ignorable = self.is_ignorable_404(path) if referer and (is_internal or is_not_search_engine) and not is_ignorable: ua = request.META.get('HTTP_USER_AGENT', '<none>') ip = request.META.get('REMOTE_ADDR', '<none>') mail_managers( "Broken %slink on %s" % (('INTERNAL ' if is_internal else ''), domain), "Referrer: %s\nRequested URL: %s\nUser agent: %s\nIP address: %s\n" % (referer, path, ua, ip), fail_silently=True) return response def _is_internal_request(domain, referer): def is_internal_request(self, domain, referer): """ Returns true if the referring URL is the same domain as the current request. Returns True if the referring URL is the same domain as the current request. """ # Different subdomains are treated as different domains. return referer is not None and re.match("^https?://%s/" % re.escape(domain), referer) return re.match("^https?://%s/" % re.escape(domain), referer) def is_ignorable_404(self, uri): """ Returns True if a 404 at the given URL *shouldn't* notify the site managers. """ return any(pattern.search(uri) for pattern in settings.IGNORABLE_404_URLS) docs/howto/error-reporting.txt +11 −8 Original line number Diff line number Diff line Loading @@ -54,18 +54,24 @@ setting. Django can also be configured to email errors about broken links (404 "page not found" errors). Django sends emails about 404 errors when: * :setting:`DEBUG` is ``False`` * :setting:`DEBUG` is ``False``; * :setting:`SEND_BROKEN_LINK_EMAILS` is ``True`` * Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware`` (which it does by default). * Your :setting:`MIDDLEWARE_CLASSES` setting includes :class:`django.middleware.common.BrokenLinkEmailsMiddleware`. If those conditions are met, Django will email the users listed in the :setting:`MANAGERS` setting whenever your code raises a 404 and the request has a referer. (It doesn't bother to email for 404s that don't have a referer -- those are usually just people typing in broken URLs or broken Web 'bots). .. note:: :class:`~django.middleware.common.BrokenLinkEmailsMiddleware` must appear before other middleware that intercepts 404 errors, such as :class:`~django.middleware.locale.LocaleMiddleware` or :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`. Put it towards the top of your :setting:`MIDDLEWARE_CLASSES` setting. You can tell Django to stop reporting particular 404s by tweaking the :setting:`IGNORABLE_404_URLS` setting. It should be a tuple of compiled regular expression objects. For example:: Loading @@ -92,9 +98,6 @@ crawlers often request:: (Note that these are regular expressions, so we put a backslash in front of periods to escape them.) The best way to disable this behavior is to set :setting:`SEND_BROKEN_LINK_EMAILS` to ``False``. .. seealso:: 404 errors are logged using the logging framework. By default, these log Loading docs/internals/deprecation.txt +7 −0 Original line number Diff line number Diff line Loading @@ -308,6 +308,13 @@ these changes. * The ``depth`` keyword argument will be removed from :meth:`~django.db.models.query.QuerySet.select_related`. 1.8 --- * The ``SEND_BROKEN_LINK_EMAILS`` setting will be removed. Add the :class:`django.middleware.common.BrokenLinkEmailsMiddleware` middleware to your :setting:`MIDDLEWARE_CLASSES` setting instead. 2.0 --- Loading docs/ref/middleware.txt +5 −3 Original line number Diff line number Diff line Loading @@ -61,14 +61,16 @@ Adds a few conveniences for perfectionists: indexer would treat them as separate URLs -- so it's best practice to normalize URLs. * Sends broken link notification emails to :setting:`MANAGERS` if :setting:`SEND_BROKEN_LINK_EMAILS` is set to ``True``. * Handles ETags based on the :setting:`USE_ETAGS` setting. If :setting:`USE_ETAGS` is set to ``True``, Django will calculate an ETag for each request by MD5-hashing the page content, and it'll take care of sending ``Not Modified`` responses, if appropriate. .. class:: BrokenLinkEmailsMiddleware * Sends broken link notification emails to :setting:`MANAGERS` (see :doc:`/howto/error-reporting`). View metadata middleware ------------------------ Loading Loading
django/conf/global_settings.py +2 −2 Original line number Diff line number Diff line Loading @@ -146,7 +146,7 @@ FILE_CHARSET = 'utf-8' # Email address that error messages come from. SERVER_EMAIL = 'root@localhost' # Whether to send broken-link emails. # Whether to send broken-link emails. Deprecated, must be removed in 1.8. SEND_BROKEN_LINK_EMAILS = False # Database connection info. If left empty, will default to the dummy backend. Loading Loading @@ -245,7 +245,7 @@ ALLOWED_INCLUDE_ROOTS = () ADMIN_FOR = () # List of compiled regular expression objects representing URLs that need not # be reported when SEND_BROKEN_LINK_EMAILS is True. Here are a few examples: # be reported by BrokenLinkEmailsMiddleware. Here are a few examples: # import re # IGNORABLE_404_URLS = ( # re.compile(r'^/apple-touch-icon.*\.png$'), Loading
django/middleware/common.py +46 −32 Original line number Diff line number Diff line import hashlib import logging import re import warnings from django.conf import settings from django import http from django.core.mail import mail_managers from django.core import urlresolvers from django import http from django.utils.http import urlquote from django.utils import six from django.core import urlresolvers logger = logging.getLogger('django.request') Loading Loading @@ -102,25 +103,15 @@ class CommonMiddleware(object): return http.HttpResponsePermanentRedirect(newurl) def process_response(self, request, response): "Send broken link emails and calculate the Etag, if needed." if response.status_code == 404: if settings.SEND_BROKEN_LINK_EMAILS and not settings.DEBUG: # 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), fail_silently=True) return response """ Calculate the ETag, if needed. """ if settings.SEND_BROKEN_LINK_EMAILS: warnings.warn("SEND_BROKEN_LINK_EMAILS is deprecated. " "Use BrokenLinkEmailsMiddleware instead.", PendingDeprecationWarning, stacklevel=2) BrokenLinkEmailsMiddleware().process_response(request, response) # Use ETags, if requested. if settings.USE_ETAGS: if response.has_header('ETag'): etag = response['ETag'] Loading @@ -139,15 +130,38 @@ class CommonMiddleware(object): return response def _is_ignorable_404(uri): class BrokenLinkEmailsMiddleware(object): def process_response(self, request, response): """ Returns True if a 404 at the given URL *shouldn't* notify the site managers. Send broken link emails for relevant 404 NOT FOUND responses. """ return any(pattern.search(uri) for pattern in settings.IGNORABLE_404_URLS) if response.status_code == 404 and not settings.DEBUG: domain = request.get_host() path = request.get_full_path() referer = request.META.get('HTTP_REFERER', '') is_internal = self.is_internal_request(domain, referer) is_not_search_engine = '?' not in referer is_ignorable = self.is_ignorable_404(path) if referer and (is_internal or is_not_search_engine) and not is_ignorable: ua = request.META.get('HTTP_USER_AGENT', '<none>') ip = request.META.get('REMOTE_ADDR', '<none>') mail_managers( "Broken %slink on %s" % (('INTERNAL ' if is_internal else ''), domain), "Referrer: %s\nRequested URL: %s\nUser agent: %s\nIP address: %s\n" % (referer, path, ua, ip), fail_silently=True) return response def _is_internal_request(domain, referer): def is_internal_request(self, domain, referer): """ Returns true if the referring URL is the same domain as the current request. Returns True if the referring URL is the same domain as the current request. """ # Different subdomains are treated as different domains. return referer is not None and re.match("^https?://%s/" % re.escape(domain), referer) return re.match("^https?://%s/" % re.escape(domain), referer) def is_ignorable_404(self, uri): """ Returns True if a 404 at the given URL *shouldn't* notify the site managers. """ return any(pattern.search(uri) for pattern in settings.IGNORABLE_404_URLS)
docs/howto/error-reporting.txt +11 −8 Original line number Diff line number Diff line Loading @@ -54,18 +54,24 @@ setting. Django can also be configured to email errors about broken links (404 "page not found" errors). Django sends emails about 404 errors when: * :setting:`DEBUG` is ``False`` * :setting:`DEBUG` is ``False``; * :setting:`SEND_BROKEN_LINK_EMAILS` is ``True`` * Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware`` (which it does by default). * Your :setting:`MIDDLEWARE_CLASSES` setting includes :class:`django.middleware.common.BrokenLinkEmailsMiddleware`. If those conditions are met, Django will email the users listed in the :setting:`MANAGERS` setting whenever your code raises a 404 and the request has a referer. (It doesn't bother to email for 404s that don't have a referer -- those are usually just people typing in broken URLs or broken Web 'bots). .. note:: :class:`~django.middleware.common.BrokenLinkEmailsMiddleware` must appear before other middleware that intercepts 404 errors, such as :class:`~django.middleware.locale.LocaleMiddleware` or :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`. Put it towards the top of your :setting:`MIDDLEWARE_CLASSES` setting. You can tell Django to stop reporting particular 404s by tweaking the :setting:`IGNORABLE_404_URLS` setting. It should be a tuple of compiled regular expression objects. For example:: Loading @@ -92,9 +98,6 @@ crawlers often request:: (Note that these are regular expressions, so we put a backslash in front of periods to escape them.) The best way to disable this behavior is to set :setting:`SEND_BROKEN_LINK_EMAILS` to ``False``. .. seealso:: 404 errors are logged using the logging framework. By default, these log Loading
docs/internals/deprecation.txt +7 −0 Original line number Diff line number Diff line Loading @@ -308,6 +308,13 @@ these changes. * The ``depth`` keyword argument will be removed from :meth:`~django.db.models.query.QuerySet.select_related`. 1.8 --- * The ``SEND_BROKEN_LINK_EMAILS`` setting will be removed. Add the :class:`django.middleware.common.BrokenLinkEmailsMiddleware` middleware to your :setting:`MIDDLEWARE_CLASSES` setting instead. 2.0 --- Loading
docs/ref/middleware.txt +5 −3 Original line number Diff line number Diff line Loading @@ -61,14 +61,16 @@ Adds a few conveniences for perfectionists: indexer would treat them as separate URLs -- so it's best practice to normalize URLs. * Sends broken link notification emails to :setting:`MANAGERS` if :setting:`SEND_BROKEN_LINK_EMAILS` is set to ``True``. * Handles ETags based on the :setting:`USE_ETAGS` setting. If :setting:`USE_ETAGS` is set to ``True``, Django will calculate an ETag for each request by MD5-hashing the page content, and it'll take care of sending ``Not Modified`` responses, if appropriate. .. class:: BrokenLinkEmailsMiddleware * Sends broken link notification emails to :setting:`MANAGERS` (see :doc:`/howto/error-reporting`). View metadata middleware ------------------------ Loading