-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmuxhelper.go
174 lines (147 loc) · 4.2 KB
/
muxhelper.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package httpu
import (
"context"
"log"
"net/http"
"strings"
"github.com/gohxs/httpu/chain"
)
// Muxer http.ServeMux compatible muxer interface
type Muxer interface {
Handle(pattern string, handler http.Handler)
HandleFunc(pattern string, handlerFunc func(w http.ResponseWriter, r *http.Request))
}
// MuxPrefix Returns a mux alike with a prefix
type MuxPrefix struct {
Muxer
prefix string
}
// MuxWithPrefix returns a compatible http.ServeMux with prefix handling on handle funcs
func MuxWithPrefix(mux Muxer, pattern string) Muxer {
return &MuxPrefix{mux, pattern}
}
// Handle a pattern
func (m *MuxPrefix) Handle(pattern string, handler http.Handler) {
m.Muxer.Handle(m.prefix+pattern, handler)
}
// HandleFunc pattern with a func
func (m *MuxPrefix) HandleFunc(pattern string, handlerFunc func(w http.ResponseWriter, r *http.Request)) {
m.Muxer.HandleFunc(m.prefix+pattern, handlerFunc)
}
// MuxHelper httpu flavoured muxer
type MuxHelper interface {
Muxer
Pattern(...string) string
Group(pattern string, ch *chain.Chain) Muxer
//HandleFunc(pattern string, handler func(w http.ResponseWriter, r *http.Request))
}
// NewMuxHelper Create a New helper mux
func NewMuxHelper(mux *http.ServeMux, ch *chain.Chain) Muxer {
return &MuxBase{
Parent: mux,
Chain: ch,
pattern: "",
}
}
// Base muxer consists in a pattern and Chain
type MuxBase struct {
Parent Muxer
Chain *chain.Chain
pattern string
}
func (m *MuxBase) Handle(pattern string, handler http.Handler) {
//pattern = strings.TrimLeft(pattern, "/")
spath := m.pattern + pattern
// Apply chain for this handler
if m.Chain != nil {
handler = m.Chain.Build(handler.ServeHTTP)
}
//Root will handle
m.Parent.Handle(spath, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), "path", spath)
handler.ServeHTTP(w, r.WithContext(ctx))
}))
}
func (m *MuxBase) HandleFunc(pattern string, handlerFunc func(w http.ResponseWriter, r *http.Request)) {
m.Handle(pattern, http.HandlerFunc(handlerFunc))
}
func (m *MuxBase) Group(pattern string, ch *chain.Chain) Muxer {
return &MuxBase{
Parent: m,
Chain: ch,
pattern: pattern,
}
}
// Solve name
func (m *MuxBase) Pattern(sub ...string) string {
subPattern := strings.Join(sub, "")
switch parent := m.Parent.(type) {
case MuxHelper:
return parent.Pattern(m.pattern, subPattern) // With us and subPattern
case Muxer:
res := m.pattern + subPattern // us hand sub too
log.Printf("[%s:MuxHandler] Base Handler, sub: %s", m.pattern, res)
return res
}
return ""
}
/////////////////////////////////
// Mux helper
///////////////////
/*
// MuxHelper main muxer struct
type MuxHelper struct {
Mux BaseMuxer // HttpMuxer
pattern string // Base pattern
Chain *Chain
}
//Handle handle http implementation
func (m *MuxHelper) Handle(pattern string, handler http.Handler) {
spath := m.Pattern(pattern)
log.Println("Sub route handle", spath, " Sending to parent")
if m.Chain != nil {
handler = m.Chain.Build(handler)
}
m.Mux.Handle(spath, handler)
}
//Pattern implementation
func (m *MuxHelper) Pattern(sub ...string) string {
if len(sub) > 0 {
return m.pattern + "/" + strings.Join(sub, "/")
}
return m.pattern
}
func (m *MuxHelper) Group(pattern string) *MuxGroup {
return &MuxGroup{m, pattern, nil}
}
///////////////////////////////////
// MuxGroup
/////////////////
//MuxGroup helper to create group
type MuxGroup struct {
Parent Muxer
pattern string
Chain *Chain
}
//Handle Implementation counting Parent muxers
func (mg *MuxGroup) Handle(pattern string, handler http.Handler) {
spath := mg.Pattern(pattern)
log.Println("Sub route Handler", spath, " Senting to parent")
// Apply chain for this handler
if mg.Chain != nil {
handler = mg.Chain.Build(handler)
}
mg.Parent.Handle(spath, handler)
}
// Pattern retrieves full pattern for this group
func (mg *MuxGroup) Pattern(sub ...string) string {
return mg.Parent.Pattern(mg.pattern, strings.Join(sub, "/"))
}
// Group sub muxer
func (mg *MuxGroup) Group(pattern string) *MuxGroup {
return &MuxGroup{mg, pattern, nil}
}
// Built pattern
/*func (m *MuxHelper) HandleFunc(pattern string, handler func(w http.ResponseWriter, r *http.Request)) {
m.Handle(pattern, http.HandlerFunc(handler))
}*/