[Web-SIG] Re: Latest WSGI Draft (Phillip J. Eby)

Ian Bicking ianb at colorstudy.com
Tue Aug 24 18:26:27 CEST 2004


Peter Hunt wrote:
> Is there a "Hello, world!" type of middleware that I could take a look at?

I haven't tested this (but I'll try to tonight), but here's perhaps a 
more realistic middleware.  This compresses (with gzip) the response 
from the application (if it is allowed to):

import gzip
from cStringIO import StringIO

class gzip_middleware(object):

     def __init__(self, application, compress_level=5):
         self.application = application
         self.compress_level = compress_level

     def __call__(self, environ, start_response):
         if 'gzip' not in environ.get('HTTP_ACCEPT'):
             # nothing for us to do, so this middleware will
             # be a no-op:
             return application(environ, start_response)
         response = GzipResponse(start_response, self.compress_level)
         app_iter = self.application(environ,
                                     response.gzip_start_response)
         response.finish_response(app_iter)
         return None

class GzipResponse(object):

     def __iter__(self, start_response, compress_level):
         self.start_response = start_response
         self.compress_level = compress_level
         self.gzip_fileobj = None

     def gzip_start_response(self, status, headers):
         # This isn't part of the spec yet:
         if headers.has_key('content-encoding'):
             # we won't double-encode
             return self.start_response(status, headers)

         headers['content-encoding'] = 'gzip'
         raw_writer = self.start_response(status, headers)
         dummy_fileobj = object()
         dummy_fileobj.write = raw_writer
         self.gzip_fileobj = GzipFile('', 'wb', self.compress_level,
                                      dummy_fileobj)
         return self.gzip_fileobj.write

     def finish_response(self, app_iter):
         try:
             for s in app_iter:
                 self.gzip_fileobj.write(s)
         finally:
             if hasattr(app_iter, 'close'):
                 app_iter.close()
             self.gzip_fileobj.close()




Hmm... For a very simple filter, I actually found that surprisingly 
difficult to write.  And I think it should take advantage of its 
server's iteration, but currently it only uses the "push" (write 
function) aspect of the server.  But I'm not sure how exactly I would do 
that, especially so that the iteration actually had any beneficial 
properties.

-- 
Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org


More information about the Web-SIG mailing list