From 7becbd6aadee548e6ed19f913008e65dd339d8b4 Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Wed, 29 Jul 2020 22:45:26 +0200 Subject: [PATCH] Implement basic db-based cache --- cache.go | 53 ++++++++++++++++++++++++++++++++++++++++++ config.go | 16 +++++++++++++ database_migrations.go | 7 ++++++ http.go | 4 ++-- posts.go | 9 +++++-- 5 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 cache.go diff --git a/cache.go b/cache.go new file mode 100644 index 0000000..bf2925e --- /dev/null +++ b/cache.go @@ -0,0 +1,53 @@ +package main + +import ( + "context" + "net/http" + "net/url" + "time" +) + +func CacheMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + requestUrl, _ := url.ParseRequestURI(r.RequestURI) + if appConfig.cache.enable && + // Check bypass query + !(requestUrl != nil && requestUrl.Query().Get("cache") == "0") { + mime, t, cache := getCache(SlashTrimmedPath(r), r.Context()) + if cache == nil { + next.ServeHTTP(w, r) + return + } else { + expiresTime := time.Unix(t+appConfig.cache.expiration, 0).Format(time.RFC1123) + w.Header().Set("Expires", expiresTime) + w.Header().Set("Content-Type", mime) + _, _ = w.Write(cache) + } + } else { + next.ServeHTTP(w, r) + } + }) +} + +func getCache(path string, context context.Context) (string, int64, []byte) { + var mime string + var t int64 + var cache []byte + allowedTime := time.Now().Unix() - appConfig.cache.expiration + row := appDb.QueryRowContext(context, "select COALESCE(mime, ''), COALESCE(time, 0), value from cache where path=? and time>=?", path, allowedTime) + _ = row.Scan(&mime, &t, &cache) + return mime, t, cache +} + +func saveCache(path string, mime string, value []byte) { + now := time.Now().Unix() + startWritingToDb() + tx, err := appDb.Begin() + if err != nil { + return + } + _, _ = tx.Exec("delete from cache where time