Skip to content

Commit 7b50d93

Browse files
committed
added response compression
1 parent cd20de6 commit 7b50d93

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

aiohttp/web.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,8 @@ def __init__(self, *, status=200, reason=None):
393393
self._keep_alive = None
394394
self._chunked = False
395395
self._chunk_size = None
396+
self._compression = False
397+
self._compression_force = False
396398
self._headers = CIMultiDict()
397399
self._cookies = http.cookies.SimpleCookie()
398400
self.set_status(status, reason)
@@ -418,6 +420,10 @@ def status(self):
418420
def chunked(self):
419421
return self._chunked
420422

423+
@property
424+
def compression(self):
425+
return self._compression
426+
421427
@property
422428
def reason(self):
423429
return self._reason
@@ -440,6 +446,11 @@ def enable_chunked_encoding(self, chunk_size=None):
440446
self._chunked = True
441447
self._chunk_size = chunk_size
442448

449+
def enable_compression(self, force=False):
450+
"""Enables response compression with `deflate` encoding."""
451+
self._compression = True
452+
self._compression_force = force
453+
443454
@property
444455
def headers(self):
445456
return self._headers
@@ -568,6 +579,12 @@ def start(self, request):
568579

569580
self._copy_cookies()
570581

582+
if self._compression:
583+
if (self._compression_force or
584+
'deflate' in request.headers.get(
585+
hdrs.ACCEPT_ENCODING, '')):
586+
resp_impl.add_compression_filter()
587+
571588
if self._chunked:
572589
resp_impl.enable_chunked_encoding()
573590
if self._chunk_size:

tests/test_web_response.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import asyncio
22
import unittest
33
from unittest import mock
4+
from aiohttp import hdrs
45
from aiohttp.multidict import CIMultiDict
56
from aiohttp.web import Request, StreamResponse, Response
67
from aiohttp.protocol import RawRequestMessage, HttpVersion11
@@ -138,6 +139,50 @@ def test_chunk_size(self, ResponseImpl):
138139

139140
msg = resp.start(req)
140141
self.assertTrue(msg.chunked)
142+
msg.add_chunking_filter.assert_called_with(8192)
143+
self.assertIsNotNone(msg.filter)
144+
145+
@mock.patch('aiohttp.web.ResponseImpl')
146+
def test_compression_no_accept(self, ResponseImpl):
147+
req = self.make_request('GET', '/')
148+
resp = StreamResponse()
149+
self.assertFalse(resp.chunked)
150+
151+
self.assertFalse(resp.compression)
152+
resp.enable_compression()
153+
self.assertTrue(resp.compression)
154+
155+
msg = resp.start(req)
156+
self.assertFalse(msg.add_compression_filter.called)
157+
158+
@mock.patch('aiohttp.web.ResponseImpl')
159+
def test_force_compression_no_accept(self, ResponseImpl):
160+
req = self.make_request('GET', '/')
161+
resp = StreamResponse()
162+
self.assertFalse(resp.chunked)
163+
164+
self.assertFalse(resp.compression)
165+
resp.enable_compression(force=True)
166+
self.assertTrue(resp.compression)
167+
168+
msg = resp.start(req)
169+
self.assertTrue(msg.add_compression_filter.called)
170+
self.assertIsNotNone(msg.filter)
171+
172+
@mock.patch('aiohttp.web.ResponseImpl')
173+
def test_compression(self, ResponseImpl):
174+
req = self.make_request(
175+
'GET', '/',
176+
headers=CIMultiDict({str(hdrs.ACCEPT_ENCODING): 'gzip, deflate'}))
177+
resp = StreamResponse()
178+
self.assertFalse(resp.chunked)
179+
180+
self.assertFalse(resp.compression)
181+
resp.enable_compression()
182+
self.assertTrue(resp.compression)
183+
184+
msg = resp.start(req)
185+
self.assertTrue(msg.add_compression_filter.called)
141186
self.assertIsNotNone(msg.filter)
142187

143188
def test_write_non_byteish(self):

0 commit comments

Comments
 (0)