/
handler.go
120 lines (100 loc) · 2.97 KB
/
handler.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
package wrphttp
import (
"net/http"
gokithttp "github.com/go-kit/kit/transport/http"
)
// Handler is a WRP handler for messages over HTTP. This is the analog of http.Handler.
type Handler interface {
ServeWRP(ResponseWriter, *Request)
}
type HandlerFunc func(ResponseWriter, *Request)
func (hf HandlerFunc) ServeWRP(w ResponseWriter, r *Request) {
hf(w, r)
}
// Option is a configurable option for an HTTP handler that works with WRP
type Option func(*wrpHandler)
// WithErrorEncoder establishes a go-kit ErrorEncoder for the given handler.
// By default, DefaultErrorEncoder is used. If the supplied ErrorEncoder is
// nil, it reverts to the default.
func WithErrorEncoder(ee gokithttp.ErrorEncoder) Option {
return func(wh *wrpHandler) {
if ee != nil {
wh.errorEncoder = ee
} else {
wh.errorEncoder = gokithttp.DefaultErrorEncoder
}
}
}
// WithNewResponseWriter establishes a factory function for ResponseWriter objects.
// By default, DefaultResponseWriterFunc() is used. If the supplied strategy function
// is nil, it reverts to the default.
func WithNewResponseWriter(rwf ResponseWriterFunc) Option {
return func(wh *wrpHandler) {
if rwf != nil {
wh.newResponseWriter = rwf
} else {
wh.newResponseWriter = DefaultResponseWriterFunc()
}
}
}
// WithDecoder sets a go-kit DecodeRequestFunc strategy that turns an http.Request into a WRP request.
// By default, DefaultDecoder() is used. If the supplied strategy is nil, it reverts to the default.
func WithDecoder(d Decoder) Option {
return func(wh *wrpHandler) {
if d != nil {
wh.decoder = d
} else {
wh.decoder = DefaultDecoder()
}
}
}
func WithBefore(funcs ...MessageFunc) Option {
return func(wh *wrpHandler) {
wh.before = append(wh.before, funcs...)
}
}
// NewHTTPHandler creates an http.Handler that forwards WRP requests to the supplied WRP handler.
func NewHTTPHandler(h Handler, options ...Option) http.Handler {
if h == nil {
panic("A WRP Handler is required")
}
wh := &wrpHandler{
handler: h,
errorEncoder: gokithttp.DefaultErrorEncoder,
decoder: DefaultDecoder(),
newResponseWriter: DefaultResponseWriterFunc(),
}
for _, o := range options {
o(wh)
}
return wh
}
type wrpHandler struct {
handler Handler
errorEncoder gokithttp.ErrorEncoder
before []MessageFunc
decoder Decoder
newResponseWriter ResponseWriterFunc
}
func (wh *wrpHandler) ServeHTTP(httpResponse http.ResponseWriter, httpRequest *http.Request) {
ctx := httpRequest.Context()
entity, err := wh.decoder(ctx, httpRequest)
if err != nil {
wh.errorEncoder(ctx, err, httpResponse)
return
}
for _, mf := range wh.before {
ctx = mf(ctx, &entity.Message)
}
wrpRequest := &Request{
Original: httpRequest,
Entity: entity,
ctx: ctx,
}
wrpResponse, err := wh.newResponseWriter(httpResponse, wrpRequest)
if err != nil {
wh.errorEncoder(wrpRequest.Context(), err, httpResponse)
return
}
wh.handler.ServeWRP(wrpResponse, wrpRequest)
}