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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | server/router/router.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 // Package middleware defines base type for context-aware HTTP request handler. 5 // Package middleware defines base type for context-aware HTTP request handler.
6 // See appengine/middleware for examples of how to use it in GAE environment. 6 // See appengine/middleware for examples of how to use it in GAE environment.
7 package middleware 7 package middleware
8 8
9 import ( 9 import (
10 "net/http" 10 "net/http"
11 11
12 "github.com/julienschmidt/httprouter" 12 "github.com/julienschmidt/httprouter"
13 "golang.org/x/net/context" 13 "golang.org/x/net/context"
14 ) 14 )
15 15
16 // Handler is the type for all request handlers. Of particular note, it's the 16 // Handler is the type for all request handlers. Of particular note, it's the
17 // same as httprouter.Handle, except that it also has a context parameter. 17 // same as httprouter.Handle, except that it also has a context parameter.
18 type Handler func(context.Context, http.ResponseWriter, *http.Request, httproute r.Params) 18 type Handler func(context.Context, http.ResponseWriter, *http.Request, httproute r.Params)
19 19
20 // ChainedHandler is the same as Handler, except that it includes a Handler
21 // parameter that calls the next ChainedHandler in the middleware chain when inv oked.
22 type ChainedHandler func(context.Context, http.ResponseWriter, *http.Request, ht tprouter.Params, Handler)
nishanths 2016/06/09 04:23:47 ChainedHandler can eventually be renamed to Handle
23
20 // Middleware takes a handler, wraps it with some additional logic, and returns 24 // Middleware takes a handler, wraps it with some additional logic, and returns
21 // resulting handler. 25 // resulting handler.
22 type Middleware func(Handler) Handler 26 type Middleware func(Handler) Handler
23 27
24 // Base is a start of the middlware chain. It sets up initial context with all 28 // Chain contains a Handler and a pointer to the next element in the Chain.
29 type Chain struct {
30 » Handler ChainedHandler
31 » next *Chain
32 }
33
34 // Handle calls the chain's Handler function after adding necessary arguments.
35 func (c *Chain) Handle(ctx context.Context, wr http.ResponseWriter, r *http.Requ est, p httprouter.Params) {
36 » c.Handler(ctx, wr, r, p, c.next.Handle)
37 }
38
39 // Add adds chains to an existing chain.
40 func (c *Chain) Add(chains ...Chain) {
41 » if len(chains) == 0 {
42 » » return
43 » }
44 » // TODO(nishanths): Hold a private reference to the tail *Chain in the
45 » // Chain struct to eliminate this loop.
46 » for ; c.next != nil; c = c.next {
47 » }
48 » c.next = &chains[0]
49 » chains[0].Add(chains[1:]...)
50 }
51
52 // AddHandlers adds a list of ChainedHandlers to a Chain.
53 func (c *Chain) AddHandlers(handlers ...ChainedHandler) {
54 » chain := NewChain(handlers...)
55 » c.Add(chain)
56 }
57
58 // NewChain creates a Chain from ChainedHandler list.
59 func NewChain(handlers ...ChainedHandler) Chain {
60 » if len(handlers) == 0 {
61 » » return voidChain()
62 » }
63 » next := NewChain(handlers[1:]...)
64 » return Chain{handlers[0], &next}
65 }
66
67 // voidChain returns a Chain that has no Chain after it (that is, it's next
68 // field is nil).
69 func voidChain() Chain {
70 » return Chain{
71 » » ChainedHandler(func(c context.Context, rw http.ResponseWriter, r *http.Request, p httprouter.Params, next Handler) {}),
72 » » nil,
73 » }
74 }
75
76 // Base is a start of the middleware chain. It sets up initial context with all
25 // base services and passes it to the given handler. Return value of Base can 77 // base services and passes it to the given handler. Return value of Base can
26 // be plugged in into httprouter directly. 78 // be plugged in into httprouter directly.
27 type Base func(Handler) httprouter.Handle 79 type Base func(Handler) httprouter.Handle
28 80
29 // TestingBase is Base that passes given context to the handler. Useful in 81 // TestingBase is Base that passes given context to the handler. Useful in
30 // tests. 82 // tests.
31 func TestingBase(c context.Context) Base { 83 func TestingBase(c context.Context) Base {
32 return func(h Handler) httprouter.Handle { 84 return func(h Handler) httprouter.Handle {
33 return func(rw http.ResponseWriter, r *http.Request, p httproute r.Params) { 85 return func(rw http.ResponseWriter, r *http.Request, p httproute r.Params) {
34 h(c, rw, r, p) 86 h(c, rw, r, p)
35 } 87 }
36 } 88 }
37 } 89 }
38 90
39 // WithContextValue is a middleware that adds a value to the context before 91 // WithContextValue is a middleware that adds a value to the context before
40 // calling the handler. 92 // calling the handler.
41 func WithContextValue(h Handler, key, val interface{}) Handler { 93 func WithContextValue(h Handler, key, val interface{}) Handler {
42 return func(c context.Context, rw http.ResponseWriter, r *http.Request, p httprouter.Params) { 94 return func(c context.Context, rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
43 h(context.WithValue(c, key, val), rw, r, p) 95 h(context.WithValue(c, key, val), rw, r, p)
44 } 96 }
45 } 97 }
OLDNEW
« 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