diff --git a/django/middleware/common.py b/django/middleware/common.py index dad1e6b2eb8..68fcb8a7802 100644 --- a/django/middleware/common.py +++ b/django/middleware/common.py @@ -127,7 +127,7 @@ class BrokenLinkEmailsMiddleware(object): referer = force_text(request.META.get('HTTP_REFERER', ''), errors='replace') if not self.is_ignorable_request(request, path, domain, referer): - ua = request.META.get('HTTP_USER_AGENT', '') + ua = force_text(request.META.get('HTTP_USER_AGENT', ''), errors='replace') ip = request.META.get('REMOTE_ADDR', '') mail_managers( "Broken %slink on %s" % ( diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 3533b1d957a..8b20a0c627c 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -320,6 +320,16 @@ class BrokenLinkEmailsMiddlewareTest(TestCase): BrokenLinkEmailsMiddleware().process_response(self.req, self.resp) self.assertEqual(len(mail.outbox), 1) + @skipIf(six.PY3, "HTTP_USER_AGENT is str type on Python 3") + def test_404_error_nonascii_user_agent(self): + # Such user agent strings should not happen, but anyway, if it happens, + # let's not crash + self.req.META['HTTP_REFERER'] = '/another/url/' + self.req.META['HTTP_USER_AGENT'] = b'\xd0\xbb\xd0\xb8\xff\xff' + BrokenLinkEmailsMiddleware().process_response(self.req, self.resp) + self.assertEqual(len(mail.outbox), 1) + self.assertIn('User agent: \u043b\u0438\ufffd\ufffd\n', mail.outbox[0].body) + def test_custom_request_checker(self): class SubclassedMiddleware(BrokenLinkEmailsMiddleware): ignored_user_agent_patterns = (re.compile(r'Spider.*'),