From c1c1bb2c4c1baf37dbcce96f144966d4ada65ac5 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Mon, 23 Jan 2023 22:30:30 +0100 Subject: Implement cache and logger middlewares for gemini --- src/http/apiutil/apiutil.go | 3 +++ src/http/http.go | 14 ++++---------- src/http/middleware.go | 23 ++++++++++++++--------- 3 files changed, 21 insertions(+), 19 deletions(-) (limited to 'src/http') diff --git a/src/http/apiutil/apiutil.go b/src/http/apiutil/apiutil.go index 1fbadea..c59104c 100644 --- a/src/http/apiutil/apiutil.go +++ b/src/http/apiutil/apiutil.go @@ -16,6 +16,9 @@ import ( "github.com/mediocregopher/mediocre-go-lib/v2/mlog" ) +// TODO I don't think Set/GetRequestLogger are necessary? Seems sufficient to +// just annotate the request's context + type loggerCtxKey int // SetRequestLogger sets the given Logger onto the given Request's Context, diff --git a/src/http/http.go b/src/http/http.go index 98cdde3..d51671d 100644 --- a/src/http/http.go +++ b/src/http/http.go @@ -15,7 +15,7 @@ import ( "strings" "time" - lru "github.com/hashicorp/golang-lru" + "github.com/mediocregopher/blog.mediocregopher.com/srv/cache" "github.com/mediocregopher/blog.mediocregopher.com/srv/cfg" "github.com/mediocregopher/blog.mediocregopher.com/srv/http/apiutil" "github.com/mediocregopher/blog.mediocregopher.com/srv/mailinglist" @@ -33,6 +33,7 @@ var staticFS embed.FS type Params struct { Logger *mlog.Logger PowManager pow.Manager + Cache cache.Cache PostStore post.Store PostAssetStore post.AssetStore @@ -190,13 +191,6 @@ func (a *api) apiHandler() http.Handler { func (a *api) blogHandler() http.Handler { - cache, err := lru.New(5000) - - // instantiating the lru cache can't realistically fail - if err != nil { - panic(err) - } - mux := http.NewServeMux() mux.Handle("/posts/", http.StripPrefix("/posts", @@ -244,11 +238,11 @@ func (a *api) blogHandler() http.Handler { readOnlyMiddlewares := []middleware{ logReqMiddleware, // only log GETs on cache miss - cacheMiddleware(cache), + cacheMiddleware(a.params.Cache, a.params.PublicURL), } readWriteMiddlewares := []middleware{ - purgeCacheOnOKMiddleware(cache), + purgeCacheOnOKMiddleware(a.params.Cache), authMiddleware(a.auther), } diff --git a/src/http/middleware.go b/src/http/middleware.go index b82fc29..a21511f 100644 --- a/src/http/middleware.go +++ b/src/http/middleware.go @@ -4,11 +4,12 @@ import ( "bytes" "net" "net/http" + "net/url" "path/filepath" "sync" "time" - lru "github.com/hashicorp/golang-lru" + "github.com/mediocregopher/blog.mediocregopher.com/srv/cache" "github.com/mediocregopher/blog.mediocregopher.com/srv/http/apiutil" "github.com/mediocregopher/mediocre-go-lib/v2/mctx" "github.com/mediocregopher/mediocre-go-lib/v2/mlog" @@ -86,6 +87,9 @@ func (rw *wrappedResponseWriter) WriteHeader(statusCode int) { } func logReqMiddleware(h http.Handler) http.Handler { + + type logCtxKey string + return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { wrw := newWrappedResponseWriter(rw) @@ -94,8 +98,6 @@ func logReqMiddleware(h http.Handler) http.Handler { h.ServeHTTP(wrw, r) took := time.Since(started) - type logCtxKey string - ctx := r.Context() ctx = mctx.Annotate(ctx, logCtxKey("took"), took.String(), @@ -139,7 +141,7 @@ func (rw *cacheResponseWriter) Write(b []byte) (int, error) { return rw.wrappedResponseWriter.Write(b) } -func cacheMiddleware(cache *lru.Cache) middleware { +func cacheMiddleware(cache cache.Cache, publicURL *url.URL) middleware { type entry struct { body []byte @@ -153,11 +155,14 @@ func cacheMiddleware(cache *lru.Cache) middleware { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - id := r.URL.RequestURI() + // r.URL doesn't have Scheme or Host populated, better to add the + // public url to the key to make sure there's no possiblity of + // collision with other protocols using the cache. + id := publicURL.String() + "|" + r.URL.String() - if val, ok := cache.Get(id); ok { + if value := cache.Get(id); value != nil { - entry := val.(entry) + entry := value.(entry) reader := pool.Get().(*bytes.Reader) defer pool.Put(reader) @@ -174,7 +179,7 @@ func cacheMiddleware(cache *lru.Cache) middleware { h.ServeHTTP(cacheRW, r) if cacheRW.statusCode == 200 { - cache.Add(id, entry{ + cache.Set(id, entry{ body: cacheRW.buf.Bytes(), createdAt: time.Now(), }) @@ -183,7 +188,7 @@ func cacheMiddleware(cache *lru.Cache) middleware { } } -func purgeCacheOnOKMiddleware(cache *lru.Cache) middleware { +func purgeCacheOnOKMiddleware(cache cache.Cache) middleware { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { -- cgit v1.2.3