diff --git a/scrapy/contrib/downloadermiddleware/httpcompression.py b/scrapy/contrib/downloadermiddleware/httpcompression.py index 031001f15..26069d437 100644 --- a/scrapy/contrib/downloadermiddleware/httpcompression.py +++ b/scrapy/contrib/downloadermiddleware/httpcompression.py @@ -2,7 +2,7 @@ import zlib from gzip import GzipFile from cStringIO import StringIO -from scrapy.http import Response +from scrapy.http import Response, TextResponse from scrapy.core.downloader.responsetypes import responsetypes @@ -21,7 +21,12 @@ class HttpCompressionMiddleware(object): decoded_body = self._decode(response.body, encoding.lower()) respcls = responsetypes.from_args(headers=response.headers, \ url=response.url) - response = response.replace(cls=respcls, body=decoded_body) + kwargs = dict(cls=respcls, body=decoded_body) + if issubclass(respcls, TextResponse): + # force recalculating the encoding until we make sure the + # responsetypes guessing is reliable + kwargs['encoding'] = None + response = response.replace(**kwargs) if not content_encoding: del response.headers['Content-Encoding'] diff --git a/scrapy/tests/test_downloadermiddleware_httpcompression.py b/scrapy/tests/test_downloadermiddleware_httpcompression.py index 40988ecd7..a48ca35a9 100644 --- a/scrapy/tests/test_downloadermiddleware_httpcompression.py +++ b/scrapy/tests/test_downloadermiddleware_httpcompression.py @@ -118,3 +118,21 @@ class HttpCompressionTest(TestCase): self.assertEqual(newresponse.body, plainbody) self.assertEqual(newresponse.encoding, resolve_encoding('gb2312')) + def test_process_response_force_recalculate_encoding(self): + headers = { + 'Content-Type': 'text/html', + 'Content-Encoding': 'gzip', + } + f = StringIO() + plainbody = """Some page""" + zf = GzipFile(fileobj=f, mode='wb') + zf.write(plainbody) + zf.close() + response = HtmlResponse("http;//www.example.com/page.html", headers=headers, body=f.getvalue()) + request = Request("http://www.example.com/") + + newresponse = self.mw.process_response(request, response, self.spider) + assert isinstance(newresponse, HtmlResponse) + self.assertEqual(newresponse.body, plainbody) + self.assertEqual(newresponse.encoding, resolve_encoding('gb2312')) +