-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadapter.go
93 lines (81 loc) · 2.48 KB
/
adapter.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
package heligo
import (
"context"
"net/http"
)
type paramsKey struct{}
var ParamsTag = paramsKey{}
type AdapterResponseWriter struct {
http.ResponseWriter
status int
}
func (w *AdapterResponseWriter) WriteHeader(code int) {
w.status = code
w.ResponseWriter.WriteHeader(code)
}
func (w *AdapterResponseWriter) Status() int {
return w.status
}
// Adapt adapts a standard http.Handler to be used as a Heligo handler.
// In the standard handler one can retrieve parameters from the context,
// using ParamsFromContext.
func Adapt(h http.Handler) Handler {
return func(ctx context.Context, w http.ResponseWriter, r Request) (int, error) {
rw := &AdapterResponseWriter{w, http.StatusOK}
req := r.Request
if r.params.count > 0 {
ctx := req.Context()
ctx = context.WithValue(ctx, ParamsTag, r.Params())
req = req.WithContext(ctx)
}
h.ServeHTTP(rw, req)
return rw.Status(), nil
}
}
// Adapt adapts a standard http.Handler to be used as a Heligo handler.
func AdaptFunc(hf http.HandlerFunc) Handler {
return Adapt(hf)
}
// ParamsFromContext gets the route parameters from the context
func ParamsFromContext(ctx context.Context) []Param {
v := ctx.Value(ParamsTag)
if v == nil {
return nil
}
return v.([]Param)
}
// AdaptMiddleware adapts a standard middleware (func(http.Handler) http.Handler)
// to be used as a Heligo middleware
func AdaptMiddleware(m func(http.Handler) http.Handler) Middleware {
return func(next Handler) Handler {
return func(ctx context.Context, w http.ResponseWriter, r Request) (int, error) {
var status int
var err error
h := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
status, err = next(ctx, w, r)
})
req := r.Request
m(h).ServeHTTP(w, req)
return status, err
}
}
}
// AdaptAsMiddleware adapts a standard http.Handler to be used as
// a Heligo middleware. Note the this is less flexible than the previous
// AdaptMiddleware, as it doesn't not allow to break the middleware chain
// except in the case of errors and calls the next handler only at the end.
func AdaptAsMiddleware(h http.Handler) Middleware {
return func(next Handler) Handler {
return func(ctx context.Context, w http.ResponseWriter, r Request) (int, error) {
s, err := Adapt(h)(ctx, w, r)
if err != nil {
return s, err
}
return next(ctx, w, r)
}
}
}
// AdaptFuncAsMiddleware adapts a standard http.HandlerFunc to be used as a Heligo middleware.
func AdaptFuncAsMiddleware(hf http.HandlerFunc) Middleware {
return AdaptAsMiddleware(hf)
}