diff options
Diffstat (limited to 'system/db')
-rw-r--r-- | system/db/cache.go | 79 | ||||
-rw-r--r-- | system/db/config.go | 11 | ||||
-rw-r--r-- | system/db/content.go | 18 |
3 files changed, 97 insertions, 11 deletions
diff --git a/system/db/cache.go b/system/db/cache.go new file mode 100644 index 0000000..5f2dd03 --- /dev/null +++ b/system/db/cache.go @@ -0,0 +1,79 @@ +package db + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" + "time" +) + +// CacheControl sets the default cache policy on static asset responses +func CacheControl(next http.Handler) http.HandlerFunc { + return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + etag := ConfigCache("etag") + policy := fmt.Sprintf("max-age=%d, public", 60*60*24*30) + res.Header().Add("ETag", etag) + res.Header().Add("Cache-Control", policy) + + if match := req.Header.Get("If-None-Match"); match != "" { + if strings.Contains(match, etag) { + res.WriteHeader(http.StatusNotModified) + return + } + } + + next.ServeHTTP(res, req) + }) +} + +// NewEtag generates a new Etag for response caching +func NewEtag() string { + now := fmt.Sprintf("%d", time.Now().Unix()) + etag := base64.StdEncoding.EncodeToString([]byte(now)) + + return etag +} + +// InvalidateCache sets a new Etag for http responses +func InvalidateCache() error { + kv := make(map[string]interface{}) + + c, err := ConfigAll() + if err != nil { + return err + } + + err = json.Unmarshal(c, &kv) + if err != nil { + return err + } + + kv["etag"] = NewEtag() + + data := make(url.Values) + for k, v := range kv { + switch v.(type) { + case string: + data.Set(k, v.(string)) + case []string: + vv := v.([]string) + for i := range vv { + if i == 0 { + data.Set(k, vv[i]) + } else { + data.Add(k, vv[i]) + } + } + } + } + + err = SetConfig(data) + if err != nil { + + } + + return nil +} diff --git a/system/db/config.go b/system/db/config.go index ab1c720..b5a07e4 100644 --- a/system/db/config.go +++ b/system/db/config.go @@ -2,12 +2,9 @@ package db import ( "bytes" - "encoding/base64" "encoding/json" - "fmt" "net/url" "strings" - "time" "github.com/bosssauce/ponzu/system/admin/config" @@ -124,11 +121,3 @@ func ConfigAll() ([]byte, error) { func ConfigCache(key string) string { return configCache.Get(key) } - -// NewEtag generates a new Etag for response caching -func NewEtag() string { - now := fmt.Sprintf("%d", time.Now().Unix()) - etag := base64.StdEncoding.EncodeToString([]byte(now)) - - return etag -} diff --git a/system/db/content.go b/system/db/content.go index 74a77ec..19c31d7 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -77,6 +77,12 @@ func update(ns, id string, data url.Values) (int, error) { go SortContent(ns) } + // update changes data, so invalidate client caching + err = InvalidateCache() + if err != nil { + return 0, err + } + return cid, nil } @@ -132,6 +138,12 @@ func insert(ns string, data url.Values) (int, error) { go SortContent(ns) } + // insert changes data, so invalidate client caching + err = InvalidateCache() + if err != nil { + return 0, err + } + return effectedID, nil } @@ -149,6 +161,12 @@ func DeleteContent(target string) error { return err } + // delete changes data, so invalidate client caching + err = InvalidateCache() + if err != nil { + return err + } + // exception to typical "run in goroutine" pattern: // we want to have an updated admin view as soon as this is deleted, so // in some cases, the delete and redirect is faster than the sort, |