-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.go
More file actions
110 lines (89 loc) · 2.28 KB
/
middleware.go
File metadata and controls
110 lines (89 loc) · 2.28 KB
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
package middleware
import "net/http"
type middlewares struct {
head *middleware
tail *middleware
}
type middleware struct {
middleware Middleware
next *middleware
}
type MiddlewareFunc func(http.ResponseWriter, *http.Request, func())
type Middleware interface {
ServeHTTP(http.ResponseWriter, *http.Request, func())
}
func (m *middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
m.middleware.ServeHTTP(w, r, func() {
if m.next != nil {
m.next.ServeHTTP(w, r)
}
})
}
func (m *middlewares) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ww := &ResponseWriter{w, 200, 0}
// execute the first middleware
m.head.ServeHTTP(ww, r)
}
// ResponseWriter is a wrapper around http.ResponseWriter, record status and size
type ResponseWriter struct {
http.ResponseWriter
status int
size int
}
func (w *ResponseWriter) WriteHeader(s int) {
w.status = s
w.ResponseWriter.WriteHeader(s)
}
func (w *ResponseWriter) Write(b []byte) (int, error) {
size, err := w.ResponseWriter.Write(b)
w.size += size
return size, err
}
func (w *ResponseWriter) Status() int {
return w.status
}
func (w *ResponseWriter) Size() int {
return w.size
}
// create middleware container
func New() *middlewares {
return &middlewares{}
}
// use middleware
func (m *middlewares) Use(mw Middleware) {
n := &middleware{mw, nil}
if m.head == nil && m.tail == nil {
m.head = n
m.tail = n
} else {
m.tail.next = n
m.tail = n
}
}
// MiddlewareFunc implement Middleware interface
func (f MiddlewareFunc) ServeHTTP(w http.ResponseWriter, r *http.Request, next func()) {
f(w, r, next)
}
// use MiddlewareFunc as middleware
func (m *middlewares) UseFunc(middlewareFunc MiddlewareFunc) {
m.Use(middlewareFunc)
}
type middlewareForHandler struct {
handler http.Handler
}
func (m *middlewareForHandler) ServeHTTP(w http.ResponseWriter, r *http.Request, next func()) {
m.handler.ServeHTTP(w, r)
next()
}
// use http.Handler as middleware
func (m *middlewares) UseHandler(handler http.Handler) {
m.Use(&middlewareForHandler{handler})
}
// use http.HandlerFunc as middleware
func (m *middlewares) UseHandlerFunc(handlerFunc http.HandlerFunc) {
m.Use(&middlewareForHandler{handlerFunc})
}
// just a sugar method
func (m *middlewares) Listen(addr string) error {
return http.ListenAndServe(addr, m)
}