From 12a8de3ee42e5b94509649745e97e30f2f51fa51 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sun, 18 Jun 2023 07:25:40 +0200 Subject: CachingMiddleware: avoid using a heterogeneous list for the cached request Type checkers tend to deal badly with heterogeneous lists and we cannot use a tuple here, because it needs to be modifiable. The attachment of names also improves clarity. --- wsgitools/middlewares.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/wsgitools/middlewares.py b/wsgitools/middlewares.py index 3e48ee0..8dca2e0 100644 --- a/wsgitools/middlewares.py +++ b/wsgitools/middlewares.py @@ -219,6 +219,14 @@ __all__.append("CachingMiddleware") class CachingMiddleware(object): """Caches reponses to requests based on C{SCRIPT_NAME}, C{PATH_INFO} and C{QUERY_STRING}.""" + + class CachedRequest(object): + def __init__(self, timestamp): + self.timestamp = timestamp + self.status = "" + self.headers = [] + self.body = [] + def __init__(self, app, maxage=60, storable=storable, cacheable=cacheable): """ @param app: is a wsgi application to be cached. @@ -255,7 +263,7 @@ class CachingMiddleware(object): except KeyError: pass else: - if obj[0] <= old: + if obj.timestamp <= old: del self.cache[key] def __call__(self, environ, start_response): @@ -273,26 +281,26 @@ class CachingMiddleware(object): path += "?" + environ.get("QUERY_STRING", "") if path in self.cache and self.cacheable(environ): cache_object = self.cache[path] - if cache_object[0] + self.maxage >= now: - start_response(cache_object[1], list(cache_object[2])) - return cache_object[3] + if cache_object.timestamp + self.maxage >= now: + start_response(cache_object.status, list(cache_object.headers)) + return cache_object.body else: del self.cache[path] - cache_object = [now, "", [], []] + cache_object = self.CachedRequest(now) def modified_start_respesponse(status, headers, exc_info=None): try: - if cache_object[3]: + if cache_object.body: assert exc_info is not None raise exc_info_for_raise(exc_info) finally: exc_info = None assert isinstance(status, str) assert isinstance(headers, list) - cache_object[1] = status - cache_object[2] = headers + cache_object.status = status + cache_object.headers = headers write = start_response(status, list(headers)) def modified_write(data): - cache_object[3].append(data) + cache_object.body.append(data) write(data) return modified_write @@ -300,12 +308,12 @@ class CachingMiddleware(object): assert hasattr(ret, "__iter__") if isinstance(ret, list): - cache_object[3].extend(ret) + cache_object.body.extend(ret) self.insert_cache(path, cache_object, now) return ret def pass_through(): for data in ret: - cache_object[3].append(data) + cache_object.body.append(data) yield data self.insert_cache(path, cache_object, now) return CloseableIterator(getattr(ret, "close", None), pass_through()) -- cgit v1.2.3