mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Tests for ETag and gzip
This commit is contained in:
parent
8cc8d83a38
commit
b4e02f6bc3
@ -543,7 +543,9 @@ class HTTPPair(object):
|
||||
self.status_code = httplib.CREATED if self.method == 'POST' else httplib.OK
|
||||
|
||||
try:
|
||||
self.status_code, output = finalize_output(output, self.inheaders, self.outheaders, self.status_code, self.response_protocol is HTTP1, self.method)
|
||||
self.status_code, output = finalize_output(
|
||||
output, self.inheaders, self.outheaders, self.status_code,
|
||||
self.response_protocol is HTTP1, self.method, self.server_loop.opts.compress_min_size)
|
||||
except IfNoneMatch as e:
|
||||
if self.method in ('GET', 'HEAD'):
|
||||
self.send_not_modified(e.etag)
|
||||
|
@ -59,6 +59,10 @@ raw_options = (
|
||||
'max_request_body_size', 500.0,
|
||||
None,
|
||||
|
||||
'Minimum size for which responses use data compression (in bytes)',
|
||||
'compress_min_size', 1024,
|
||||
None,
|
||||
|
||||
'Decrease latency by using the TCP_NODELAY feature',
|
||||
'no_delay', True,
|
||||
'no_delay turns on TCP_NODELAY which decreases latency at the cost of'
|
||||
|
@ -124,6 +124,8 @@ class GeneratedOutput(object):
|
||||
class StaticGeneratedOutput(object):
|
||||
|
||||
def __init__(self, data):
|
||||
if isinstance(data, type('')):
|
||||
data = data.encode('utf-8')
|
||||
self.data = data
|
||||
self.etag = '"%s"' % hashlib.sha1(data).hexdigest()
|
||||
self.content_length = len(data)
|
||||
@ -145,7 +147,7 @@ def generate_static_output(cache, gso_lock, name, generator):
|
||||
def parse_if_none_match(val):
|
||||
return {x.strip() for x in val.split(',')}
|
||||
|
||||
def finalize_output(output, inheaders, outheaders, status_code, is_http1, method):
|
||||
def finalize_output(output, inheaders, outheaders, status_code, is_http1, method, compress_min_size):
|
||||
ct = outheaders.get('Content-Type', '')
|
||||
compressible = not ct or ct.startswith('text/') or ct.startswith('image/svg') or ct.startswith('application/json')
|
||||
if isinstance(output, file):
|
||||
@ -156,7 +158,8 @@ def finalize_output(output, inheaders, outheaders, status_code, is_http1, method
|
||||
pass
|
||||
else:
|
||||
output = GeneratedOutput(output, outheaders)
|
||||
compressible = (status_code == httplib.OK and compressible and output.content_length > 1024 and
|
||||
compressible = (status_code == httplib.OK and compressible and
|
||||
(compress_min_size > -1 and output.content_length >= compress_min_size) and
|
||||
acceptable_encoding(inheaders.get('Accept-Encoding', '')) and not is_http1)
|
||||
accept_ranges = (not compressible and output.accept_ranges is not None and status_code == httplib.OK and
|
||||
not is_http1)
|
||||
|
@ -61,7 +61,9 @@ class TestServer(Thread):
|
||||
def __exit__(self, *args):
|
||||
self.loop.stop()
|
||||
|
||||
def connect(self, timeout=0.1):
|
||||
def connect(self, timeout=None):
|
||||
if timeout is None:
|
||||
timeout = self.loop.opts.timeout
|
||||
return httplib.HTTPConnection(self.address[0], self.address[1], strict=True, timeout=timeout)
|
||||
|
||||
def change_handler(self, handler):
|
||||
|
@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
import textwrap, httplib
|
||||
import textwrap, httplib, hashlib, zlib
|
||||
from io import BytesIO
|
||||
|
||||
from calibre.srv.tests.base import BaseTest, TestServer
|
||||
@ -159,3 +159,28 @@ class TestHTTP(BaseTest):
|
||||
self.ae(server.loop.requests.idle, 10)
|
||||
|
||||
# }}}
|
||||
|
||||
def test_http_response(self): # {{{
|
||||
'Test HTTP protocol responses'
|
||||
def handler(conn):
|
||||
return conn.generate_static_output('test', lambda : ''.join(conn.path))
|
||||
with TestServer(handler, timeout=0.1, compress_min_size=0) as server:
|
||||
# Test ETag
|
||||
conn = server.connect()
|
||||
conn.request('GET', '/an_etagged_path')
|
||||
r = conn.getresponse()
|
||||
self.ae(r.status, httplib.OK), self.ae(r.read(), b'an_etagged_path')
|
||||
etag = r.getheader('ETag')
|
||||
self.ae(etag, '"%s"' % hashlib.sha1('an_etagged_path').hexdigest())
|
||||
conn.request('GET', '/an_etagged_path', headers={'If-None-Match':etag})
|
||||
r = conn.getresponse()
|
||||
self.ae(r.status, httplib.NOT_MODIFIED)
|
||||
self.ae(r.read(), b'')
|
||||
|
||||
# Test gzip
|
||||
conn.request('GET', '/an_etagged_path', headers={'Accept-Encoding':'gzip'})
|
||||
r = conn.getresponse()
|
||||
self.ae(r.status, httplib.OK), self.ae(zlib.decompress(r.read(), 16+zlib.MAX_WBITS), b'an_etagged_path')
|
||||
|
||||
# }}}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user