From 6932cfd8c47583dae05e94568e4ed510432f3bb3 Mon Sep 17 00:00:00 2001 From: Andy Babic Date: Fri, 10 May 2024 09:16:55 +0100 Subject: [PATCH] Implement 'purge_everything' method the Cloudflare front-end cache backend --- wagtail/contrib/frontend_cache/backends.py | 70 ++++++++++++---------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/wagtail/contrib/frontend_cache/backends.py b/wagtail/contrib/frontend_cache/backends.py index 7f6f2fdd495e..9a10f9c70d99 100644 --- a/wagtail/contrib/frontend_cache/backends.py +++ b/wagtail/contrib/frontend_cache/backends.py @@ -40,6 +40,9 @@ def invalidates_hostname(self, hostname): """ return validate_host(hostname, self.hostnames) + def purge_everything(self): + raise NotImplementedError + class HTTPBackend(BaseBackend): def __init__(self, params): @@ -118,42 +121,28 @@ def __init__(self, params): "The setting 'WAGTAILFRONTENDCACHE' requires both 'EMAIL' and 'API_KEY', or 'BEARER_TOKEN' to be specified." ) - def _purge_urls(self, urls): - try: - purge_url = ( - "https://api.cloudflare.com/client/v4/zones/{}/purge_cache".format( - self.cloudflare_zoneid - ) - ) - - headers = {"Content-Type": "application/json"} - - if self.cloudflare_token: - headers["Authorization"] = f"Bearer {self.cloudflare_token}" - else: - headers["X-Auth-Email"] = self.cloudflare_email - headers["X-Auth-Key"] = self.cloudflare_api_key + def _make_purge_request(self, urls, method="DELETE"): + headers = {"Content-Type": "application/json"} + if self.cloudflare_token: + headers["Authorization"] = f"Bearer {self.cloudflare_token}" + else: + headers["X-Auth-Email"] = self.cloudflare_email + headers["X-Auth-Key"] = self.cloudflare_api_key + if urls: data = {"files": urls} + else: + data = None - response = requests.delete( - purge_url, + try: + response = requests.request( + method=method, + url="https://api.cloudflare.com/client/v4/zones/{}/purge_cache".format( + self.cloudflare_zoneid + ), json=data, headers=headers, ) - - try: - response_json = response.json() - except ValueError: - if response.status_code != 200: - response.raise_for_status() - else: - for url in urls: - logger.error( - "Couldn't purge '%s' from Cloudflare. Unexpected JSON parse error.", - url, - ) - except requests.exceptions.HTTPError as e: for url in urls: logging.exception( @@ -163,6 +152,19 @@ def _purge_urls(self, urls): ) return + try: + response_json = response.json() + except ValueError: + if response.status_code != 200: + response.raise_for_status() + else: + for url in urls: + logger.error( + "Couldn't purge '%s' from Cloudflare. Unexpected JSON parse error.", + url, + ) + return + if response_json["success"] is False: error_messages = ", ".join( [str(err["message"]) for err in response_json["errors"]] @@ -179,11 +181,13 @@ def purge_batch(self, urls): # Break the batched URLs in to chunks to fit within Cloudflare's maximum size for # the purge_cache call (https://api.cloudflare.com/#zone-purge-files-by-url) for i in range(0, len(urls), self.CHUNK_SIZE): - chunk = urls[i : i + self.CHUNK_SIZE] - self._purge_urls(chunk) + self._make_purge_request(urls[i : i + self.CHUNK_SIZE]) def purge(self, url): - self.purge_batch([url]) + self._make_purge_request(urls=[url]) + + def purge_everything(self): + self._make_purge_request(urls=None, method="POST") class CloudfrontBackend(BaseBackend):