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

Side by Side Diff: server/router/handler.go

Issue 2043423004: Make HTTP middleware easier to use (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: router: Do not allocate merged array in Handle 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
OLDNEW
(Empty)
1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 package router
6
7 import "golang.org/x/net/context"
8
9 type (
10 // Handler is the type for all request handlers.
11 Handler func(*Context)
12
13 // Middleware is a function that accepts a shared context and the next
14 // function. Since Middleware is typically part of a chain of functions
15 // that handles a HTTP request, it must obey the following rules.
nodir 2016/06/15 20:14:43 an HTTP
nishanths 2016/06/16 00:14:18 Done.
16 //
17 // Middleware must call next if it has not written to the Context
18 // by the end of the function. A Middleware must not call the next
19 // function if it has written to the Context. Middleware must not write
20 // to the Context after c.Written()==true. Middleware may
nodir 2016/06/15 20:14:43 "after next is called and c.Written()==true" other
nishanths 2016/06/16 00:14:18 Done.
21 // modify the embedded context before calling next.
nodir 2016/06/15 20:14:43 use "a" and "the" consistently across paragraph (M
nishanths 2016/06/16 00:14:18 My bad. Done.
22 Middleware func(c *Context, next Handler)
23
24 // MiddlewareChain is a list of Middleware.
25 MiddlewareChain []Middleware
26 )
27
28 // Run executes the middleware chain and final handler with the given context as
29 // the initial context.
30 func (mc MiddlewareChain) Run(c *Context, h Handler) {
31 run(c, mc, nil, h)
32 }
33
34 // run executes the middleware chains m and n, and the handler h using the
35 // Context c as the initial context.
36 func run(c *Context, m, n MiddlewareChain, h Handler) {
37 if len(m) > 0 {
nodir 2016/06/15 20:14:43 use `switch {`
nishanths 2016/06/16 00:14:18 Done.
38 m[0](c, Handler(func(ctx *Context) {
nodir 2016/06/15 20:14:43 `Handler(` is unnecessary because func is a litera
nishanths 2016/06/16 00:14:18 Done.
39 run(ctx, m[1:], n, h)
40 }))
41 } else if len(n) > 0 {
42 n[0](c, Handler(func(ctx *Context) {
nodir 2016/06/15 20:14:43 same here
nishanths 2016/06/16 00:14:18 Done.
43 run(ctx, m, n[1:], h)
44 }))
45 } else {
46 h(c)
47 }
48 }
49
50 // MergeMiddlewareChains allocates a new array and copies the given middleware
51 // chains into it.
52 func MergeMiddlewareChains(mchains ...MiddlewareChain) (final MiddlewareChain) {
53 finalLen := 0
54 for _, mc := range mchains {
55 finalLen += len(mc)
56 }
57 final = make(MiddlewareChain, 0, finalLen)
nodir 2016/06/15 20:14:43 optional: return if finalLen == 0
nishanths 2016/06/16 00:14:18 Done.
58 for _, mc := range mchains {
59 final = append(final, mc...)
60 }
61 return
62 }
63
64 // MiddlewareWithContext returns a Middleware that embeds the given
65 // context.Context into the shared context and calls the next handler.
66 func MiddlewareWithContext(c context.Context) Middleware {
nodir 2016/06/15 20:14:43 I am not sure we need this. odds are there will be
nishanths 2016/06/16 00:14:18 I've left it in (for now). We can see how it turns
67 return Middleware(func(ctx *Context, next Handler) {
nodir 2016/06/15 20:14:43 perhaps `Middleware(` is unnecessary
nishanths 2016/06/16 00:14:18 Done.
68 ctx.Context = c
69 next(ctx)
70 })
71 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698