Source code for flask_zipper.zipper

from brotli import MODE_GENERIC
from flask import request

from .exceptions import *


[docs]class Zipper(object): """ An object used to hold compressor settings for the Flask-Zipper extension. Instances of :class:`Zipper` are *not* bound to specific apps, so you can create one in the main body of your code and then bind it to your app in a factory function. """ def __init__(self, app=None): """ Create the Flask-Zipper instance. You can either pass a flask application in directly here to register this extension with the flask app, or call init_app after creating this object (in a factory pattern). :param app: A flask application """ self.app = app if app is not None: self.init_app(app)
[docs] def init_app(self, app): """ Register this extension with the flask app. :param app: A flask application """ # Save this so we can use it later in the extension if not hasattr(app, 'extensions'): # pragma: no cover app.extensions = {} app.extensions['flask-zipper'] = self self._set_default_configuration_options(app) self._set_default_errorhandler(app)
[docs] @staticmethod def _set_default_configuration_options(app): """ Sets the default configuration options used by this extension """ # gzip config app.config.setdefault('GZIP_COMPRESS_LEVEL', 9) # brotli config app.config.setdefault('BROTLI_QUALITY_LEVEL', 11) app.config.setdefault('BROTLI_MODE', MODE_GENERIC) app.config.setdefault('BROTLI_SLIDING_WINDOW_SIZE', 22) app.config.setdefault('BROTLI_MAX_INPUT_BLOCK_SIZE', 0) # deflate(zlib) config app.config.setdefault('DEFLATE_COMPRESS_LEVEL', 9)
[docs] @staticmethod def _set_default_errorhandler(app): """ Sets the default error handler used by this extension """ @app.errorhandler(GzipCompressionError) def handle_gzip_compression_error(e): pass @app.errorhandler(BrotliCompressionError) def handle_brotli_compression_error(e): pass @app.errorhandler(DeflateCompressionError) def handle_deflate_compression_error(e): pass
[docs] def encode_response(self, accept_encoding_string: str, compressor, error_class: Exception, response): """ A encoder to compress response with delivered compressor and other arguments :param accept_encoding_string: Content-Encoding argument like `br`, 'deflate', `gzip` :param compressor: Compressor in :mod:`flask_zipper.compressor` :param error_class: Exception in :mod:`flask_zipper.exceptions` :param response: Response object to compress :return: Compressed response """ if accept_encoding_string.upper() not in request.headers.get('Accept-Encoding', '').upper() \ or not 200 <= response.status_code < 300 \ or 'Content-Encoding' in response.headers: # 1. Accept-Encoding에 encode가 포함되어 있지 않거나 # 2. 200번대의 status code로 response하지 않거나 # 3. response header에 이미 Content-Encoding이 명시되어 있는 경우 return response try: compressor(response) response.headers.update({ 'Content-Encoding': accept_encoding_string, 'Vary': 'Accept-Encoding', 'Content-Length': len(response.data) }) except Exception as e: raise error_class(e) finally: return response