client-side caching for avatars

This commit is contained in:
Umputun
2018-05-12 13:03:01 -05:00
parent 70c910b21a
commit 9cacdb1497
2 changed files with 20 additions and 1 deletions
+19
View File
@@ -8,6 +8,7 @@ import (
"net/http"
"os"
"path"
"strconv"
"strings"
"sync"
"time"
@@ -87,7 +88,20 @@ func (p *AvatarProxy) Routes() (string, chi.Router) {
// GET /123456789.image
router.Get("/{avatar}", func(w http.ResponseWriter, r *http.Request) {
avatar := chi.URLParam(r, "avatar")
// client-side caching
etag := `"` + avatar + `"`
w.Header().Set("Etag", etag)
w.Header().Set("Cache-Control", "max-age=2592000") // 30 days
if match := r.Header.Get("If-None-Match"); match != "" {
if strings.Contains(match, etag) {
w.WriteHeader(http.StatusNotModified)
return
}
}
location := p.location(strings.TrimSuffix(avatar, imgSfx))
avFile := path.Join(location, avatar)
fh, err := os.Open(avFile)
@@ -103,6 +117,11 @@ func (p *AvatarProxy) Routes() (string, chi.Router) {
}()
w.Header().Set("Content-Type", "image/*")
if fi, err := fh.Stat(); err == nil {
w.Header().Set("Content-Length", strconv.Itoa(int(fi.Size())))
}
// write all headers
if status, ok := r.Context().Value(render.StatusCtxKey).(int); ok {
w.WriteHeader(status)
}
+1 -1
View File
@@ -85,7 +85,7 @@ func TestRoutes(t *testing.T) {
handler.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)
assert.Equal(t, http.Header{"Content-Type": []string{"image/*"}}, rr.HeaderMap)
assert.EqualValues(t, http.Header{"Content-Type": []string{"image/*"}, "Content-Length": []string{"21"}}, rr.HeaderMap)
bb := bytes.Buffer{}
sz, err := io.Copy(&bb, rr.Body)
assert.NoError(t, err)