# -*- coding: utf-8 -*- # gzip_middleware.py # Copyright (C) 2013 LEAP # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ Gzip middleware for WSGI apps. """ import StringIO from gzip import GzipFile class GzipMiddleware(object): """ GzipMiddleware class for WSGI. """ def __init__(self, app, compresslevel=9): self.app = app self.compresslevel = compresslevel def __call__(self, environ, start_response): if 'gzip' not in environ.get('HTTP_ACCEPT_ENCODING', ''): return self.app(environ, start_response) buffer = StringIO.StringIO() output = GzipFile( mode='wb', compresslevel=self.compresslevel, fileobj=buffer ) start_response_args = [] def dummy_start_response(status, headers, exc_info=None): start_response_args.append(status) start_response_args.append(headers) start_response_args.append(exc_info) return output.write app_iter = self.app(environ, dummy_start_response) for line in app_iter: output.write(line) if hasattr(app_iter, 'close'): app_iter.close() output.close() buffer.seek(0) result = buffer.getvalue() headers = [] for name, value in start_response_args[1]: if name.lower() != 'content-length': headers.append((name, value)) headers.append(('Content-Length', str(len(result)))) headers.append(('Content-Encoding', 'gzip')) start_response(start_response_args[0], headers, start_response_args[2]) buffer.close() return [result]