Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Flash-caching results in caching of non-compressed files #44

Open
Kacper-Lisikiewicz-THG opened this issue Oct 4, 2023 · 0 comments

Comments

@Kacper-Lisikiewicz-THG
Copy link

When using the flask-caching===2.0.2 library together with flask-compress==1.14.0 I run into an issue where the caching doesn't work properly.
I tested three scenarios:

using just the @cache.cached(timeout=600, query_string=True) decorator:
as expected the cached response is not compressed but the one served to the webpage is compressed

using the @cache.cached(timeout=600, query_string=True) decorator and

    compress.cache = cache
    compress.cache_key = get_cache_key
    
    # Define a function to return cache key for incoming requests
def get_cache_key(request):
    return request.url

Taking the get_cache_key function from documentation results in caching both the non-compressed response and the compressed response.

def get_cache_key(request):
    args_as_sorted_tuple = tuple(
        sorted(pair for pair in request.args.items(multi=True))
    )
    # ... now hash the sorted (key, value) tuple so it can be
    # used as a key for cache. Turn them into bytes so that the
    # hash function will accept them
    args_as_bytes = str(args_as_sorted_tuple).encode()
    cache_hash = hashlib.md5(args_as_bytes)

    cache_hash = str(cache_hash.hexdigest())

    cache_key = request.path + cache_hash

    return cache_key

unifying the get_cache_key functions so that they return the same cache key results in an error

eds-eds-1 | Traceback (most recent call last):
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 271, in handle
eds-eds-1 | keepalive = self.handle_request(req, conn)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 323, in handle_request
eds-eds-1 | respiter = self.wsgi(environ, resp.start_response)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2213, in call
eds-eds-1 | return self.wsgi_app(environ, start_response)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2193, in wsgi_app
eds-eds-1 | response = self.handle_exception(e)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask_cors/extension.py", line 165, in wrapped_function
eds-eds-1 | return cors_after_request(app.make_response(f(*args, **kwargs)))
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2190, in wsgi_app
eds-eds-1 | response = self.full_dispatch_request()
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1487, in full_dispatch_request
eds-eds-1 | return self.finalize_request(rv)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1508, in finalize_request
eds-eds-1 | response = self.process_response(response)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2002, in process_response
eds-eds-1 | response = self.ensure_sync(func)(response)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask_compress/flask_compress.py", line 208, in after_request
eds-eds-1 | response.set_data(compressed_content)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/werkzeug/wrappers/response.py", line 302, in set_data
eds-eds-1 | self.headers["Content-Length"] = str(len(value))
eds-eds-1 | TypeError: object of type 'Response' has no len()

I want to cache only the compressed response to save resources, am I doing something wrong, or is that a bug in either of the packages?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant