forked from SpirentOrion/luddite.v2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
155 lines (135 loc) · 4.62 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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package luddite
import (
"context"
"net/http"
log "github.com/sirupsen/logrus"
)
type contextKey int
const contextHandlerDetailsKey = contextKey(0)
// NB: New fields added to this structure must be explicitly initialized in the
// init method below. This enables pool-based allocation.
type handlerDetails struct {
s *Service
rw ResponseWriter
request *http.Request
requestId string
requestProgress string
apiVersion int
external map[interface{}]interface{}
}
func (d *handlerDetails) init(s *Service, rw ResponseWriter, request *http.Request, requestId, requestProgress string) {
d.s = s
d.rw = rw
d.request = request
d.requestId = requestId
d.requestProgress = requestProgress
d.apiVersion = 0
d.external = nil
}
func withHandlerDetails(ctx context.Context, d *handlerDetails) context.Context {
return context.WithValue(ctx, contextHandlerDetailsKey, d)
}
func contextHandlerDetails(ctx context.Context) (d *handlerDetails) {
d, _ = ctx.Value(contextHandlerDetailsKey).(*handlerDetails)
return
}
// ContextService returns the Service instance value from a
// context.Context, if possible.
func ContextService(ctx context.Context) (s *Service) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
s = d.s
}
return
}
// ContextLogger returns the Service's logger instance value from a
// context.Context, if possible.
func ContextLogger(ctx context.Context) (logger *log.Logger) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
logger = d.s.Logger()
} else {
logger = log.New()
}
return
}
// ContextResponseWriter returns the current HTTP request's ResponseWriter from
// a context.Context, if possible.
func ContextResponseWriter(ctx context.Context) (rw ResponseWriter) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
rw, _ = d.rw.(ResponseWriter)
}
return
}
// ContextResponseHeaders returns the current HTTP response's header collection from
// a context.Context, if possible.
func ContextResponseHeaders(ctx context.Context) (header http.Header) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
header = d.rw.Header()
}
return
}
// ContextRequest returns the current HTTP request from a context.Context, if
// possible.
func ContextRequest(ctx context.Context) (request *http.Request) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
request = d.request
}
return
}
// ContextRequestId returns the current HTTP request's ID value from a
// context.Context, if possible.
func ContextRequestId(ctx context.Context) (requestId string) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
requestId = d.requestId
}
return
}
// ContextSessionId returns the current HTTP request's session ID value from a
// context.Context, if possible.
func ContextSessionId(ctx context.Context) (sessionId string) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
sessionId = d.request.Header.Get(HeaderSessionId)
}
return
}
// ContextRequestProgress returns the current HTTP request's progress trace from
// a context.Context, if possible.
func ContextRequestProgress(ctx context.Context) (reqProgress string) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
reqProgress = d.requestProgress
}
return
}
// SetContextRequestProgress sets the current HTTP request's progress trace in
// a context.Context.
func SetContextRequestProgress(ctx context.Context, progress string) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
d.requestProgress = progress
}
}
// ContextApiVersion returns the current HTTP request's API version value from a
// context.Context, if possible.
func ContextApiVersion(ctx context.Context) (apiVersion int) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
apiVersion = d.apiVersion
}
return
}
// SetContextDetail sets a detail in the current HTTP request's context. This
// may be used by the service's own middleware and avoids allocating a new
// request with additional context.
func SetContextDetail(ctx context.Context, key, value interface{}) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok {
if d.external == nil {
d.external = make(map[interface{}]interface{})
}
d.external[key] = value
}
}
// ContextDetail gets a detail from the current HTTP request's context, if
// possible.
func ContextDetail(ctx context.Context, key interface{}) (value interface{}) {
if d, ok := ctx.Value(contextHandlerDetailsKey).(*handlerDetails); ok && d.external != nil {
value, _ = d.external[key]
}
return
}