From 8f7f5be71ceba7c534ce5822244a9b96d2aad0a3 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Thu, 26 Dec 2013 19:04:35 -0800 Subject: [PATCH] etag and last-modified support on incoming requests fixes #3 --- proxy/proxy.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index 71ff407..b5e5f22 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -24,6 +24,7 @@ import ( "net/http" "net/url" "reflect" + "time" "github.com/golang/glog" "github.com/gregjones/httpcache" @@ -102,9 +103,16 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - w.Header().Add("Content-Length", resp.Header.Get("Content-Length")) + w.Header().Add("Last-Modified", resp.Header.Get("Last-Modified")) w.Header().Add("Expires", resp.Header.Get("Expires")) + w.Header().Add("Etag", resp.Header.Get("Etag")) + if is304 := check304(w, r, resp); is304 { + w.WriteHeader(http.StatusNotModified) + return + } + + w.Header().Add("Content-Length", resp.Header.Get("Content-Length")) defer resp.Body.Close() io.Copy(w, resp.Body) } @@ -124,6 +132,27 @@ func (p *Proxy) allowed(u *url.URL) bool { return false } +func check304(w http.ResponseWriter, req *http.Request, resp *http.Response) bool { + etag := resp.Header.Get("Etag") + if etag != "" && etag == req.Header.Get("If-None-Match") { + return true + } + + lastModified, err := time.Parse(time.RFC1123, resp.Header.Get("Last-Modified")) + if err != nil { + return false + } + ifModSince, err := time.Parse(time.RFC1123, req.Header.Get("If-Modified-Since")) + if err != nil { + return false + } + if lastModified.Before(ifModSince) { + return true + } + + return false +} + // TransformingTransport is an implementation of http.RoundTripper that // optionally transforms images using the options specified in the request URL // fragment.