Skip to main content

Configurable middleware to add HTTP caching headers for URL's.

Project description

Django Cache Headers

Travis

Overview

Django Cache Headers allows you to set HTTP caching headers for URL patterns according to certain policies. It does not perform any caching itself - it merely sets the headers on the response which are then interpreted by eg. Nginx.

Installation

  1. Install or add django-cache-headers to your Python path.

  2. Add cache_headers to your INSTALLED_APPS setting.

  3. Add cache_headers.middleware.CacheHeadersMiddleware before SessionMiddleware and AuthenticationMiddleware to your MIDDLEWARE_CLASSES setting.

Policies

Django Cache Headers provides four caching policies. You may define your own policies.:

  1. all-users - response is marked as cached once for all users.

  2. anonymous-only - response is marked as cached once only for anonymous users.

  3. anonymous-and-authenticated - response is marked as cached once for anonymous users and once for authenticated users.

  4. per-user - response is marked as cached once for anonymous users and for each authenticated user individually.

Sample Varnish config file

Save this snippet as /etc/varnish/default.vcl:

# Use 4.0 format
vcl 4.0;

# Default upstream
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

# Access control
acl purge {
    "localhost";
    "127.0.0.1";
}

# vcl_recv adapted from the Varnish default
sub vcl_recv {
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return(synth(405, "Not allowed."));
        }
        return(purge);
    }

    if (req.method == "PRI") {
        # We do not support SPDY or HTTP/2.0
        return(synth(405));
    }

    if (req.method != "GET" &&
      req.method != "HEAD" &&
      req.method != "PUT" &&
      req.method != "POST" &&
      req.method != "TRACE" &&
      req.method != "OPTIONS" &&
      req.method != "DELETE") {
        # Non-RFC2616 or CONNECT which is weird
        return(pipe);
    }

    if (req.method != "GET" && req.method != "HEAD") {
        # We only deal with GET and HEAD by default
        return(pass);
    }
    if (req.http.Authorization) {
        # Not cacheable by default
        return(pass);
    }
    return(hash);
}

# Useful headers
sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    } else {
        set resp.http.X-Cache = "MISS";
    }
}

sub vcl_hash {
    # Cache even with cookies present. Note we don't delete the cookies.
    # Also, we only consider cookies in X-Cookie-Hash as part of the hash.
    # This value is set by the relevant Django Cache Headers policy.
    set req.http.X-Cookie-Hash = "";
    if (req.http.X-Hash-Cookies) {
        set req.http.X-Cookie-Pattern = ";("  + req.http.X-Hash-Cookies + ")=";
        set req.http.X-Cookie-Hash = ";" + req.http.Cookie;
        # VCL does not currently support variables in regsuball, so hardcode
        #set req.http.X-Cookie-Hash = regsuball(req.http.X-Cookie-Hash, req.http.X-Cookie-Pattern, "; \1=");
        if (req.http.X-Cookie-Hash == "messages") {
                set req.http.X-Cookie-Hash = regsuball(req.http.X-Cookie-Hash, ";(messages)=", "; \1=");
        }
        if (req.http.X-Cookie-Hash == "messages|isauthenticated") {
                set req.http.X-Cookie-Hash = regsuball(req.http.X-Cookie-Hash, ";(messages|isauthenticated)=", "; \1=");
        }
        if (req.http.X-Cookie-Hash == "messages|sessionid") {
                set req.http.X-Cookie-Hash = regsuball(req.http.X-Cookie-Hash, ";(messages|sessionid)=", "; \1=");
        }
        set req.http.X-Cookie-Hash = regsuball(req.http.X-Cookie-Hash, ";[^ ][^;]*", "");
        set req.http.X-Cookie-Hash = regsuball(req.http.X-Cookie-Hash, "^[; ]+|[; ]+$", "");
    }
    hash_data(req.http.X-Cookie-Hash);
}

Settings

The timeouts key combines the policy, timeout in seconds and URL regexes in a nested dictionary:

CACHE_HEADERS = {
    "timeouts": {
        "all-users": {
            60: (
                "^/all-users/",
            )
        },
        "anonymous-only": {
            60: (
                "^/anonymous-only/",
            )
        },
        "anonymous-and-authenticated": {
            60: (
                "^/anonymous-and-authenticated/",
            )
        },
        "per-user": {
            60: (
                "^/per-user/",
            )
        },
        "custom-policy": {
            60: (
                "^/custom-policy/",
            )
        }
    }
}

Authors

Praekelt Consulting

  • Hedley Roos

Changelog

0.2.2

  1. Iterate over regexes in order of most specific (longest) to least specific (shortest).

  2. Revert OrderedDict change since it is not required anymore due to the above change.

0.2.1

  1. Use an OrderedDict for guaranteed policy iteration order.

0.2

  1. Ignoring cookies completely when setting headers turned out to be a mistake due to too many security concerns. Restore them.

0.1.3

  1. Handle case where user may also be logged in and a cookie not being set.

0.1.2

  1. Use the s-maxage header for compatability with Varnish.

0.1.1

  1. Leave response untouched if status code is not 200.

0.1

  1. Initial release.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-cache-headers-0.2.2.tar.gz (9.2 kB view details)

Uploaded Source

Built Distribution

django_cache_headers-0.2.2-py2.7.egg (21.3 kB view details)

Uploaded Source

File details

Details for the file django-cache-headers-0.2.2.tar.gz.

File metadata

File hashes

Hashes for django-cache-headers-0.2.2.tar.gz
Algorithm Hash digest
SHA256 1e5a0c3339cb9b7779cbf6e9b4bb160bc0d4b9e9faf52ae38b24e42d869ffb91
MD5 1c1522d3a26338a0778f216537147a7f
BLAKE2b-256 b68e36320ca90fc6e75b1ebd5eb4661f744114851c8fecd0775b24bd09bb14ab

See more details on using hashes here.

File details

Details for the file django_cache_headers-0.2.2-py2.7.egg.

File metadata

File hashes

Hashes for django_cache_headers-0.2.2-py2.7.egg
Algorithm Hash digest
SHA256 9b8a02d2a17cbfa8070da11ffc356fb8c85bdd6ed196888389a4923374c858d9
MD5 a470c2fc19a5deac7348a750d3ab240c
BLAKE2b-256 ab53cbfa8a7ca62cc42262c4d4cc2d4625510eac2c1c1f3b8a39dfaf8f8f4992

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page