From d93cb4098f91f38ad700d35040888c49e67fcbd7 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 22 Aug 2013 23:53:49 -0500 Subject: [PATCH] website: support 304 Not Modified Change-Id: I711e78d1a138f243bcacbcba3f9559202ee8d808 --- website/TODO | 3 --- website/camweb.go | 26 ++++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) delete mode 100644 website/TODO diff --git a/website/TODO b/website/TODO deleted file mode 100644 index 515b0ec3a..000000000 --- a/website/TODO +++ /dev/null @@ -1,3 +0,0 @@ -TODO: - -- 304 Not-Found support on content pages. diff --git a/website/camweb.go b/website/camweb.go index cc56656d7..7eb230a83 100644 --- a/website/camweb.go +++ b/website/camweb.go @@ -210,12 +210,34 @@ func mainHandler(rw http.ResponseWriter, req *http.Request) { } } - switch { - case !fi.IsDir(): + if !fi.IsDir() { + if checkLastModified(rw, req, fi.ModTime()) { + return + } serveFile(rw, req, relPath, absPath) } } +// modtime is the modification time of the resource to be served, or IsZero(). +// return value is whether this request is now complete. +func checkLastModified(w http.ResponseWriter, r *http.Request, modtime time.Time) bool { + if modtime.IsZero() { + return false + } + + // The Date-Modified header truncates sub-second precision, so + // use mtime < t+1s instead of mtime <= t to check for unmodified. + if t, err := time.Parse(http.TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && modtime.Before(t.Add(1*time.Second)) { + h := w.Header() + delete(h, "Content-Type") + delete(h, "Content-Length") + w.WriteHeader(http.StatusNotModified) + return true + } + w.Header().Set("Last-Modified", modtime.UTC().Format(http.TimeFormat)) + return false +} + func serveFile(rw http.ResponseWriter, req *http.Request, relPath, absPath string) { data, err := ioutil.ReadFile(absPath) if err != nil {