Configurable middleware to add HTTP caching headers for URL's.
Project description
Django Cache Headers
====================
.. figure:: https://travis-ci.org/praekelt/django-cache-headers.svg?branch=develop
:align: center
:alt: 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
--------------------------
# 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
---
#. Ignoring cookies completely when setting headers turned out to be a mistake due to too many security concerns. Restore them.
0.1.3
-----
#. Handle case where user may also be logged in and a cookie not being set.
0.1.2
-----
#. Use the s-maxage header for compatability with Varnish.
0.1.1
-----
#. Leave response untouched if status code is not 200.
0.1
---
#. Initial release.
====================
.. figure:: https://travis-ci.org/praekelt/django-cache-headers.svg?branch=develop
:align: center
:alt: 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
--------------------------
# 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
---
#. Ignoring cookies completely when setting headers turned out to be a mistake due to too many security concerns. Restore them.
0.1.3
-----
#. Handle case where user may also be logged in and a cookie not being set.
0.1.2
-----
#. Use the s-maxage header for compatability with Varnish.
0.1.1
-----
#. Leave response untouched if status code is not 200.
0.1
---
#. Initial release.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django-cache-headers-0.2.tar.gz
.
File metadata
- Download URL: django-cache-headers-0.2.tar.gz
- Upload date:
- Size: 9.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 462cb2af3bddf7a10ad9cde36d296f605f4ccd98a90504c215f29229ccd5ca56 |
|
MD5 | b09a13f24f9bd1e107f94cdc34d6dae7 |
|
BLAKE2b-256 | 95e3f0b76076d4aab77472d0fa990e51aa3345e650243c9977ec10fb19c708cf |
File details
Details for the file django_cache_headers-0.2-py2.7.egg
.
File metadata
- Download URL: django_cache_headers-0.2-py2.7.egg
- Upload date:
- Size: 20.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3bf802bfb3e455e6a5f1e967205bfd6dac3abaa1dc52f05648f54fec4b9d2e84 |
|
MD5 | 7302cd7557e4ed60bdf075e606777ce6 |
|
BLAKE2b-256 | b699d8b608161eacac4d334b5f1e5d93e56f719c13b041a471402f9d13c2e53c |