diff options
| author | Paul Mundt <paul.mundt@adaptant.io> | 2016-05-12 13:15:33 +0000 |
|---|---|---|
| committer | Felix Hanley <felix@userspace.com.au> | 2016-05-12 13:15:33 +0000 |
| commit | bb8476ffe78210d1a4c0b4bbee6da99da1bc15c5 (patch) | |
| tree | 5a70f855509889e02ea6df60d0b0fac208ee6f49 /src | |
| parent | a3a77dbd4ec45c17687d3e42dab551db59c93ca3 (diff) | |
| download | go-dict2rest-bb8476ffe78210d1a4c0b4bbee6da99da1bc15c5.tar.gz go-dict2rest-bb8476ffe78210d1a4c0b4bbee6da99da1bc15c5.tar.bz2 | |
Inhibit repeated handling of requests through context-aware middleware chains (#3)
* Squashed 'vendor/src/github.com/alexedwards/stack/' content from commit a4c0268
git-subtree-dir: vendor/src/github.com/alexedwards/stack
git-subtree-split: a4c0268505f12934376d6d8fdca232416861e271
* Use context-aware handler chains to limit repeated handling
Presently each middleware must advance through the handler chain to
reach the router endpoint. In the case of multiple compressors (gzip,
deflate) we need to be able to walk through the chain without additional
processing of already handled requests. This implements some simple
iteration logic based on request context that we pass down the chain.
Signed-off-by: Paul Mundt <paul.mundt@adaptant.io>
Diffstat (limited to 'src')
| -rw-r--r-- | src/dict2rest/deflate.go | 9 | ||||
| -rw-r--r-- | src/dict2rest/gzip.go | 10 | ||||
| -rw-r--r-- | src/dict2rest/main.go | 15 |
3 files changed, 18 insertions, 16 deletions
diff --git a/src/dict2rest/deflate.go b/src/dict2rest/deflate.go index b8ce5d6..3bd0ed8 100644 --- a/src/dict2rest/deflate.go +++ b/src/dict2rest/deflate.go @@ -5,6 +5,7 @@ import ( "io" "net/http" "strings" + "github.com/alexedwards/stack" ) // DEFLATE Compression @@ -17,10 +18,10 @@ func (w flateResponseWriter) Write(b []byte) (int, error) { return w.Writer.Write(b) } -func Deflate(next http.Handler) http.Handler { +func Deflate(ctx *stack.Context, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - if !strings.Contains(req.Header.Get("Accept-Encoding"), "deflate") { - // If deflate is unsupported, revert to standard handler. + if !strings.Contains(req.Header.Get("Accept-Encoding"), "deflate") || + ctx.Get("handled").(bool) == true { next.ServeHTTP(w, req) return } @@ -32,6 +33,8 @@ func Deflate(next http.Handler) http.Handler { w.Header().Set("Content-Encoding", "deflate") defer fl.Close() flw := flateResponseWriter{Writer: fl, ResponseWriter: w} + ctx.Put("handled", true) + defer ctx.Delete("handled") next.ServeHTTP(flw, req) }) } diff --git a/src/dict2rest/gzip.go b/src/dict2rest/gzip.go index d2264e2..c3bb5ed 100644 --- a/src/dict2rest/gzip.go +++ b/src/dict2rest/gzip.go @@ -5,6 +5,7 @@ import ( "io" "net/http" "strings" + "github.com/alexedwards/stack" ) // Gzip Compression @@ -17,10 +18,11 @@ func (w gzipResponseWriter) Write(b []byte) (int, error) { return w.Writer.Write(b) } -func Gzip(next http.Handler) http.Handler { +func Gzip(ctx *stack.Context, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - if !strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") { - // If gzip is unsupported, revert to standard handler. + if !strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") || + ctx.Get("handled").(bool) == true { + // move on to next handler in the chain next.ServeHTTP(w, req) return } @@ -28,6 +30,8 @@ func Gzip(next http.Handler) http.Handler { gz := gzip.NewWriter(w) defer gz.Close() gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w} + ctx.Put("handled", true) + defer ctx.Delete("handled") next.ServeHTTP(gzw, req) }) } diff --git a/src/dict2rest/main.go b/src/dict2rest/main.go index 391f97e..94e1ac2 100644 --- a/src/dict2rest/main.go +++ b/src/dict2rest/main.go @@ -3,7 +3,7 @@ package main import ( "flag" "github.com/julienschmidt/httprouter" - "github.com/justinas/alice" + "github.com/alexedwards/stack" "github.com/rs/cors" "github.com/stretchr/graceful" "log" @@ -64,23 +64,18 @@ func main() { }, }) - stdChain := alice.New(cors.Handler, Logger) + stdChain := stack.New(stack.Adapt(cors.Handler), stack.Adapt(Logger)) if *gzip { stdChain = stdChain.Append(Gzip) log.Println("Adding support for Gzip compression") } if *deflate { - // Temporary limitation until the iteration logic is fixed up - if *gzip { - log.Println("Not enabling DEFLATE, presently only one compression method can be active at a time") - } else { - stdChain = stdChain.Append(Deflate) - log.Println("Adding support for DEFLATE compression") - } + stdChain = stdChain.Append(Deflate) + log.Println("Adding support for DEFLATE compression") } - chain := stdChain.Then(router) + chain := stdChain.ThenHandler(router) listen := ":" + *port |
