SVN: r25536 - trunk/quixote
Neil Schemenauer <nascheme-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Thu, 4 Nov 2004 18:30:53 -0500
| Newsgroups | gmane.comp.web.quixote.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: nascheme
Date: 2004-11-04 18:30:44 -0500 (Thu, 04 Nov 2004)
New Revision: 25536
Modified:
trunk/quixote/http_response.py
trunk/quixote/publish.py
Log:
Move page compression functionality to http_response module.
Modified: trunk/quixote/http_response.py
===================================================================
--- trunk/quixote/http_response.py 2004-11-04 23:21:40 UTC (rev 25535)
+++ trunk/quixote/http_response.py 2004-11-04 23:30:44 UTC (rev 25536)
@@ -6,6 +6,11 @@
"""
import time
+try:
+ import zlib
+except ImportError:
+ pass
+import struct
from rfc822 import formatdate
from quixote.html import stringify
@@ -58,7 +63,14 @@
507: 'Insufficient Storage',
}
+_GZIP_HEADER = ("\037\213" # magic
+ "\010" # compression method
+ "\000" # flags
+ "\000\000\000\000" # time, who cares?
+ "\002"
+ "\377")
+
class HTTPResponse:
"""
An object representation of an HTTP response.
@@ -199,16 +211,37 @@
else:
return chunk.encode(self.charset)
- def set_body(self, body):
- """(body : any)
-
- Sets the response body equal to the argument "body".
+ def _compress_body(self, body):
+ """(body: str) -> str
"""
- if isinstance(body, Stream):
- self.body = body
+ n = len(body)
+ co = zlib.compressobj(6, zlib.DEFLATED, -zlib.MAX_WBITS,
+ zlib.DEF_MEM_LEVEL, 0)
+ chunks = [_GZIP_HEADER,
+ co.compress(body),
+ co.flush(),
+ struct.pack("<ll", zlib.crc32(body), n)]
+ compressed_body = "".join(chunks)
+ ratio = float(n) / len(compressed_body)
+ #print "gzip original size %d, ratio %.1f" % (n, ratio)
+ if ratio > 1.1:
+ self.set_header("Content-Encoding", "gzip")
+ return compressed_body
else:
- self.body = self._encode_chunk(stringify(body))
+ return body
+ def set_body(self, body, compress=False):
+ """(body : any, compress : bool = False)
+
+ Sets the response body equal to the argument 'body'. If 'compress'
+ is true then the body may be compressed using 'gzip'.
+ """
+ if not isinstance(body, Stream):
+ body = self._encode_chunk(stringify(body))
+ if compress:
+ body = self._compress_body(body)
+ self.body = body
+
def expire_cookie(self, name, **attrs):
"""
Cause an HTTP cookie to be removed from the browser
Modified: trunk/quixote/publish.py
===================================================================
--- trunk/quixote/publish.py 2004-11-04 23:21:40 UTC (rev 25535)
+++ trunk/quixote/publish.py 2004-11-04 23:30:44 UTC (rev 25536)
@@ -9,7 +9,6 @@
import sys, traceback, cStringIO
import time, re
-import struct
import urlparse
import cgitb
try:
@@ -265,41 +264,10 @@
self.finish_successful_request()
return output
- _GZIP_HEADER = ("\037\213" # magic
- "\010" # compression method
- "\000" # flags
- "\000\000\000\000" # time, who cares?
- "\002"
- "\377")
-
- _GZIP_THRESHOLD = 200 # responses smaller than this are not compressed
-
- def compress_output(self, request, output):
- encoding = request.get_encoding(["gzip", "x-gzip"])
- n = len(output)
- if n > self._GZIP_THRESHOLD and encoding:
- co = zlib.compressobj(6, zlib.DEFLATED, -zlib.MAX_WBITS,
- zlib.DEF_MEM_LEVEL, 0)
- chunks = [self._GZIP_HEADER,
- co.compress(output),
- co.flush(),
- struct.pack("<ll", zlib.crc32(output), len(output))]
- output = "".join(chunks)
- #self.log("gzip (original size %d, ratio %.1f)" %
- # (n, float(n)/len(output)))
- request.response.set_header("Content-Encoding", encoding)
- return output
-
def filter_output(self, request, output):
"""Hook for post processing the output. Subclasses may wish to
override (e.g. check HTML syntax).
"""
- if 0:
- # XXX need to use charset from response
- if (output and
- self.config.compress_pages and
- not isinstance(output, Stream)):
- output = self.compress_output(request, str(output))
return output
def process_request(self, request):
@@ -332,7 +300,11 @@
output = self.filter_output(request, output)
self.logger.log_request(request, start_time)
if output:
- request.response.set_body(output)
+ if self.config.compress_pages and request.get_encoding(["gzip"]):
+ compress = True
+ else:
+ compress = False
+ request.response.set_body(output, compress)
self._clear_request()
return request.response