]> jfr.im git - irc/quakenet/qwebirc.git/blame - qwebirc/util/gziprequest.py
Fix issue #297 (AttributeError with newer versions of Twisted)
[irc/quakenet/qwebirc.git] / qwebirc / util / gziprequest.py
CommitLineData
85f01e3f
CP
1import struct, zlib
2
3class GZipRequest(object):
4 """Wrapper for a request that applies a gzip content encoding"""
5
6 def __init__(self, request, compressLevel=6):
7 self.request = request
8 self.request.setHeader('Content-Encoding', 'gzip')
9 # Borrowed from twisted.web2 gzip filter
10 self.compress = zlib.compressobj(compressLevel, zlib.DEFLATED, -zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL,0)
11
12 def __getattr__(self, attr):
13 if 'request' in self.__dict__:
14 return getattr(self.request, attr)
15
16 raise AttributeError, attr
17
18 def __setattr__(self, attr, value):
19 if 'request' in self.__dict__:
20 return setattr(self.request, attr, value)
21
22 self.__dict__[attr] = value
23
24 def write(self, data):
25 if not self.request.startedWriting:
26 self.crc = zlib.crc32('')
27 self.size = self.csize = 0
28 # XXX: Zap any length for now since we don't know final size
7f1d6ffa
CP
29 if self.request.responseHeaders.hasHeader('content-length'):
30 self.request.responseHeaders.removeHeader('content-length')
85f01e3f
CP
31 # Borrow header information from twisted.web2 gzip filter
32 self.request.write('\037\213\010\000' '\0\0\0\0' '\002\377')
33
34 self.crc = zlib.crc32(data, self.crc)
35 self.size += len(data)
36 cdata = self.compress.compress(data)
37 self.csize += len(cdata)
38 if cdata:
39 self.request.write(cdata)
40 elif self.request.producer:
41 # Simulate another pull even though it hasn't really made it out to the consumer yet.
42 self.request.producer.resumeProducing()
43
44 def finish(self):
45 remain = self.compress.flush()
46 self.csize += len(remain)
47 if remain:
48 self.request.write(remain)
49
50 self.request.write(struct.pack('<LL', self.crc & 0xFFFFFFFFL, self.size & 0xFFFFFFFFL))
51 self.request.finish()