Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Unified Diff: server/middleware/middleware.go

Issue 2043423004: Make HTTP middleware easier to use (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | server/router/router.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: server/middleware/middleware.go
diff --git a/server/middleware/middleware.go b/server/middleware/middleware.go
index 81dd71920964a7089cb8e6de99999f9bc331b652..707229f105d49e4fdf80d4c1ca2b99d19c055a69 100644
--- a/server/middleware/middleware.go
+++ b/server/middleware/middleware.go
@@ -17,11 +17,63 @@ import (
// same as httprouter.Handle, except that it also has a context parameter.
type Handler func(context.Context, http.ResponseWriter, *http.Request, httprouter.Params)
+// ChainedHandler is the same as Handler, except that it includes a Handler
+// parameter that calls the next ChainedHandler in the middleware chain when invoked.
+type ChainedHandler func(context.Context, http.ResponseWriter, *http.Request, httprouter.Params, Handler)
nishanths 2016/06/09 04:23:47 ChainedHandler can eventually be renamed to Handle
+
// Middleware takes a handler, wraps it with some additional logic, and returns
// resulting handler.
type Middleware func(Handler) Handler
-// Base is a start of the middlware chain. It sets up initial context with all
+// Chain contains a Handler and a pointer to the next element in the Chain.
+type Chain struct {
+ Handler ChainedHandler
+ next *Chain
+}
+
+// Handle calls the chain's Handler function after adding necessary arguments.
+func (c *Chain) Handle(ctx context.Context, wr http.ResponseWriter, r *http.Request, p httprouter.Params) {
+ c.Handler(ctx, wr, r, p, c.next.Handle)
+}
+
+// Add adds chains to an existing chain.
+func (c *Chain) Add(chains ...Chain) {
+ if len(chains) == 0 {
+ return
+ }
+ // TODO(nishanths): Hold a private reference to the tail *Chain in the
+ // Chain struct to eliminate this loop.
+ for ; c.next != nil; c = c.next {
+ }
+ c.next = &chains[0]
+ chains[0].Add(chains[1:]...)
+}
+
+// AddHandlers adds a list of ChainedHandlers to a Chain.
+func (c *Chain) AddHandlers(handlers ...ChainedHandler) {
+ chain := NewChain(handlers...)
+ c.Add(chain)
+}
+
+// NewChain creates a Chain from ChainedHandler list.
+func NewChain(handlers ...ChainedHandler) Chain {
+ if len(handlers) == 0 {
+ return voidChain()
+ }
+ next := NewChain(handlers[1:]...)
+ return Chain{handlers[0], &next}
+}
+
+// voidChain returns a Chain that has no Chain after it (that is, it's next
+// field is nil).
+func voidChain() Chain {
+ return Chain{
+ ChainedHandler(func(c context.Context, rw http.ResponseWriter, r *http.Request, p httprouter.Params, next Handler) {}),
+ nil,
+ }
+}
+
+// Base is a start of the middleware chain. It sets up initial context with all
// base services and passes it to the given handler. Return value of Base can
// be plugged in into httprouter directly.
type Base func(Handler) httprouter.Handle
« no previous file with comments | « no previous file | server/router/router.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698