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

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: Update documentation and improve code style 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 an HTTP request, it must obey the following rules.
16 //
17 // Middleware must call next if it has not written to the Context
18 // by the end of the function. Middleware must not call next
19 // if it has written to the Context. Middleware must not write
20 // to the Context after next is called and c.Written()==true. Middleware
21 // may modify the embedded context before calling next.
iannucci 2016/06/16 00:54:24 let's make these bullets: // - Middleware mu
nishanths 2016/06/16 03:43:27 +1 Done. With aligned dashes inside a <pre> block.
nodir 2016/06/16 04:20:25 +1
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 switch {
38 case len(m) > 0:
39 m[0](c, func(ctx *Context) {
40 run(ctx, m[1:], n, h)
41 })
42 case len(n) > 0:
43 n[0](c, func(ctx *Context) {
44 run(ctx, m, n[1:], h)
45 })
46 default:
47 h(c)
48 }
49 }
50
51 // MergeMiddlewareChains allocates a new array and copies the given middleware
52 // chains into it.
53 func MergeMiddlewareChains(mchains ...MiddlewareChain) (final MiddlewareChain) {
iannucci 2016/06/16 00:54:24 Maybe JoinMiddlewareChains? Or ConcatMiddlewareCha
nishanths 2016/06/16 03:43:27 Good point. But, removing this func as it is unuse
54 finalLen := 0
55 for _, mc := range mchains {
56 finalLen += len(mc)
57 }
58 if finalLen == 0 {
59 return
60 }
61
62 final = make(MiddlewareChain, 0, finalLen)
63 for _, mc := range mchains {
64 final = append(final, mc...)
65 }
66 return
67 }
68
69 // MiddlewareWithContext returns a Middleware that embeds the given
70 // context.Context into the shared context and calls the next handler.
71 func MiddlewareWithContext(c context.Context) Middleware {
iannucci 2016/06/16 00:54:24 hm... this seems a bit dangerous: this /replaces/
nishanths 2016/06/16 03:43:27 Yep, SetContext is a far better name. Nevertheles
72 return func(ctx *Context, next Handler) {
73 ctx.Context = c
74 next(ctx)
75 }
76 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698