/usr/lib/python2.7/dist-packages/twext/web2/filter/gzip.py is in calendarserver 5.2+dfsg-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | from __future__ import generators
import struct
import zlib
from twext.web2 import stream
# TODO: ungzip (can any browsers actually generate gzipped
# upload data?) But it's necessary for client anyways.
def gzipStream(input, compressLevel=6):
crc, size = zlib.crc32(''), 0
# magic header, compression method, no flags
header = '\037\213\010\000'
# timestamp
header += struct.pack('<L', 0)
# uh.. stuff
header += '\002\377'
yield header
compress = zlib.compressobj(compressLevel, zlib.DEFLATED, -zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0)
_compress = compress.compress
_crc32 = zlib.crc32
yield input.wait
for buf in input:
if len(buf) != 0:
crc = _crc32(buf, crc)
size += len(buf)
yield _compress(buf)
yield input.wait
yield compress.flush()
yield struct.pack('<LL', crc & 0xFFFFFFFFL, size & 0xFFFFFFFFL)
gzipStream=stream.generatorToStream(gzipStream)
def deflateStream(input, compressLevel=6):
# NOTE: this produces RFC-conformant but some-browser-incompatible output.
# The RFC says that you're supposed to output zlib-format data, but many
# browsers expect raw deflate output. Luckily all those browsers support
# gzip, also, so they won't even see deflate output.
compress = zlib.compressobj(compressLevel, zlib.DEFLATED, zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0)
_compress = compress.compress
yield input.wait
for buf in input:
if len(buf) != 0:
yield _compress(buf)
yield input.wait
yield compress.flush()
deflateStream=stream.generatorToStream(deflateStream)
def gzipfilter(request, response):
if response.stream is None or response.headers.getHeader('content-encoding'):
# Empty stream, or already compressed.
return response
# FIXME: make this a more flexible matching scheme
mimetype = response.headers.getHeader('content-type')
if not mimetype or mimetype.mediaType != 'text':
return response
# Make sure to note we're going to return different content depending on
# the accept-encoding header.
vary = response.headers.getHeader('vary', [])
if 'accept-encoding' not in vary:
response.headers.setHeader('vary', vary+['accept-encoding'])
ae = request.headers.getHeader('accept-encoding', {})
# Always prefer gzip over deflate no matter what their q-values are.
if ae.get('gzip', 0):
response.stream = gzipStream(response.stream)
response.headers.setHeader('content-encoding', ['gzip'])
elif ae.get('deflate', 0):
response.stream = deflateStream(response.stream)
response.headers.setHeader('content-encoding', ['deflate'])
return response
__all__ = ['gzipfilter']
|