Files
postgres-web/pgweb/util/misc.py
Magnus Hagander f92709d2a6 Implement basic varnish purging
This allows all models inherited from PgModel to specify which
URLs to purge by either setting a field or defining a function
called purge_urls, at which point they will be purged whenever
the save signal is fired.

Also implements a form under /admin/purge/ that allows for manual
purging. This should probably be extended in the future to show
the status of the pgq slaves, but that will come later.

Includes a SQL function that posts the expires to a pgq queue. For
a local deployment, this can be replaced with a simple void function
to turn off varnish purging.
2011-06-14 19:48:48 +02:00

73 lines
2.3 KiB
Python

from subprocess import Popen, PIPE
from email.mime.text import MIMEText
from django.db import connection
from django.conf import settings
from pgweb.util.helpers import template_to_string
def sendmail(msg):
pipe = Popen("sendmail -t", shell=True, stdin=PIPE).stdin
pipe.write(msg.as_string())
pipe.close()
def send_template_mail(sender, receiver, subject, templatename, templateattr={}):
msg = MIMEText(
template_to_string(templatename, templateattr),
_charset='utf-8')
msg['Subject'] = subject
msg['To'] = receiver
msg['From'] = sender
sendmail(msg)
def is_behind_cache(request):
"""
Determine if the client is behind a cache. In this, we are only interested in our own
frontend caches, we don't care about any client side caches or such things.
"""
if request.is_secure():
# We never proxy https requests, so shortcut the check if it's there
return False
if request.META.has_key('HTTP_X_VARNISH'):
# So, it's a varnish cache. Check that it's one of our frontends
if request.META['REMOTE_ADDR'] in settings.FRONTEND_SERVERS:
# Yup, it's one of our varnish servers, so we're behind a cache
return True
else:
# It's someone elses varnish? Or misconfigured? Either way, don't claim
# it's behind a cache.
return False
# X-Varnish not set, clearly we're not behind a cache
return False
def get_client_ip(request):
"""
Get the IP of the client. If the client is served through our Varnish caches,
make sure we get the *actual* client IP, and not the IP of the Varnish cache.
"""
if is_behind_cache:
# When we are served behind a cache, our varnish is (should) always be configured
# to set the X-Forwarded-For header. It will also remove any previous such header,
# so we can always trust that header if it's there.
try:
return request.META['HTTP_X_FORWARDED_FOR']
except:
# In case something failed, we'll return the remote address. This is most likely
# the varnish server itself, but it's better than aborting the request.
return request.META['REMOTE_ADDR']
else:
return request.META['REMOTE_ADDR']
def varnish_purge(url):
"""
Purge the specified URL from Varnish. Will add initial anchor to the URL,
but no trailing one, so by default a wildcard match is done.
"""
url = '^%s' % url
connection.cursor().execute("SELECT varnish_purge(%s)", (url, ))