class GzipHttpOnlyMiddleware(object): ''' Wraps django's default GZIP middleware to only GZIP HTTP Requests, not HTTPS thus sidestepping the BREACH vulnerability on HTTPS pages and getting gzip performance improvements on HTTP pages Overview of BREACH and django: http://stacks.11craft.com/what-is-breach-how-can-we-protect-django-projects-against-it.html Alternate BREACH mitigation: https://github.com/lpomfrey/django-debreach https://github.com/jsocol/django-ratelimit ''' def __init__(self, *args, **kwargs): self.gzip_middleware = GZipMiddleware(*args, **kwargs) def process_response(self, request, response): if CONVOY_CONSERVATIVE_MSIE_GZIP: if "msie" in request.META.get('HTTP_USER_AGENT', '').lower(): return response if hasattr(request, 'scheme') and request.scheme is 'https': # scheme property wasn't added until late 2013 # https://code.djangoproject.com/ticket/7603 return response if request.is_secure(): return response if request.META.get("HTTP_X_FORWARDED_PROTO", "") == 'https': return response return self.gzip_middleware.process_response(request, response)
def records(request): query = request.GET.copy() records = None record_filter = query.pop("filter", ["none"])[0].lower() record_format = query.pop("format", ["json"])[0].lower() record_sort = query.pop("sort", ["none"])[0].lower() cached_records = query.pop("cached", ["true"])[0].lower() in ("yes", "true") compress_records = query.pop("compress", ["true"])[0].lower() in ("yes", "true") pretty_records = query.pop("pretty", ["false"])[0].lower() in ("yes", "true") cache_key = "UI_REQUEST(%s)" % hash_to_query(query) geocode_records = query.pop("geocode", ["false"])[0].lower() in ("yes", "true") remap_records = query.pop("remap", ["false"])[0].lower() in ("yes", "true") if config.UI_CACHE_REQUESTS and cached_records: records = models.cache_get_records(cache_key) if records is None: logger.info("Not using UI cache for %s" % cache_key) records = models.query_ls(query=query, cached_records=cached_records) if geocode_records: records = models.geocode_records(records) if remap_records: records = models.remap_records(records) if config.UI_CACHE_REQUESTS: models.cache_set_records(cache_key, records, config.UI_CACHE_TIMEOUT) else: logger.info("Using UI cache for %s" % cache_key) if record_filter in ("default",): records = models.filter_default(records) if record_sort not in ("none",): records = sorted(records, key=lambda v: v.get(record_sort, "")) if record_format in ("html",): context = {} if pretty_records: context = {"records": records, "pretty": True} else: context = {"records": records, "pretty": False} response = render(request, "servicesDirectory/records.html", context) else: content = "" if pretty_records or record_format in ("pretty",): content = json.dumps(records, sort_keys=True, indent=4) else: content = json.dumps(records) response = HttpResponse(content, content_type="application/json") if compress_records: gzip = GZipMiddleware() return gzip.process_response(request, response) else: return response
def test_middleware_wont_compress_if_response_is_already_compressed(self): fake_request = FakeRequestAcceptsBrotli() response_content = UTF8_LOREM_IPSUM_IN_CZECH fake_response = FakeResponse(content=response_content) brotli_middleware = BrotliMiddleware() django_gzip_middleware = GZipMiddleware() gzip_response = django_gzip_middleware.process_response( fake_request, fake_response) brotli_response = brotli_middleware.process_response( fake_request, gzip_response) self.assertEqual( response_content, gzip.decompress(brotli_response.content).decode(encoding='utf-8'))
def test_middleware_wont_compress_if_client_not_accept(self): fake_request = FakeLegacyRequest() response_content = UTF8_LOREM_IPSUM_IN_CZECH fake_response = FakeResponse(content=response_content) compression_middleware = CompressionMiddleware() response = compression_middleware.process_response( fake_request, fake_response) django_gzip_middleware = GZipMiddleware() gzip_response = django_gzip_middleware.process_response( fake_request, fake_response) self.assertEqual(response_content, response.content.decode(encoding='utf-8')) self.assertEqual(response.get('Vary'), 'Accept-Encoding')
def wrapped_function(request, layer_name, z, x, y): x, y, z = int(x), int(y), int(z) tile_cache_path = os.path.realpath(settings.STATIC_ROOT + '/tiles') layer = Layer.objects.get(name=layer_name) name = layer.query_hash() tile_path = tile_cache_path + '/{}/{}/{}/{}.pbf'.format(name, z, x, y) if not os.path.isfile(tile_path): response = func(request, name, z, x, y) else: print "Sending cached tile..." response = HttpResponse(content_type='application/x-protobuf') with open(tile_path, 'rb') as f: response.write(f.read()) gzip_middleware = GZipMiddleware() response = gzip_middleware.process_response(request, response) return response
def patch_gzip_response(response, request): if not response.status_code == 200: return # nocv GZipMiddleware.process_response(None, request, response)