diff --git a/wagtail/contrib/wagtailfrontendcache/purger.py b/wagtail/contrib/wagtailfrontendcache/purger.py index ca00408e2..250f62840 100644 --- a/wagtail/contrib/wagtailfrontendcache/purger.py +++ b/wagtail/contrib/wagtailfrontendcache/purger.py @@ -1,14 +1,33 @@ -from urlparse import urlparse, urlunparse import requests +from requests.adapters import HTTPAdapter from django.conf import settings +class CustomHTTPAdapter(HTTPAdapter): + """ + Requests will always send requests to whatever server is in the netloc + part of the URL. This is a problem with purging the cache as this netloc + may point to a different server (such as an nginx instance running in + front of the cache). + + This class allows us to send a purge request directly to the cache server + with the host header still set correctly. It does this by changing the "url" + parameter of get_connection to always point to the cache server. Requests + will then use this connection to purge the page. + """ + def __init__(self, cache_url): + self.cache_url = cache_url + super(CustomHTTPAdapter, self).__init__() + + def get_connection(self, url, proxies=None): + return super(CustomHTTPAdapter, self).get_connection(self.cache_url, proxies) + + def purge_page_from_cache(page): - # Build purge url - varnish_url = urlparse(getattr(settings, 'WAGTAILFRONTENDCACHE_LOCATION', 'http://127.0.0.1:8000/')) - page_url = urlparse(page.url) - purge_url = urlunparse((varnish_url.scheme, varnish_url.netloc, page_url.path, page_url.params, page_url.query, page_url.fragment)) + varnish_url = getattr(settings, 'WAGTAILFRONTENDCACHE_LOCATION', 'http://127.0.0.1:8000/') # Purge - requests.request('PURGE', purge_url) + session = requests.Session() + session.mount('http://', CustomHTTPAdapter(varnish_url)) + session.request('PURGE', page.full_url)