From 190bca6bc74d4cf80ad8d49eb5e8662f9494f0e4 Mon Sep 17 00:00:00 2001 From: Matt Silverlock Date: Fri, 23 May 2014 17:13:28 +0800 Subject: [PATCH] NoCache middleware - prevents proxies/clients from caching content. --- web/middleware/nocache.go | 56 ++++++++++++++++++++++++++++++++++ web/middleware/nocache_test.go | 29 ++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 web/middleware/nocache.go create mode 100644 web/middleware/nocache_test.go diff --git a/web/middleware/nocache.go b/web/middleware/nocache.go new file mode 100644 index 0000000..54ead3b --- /dev/null +++ b/web/middleware/nocache.go @@ -0,0 +1,56 @@ +package middleware + +import ( + "fmt" + "net/http" + "time" +) + +// Unix epoch time +var epoch = fmt.Sprintf("%s", time.Unix(0, 0).Format(time.RFC1123)) + +// Taken from https://github.com/mytrile/nocache +var noCacheHeaders = map[string]string{ + "Expires": epoch, + "Cache-Control": "no-cache, private, max-age=0", + "Pragma": "no-cache", + "X-Accel-Expires": "0", +} + +var etagHeaders = []string{ + "ETag", + "If-Modified-Since", + "If-Match", + "If-None-Match", + "If-Range", + "If-Unmodified-Since", +} + +// NoCache is a simple piece of middleware that sets a number of HTTP headers to prevent +// a router (or subrouter) from being cached by an upstream proxy and/or client. +// +// As per http://wiki.nginx.org/HttpProxyModule - NoCache sets: +// Expires: Thu, 01 Jan 1970 00:00:00 UTC +// Cache-Control: no-cache, private, max-age=0 +// X-Accel-Expires: 0 +// Pragma: no-cache (for HTTP/1.0 proxies/clients) +func NoCache(h http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + + // Delete any ETag headers that may have been set + for _, v := range etagHeaders { + if r.Header.Get(v) != "" { + r.Header.Del(v) + } + } + + // Set our NoCache headers + for k, v := range noCacheHeaders { + w.Header().Set(k, v) + } + + h.ServeHTTP(w, r) + } + + return http.HandlerFunc(fn) +} diff --git a/web/middleware/nocache_test.go b/web/middleware/nocache_test.go new file mode 100644 index 0000000..1fb71f6 --- /dev/null +++ b/web/middleware/nocache_test.go @@ -0,0 +1,29 @@ +package middleware + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/zenazn/goji/web" +) + +func TestNoCache(t *testing.T) { + + rr := httptest.NewRecorder() + s := web.New() + + s.Use(NoCache) + r, err := http.NewRequest("GET", "/", nil) + if err != nil { + t.Fatal(err) + } + + s.ServeHTTP(rr, r) + + for k, v := range noCacheHeaders { + if rr.HeaderMap[k][0] != v { + t.Errorf("%s header not set by middleware.", k) + } + } +}