-
Notifications
You must be signed in to change notification settings - Fork 79
/
context.go
62 lines (53 loc) · 1.45 KB
/
context.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package tigertonic
import (
"net/http"
"reflect"
"sync"
)
var (
contexts map[*http.Request]interface{}
mutex sync.Mutex
)
// Context returns the request context as an interface{} given a pointer
// to the request itself.
func Context(r *http.Request) interface{} {
mutex.Lock()
defer mutex.Unlock()
return contexts[r]
}
// ContextHandler is an http.Handler that associates a context object of
// any type with each request it handles.
type ContextHandler struct {
handler http.Handler
t reflect.Type
}
// WithContext wraps an http.Handler and associates a new context object of
// the same type as the second parameter with each request it handles. You
// must wrap any handler that uses Context or the four-parameter form of
// Marshaled in WithContext.
func WithContext(handler http.Handler, i interface{}) *ContextHandler {
return &ContextHandler{
handler: handler,
t: reflect.TypeOf(i),
}
}
// ServeHTTP adds and removes the per-request context and calls the wrapped
// http.Handler in between.
func (ch *ContextHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ch.add(r)
defer ch.remove(r)
ch.handler.ServeHTTP(w, r)
}
func (ch *ContextHandler) add(r *http.Request) {
mutex.Lock()
defer mutex.Unlock()
contexts[r] = reflect.New(ch.t).Interface()
}
func (ch *ContextHandler) remove(r *http.Request) {
mutex.Lock()
defer mutex.Unlock()
delete(contexts, r)
}
func init() {
contexts = make(map[*http.Request]interface{})
}