@@ -20,26 +20,25 @@ var (
2020 server = newHTTPServer ()
2121)
2222
23- type uriRegexp struct {
24- path string
25- keys []string
26- exp * regexp.Regexp
27- source reflect.Type
23+ type handlerRegexp struct {
24+ keys []string
25+ exp * regexp.Regexp
26+ handler
2827}
2928
30- // iface 对外服务接口, path格式:Method/URI
31- type iface struct {
32- path string
33- source reflect. Type
29+ // handler 对外服务接口, path格式:Method/URI
30+ type handler struct {
31+ path string
32+ call func (http. ResponseWriter , * http. Request )
3433}
3534
3635type prefix struct {
37- path string
38- uriExps []uriRegexp
36+ path string
37+ exps []handlerRegexp
3938}
4039
4140type httpServer struct {
42- path map [string ]iface
41+ path map [string ]handler
4342 prefix * btree.BTree
4443 filter Filter
4544 listener net.Listener
@@ -48,7 +47,7 @@ type httpServer struct {
4847
4948func newHTTPServer () * httpServer {
5049 return & httpServer {
51- path : make (map [string ]iface ),
50+ path : make (map [string ]handler ),
5251 prefix : btree .New (3 ),
5352 filter : defaultFilter ,
5453 }
@@ -83,6 +82,32 @@ func Register(obj interface{}) error {
8382 return register (obj , "" , false )
8483}
8584
85+ //RegisterPath 注册url完全匹配.
86+ func RegisterPath (obj interface {}, path string ) error {
87+ return register (obj , path , false )
88+ }
89+
90+ //RegisterHandler 注册自定义url完全匹配.
91+ func RegisterHandler (call func (http.ResponseWriter , * http.Request ), method , path string ) error {
92+ h := handler {
93+ path : fmt .Sprintf ("%v%v" , method , path ),
94+ call : call ,
95+ }
96+
97+ server .Lock ()
98+ defer server .Unlock ()
99+
100+ if _ , ok := server .path [h .path ]; ok {
101+ return errors .Errorf ("exist url:%v %v" , method , path )
102+ }
103+
104+ server .path [h .path ] = h
105+
106+ log .Infof ("add handler %v %v" , method , path )
107+
108+ return nil
109+ }
110+
86111//RegisterPrefix 注册url前缀.
87112func RegisterPrefix (obj interface {}, path string ) error {
88113 return register (obj , path , true )
@@ -100,28 +125,22 @@ func init() {
100125 keysExp = exp
101126}
102127
103- func newURIRegexp (path string , source reflect.Type ) uriRegexp {
104- ur := uriRegexp {
105- path : path ,
106- source : source ,
107- }
128+ func newHandlerRegexp (h handler ) handlerRegexp {
129+ hr := handlerRegexp {handler : h }
108130
109- //log.Debugf("path:%v", path)
110- for _ , m := range keysExp .FindAllStringSubmatch (path , - 1 ) {
111- //log.Debugf("path:%v, key:%#v", path, m)
112- ur .keys = append (ur .keys , m [1 ])
131+ for _ , m := range keysExp .FindAllStringSubmatch (hr .path , - 1 ) {
132+ hr .keys = append (hr .keys , m [1 ])
113133 }
114134
115- np := keysExp .ReplaceAllString (path , "(.+)" )
135+ np := keysExp .ReplaceAllString (hr . path , "(.+)" )
116136 exp , err := regexp .Compile (np )
117137 if err != nil {
118138 panic (err .Error ())
119139 }
120- ur .exp = exp
121140
122- // log.Debugf("uriRegexp:%#v", ur)
141+ hr . exp = exp
123142
124- return ur
143+ return hr
125144}
126145
127146func register (obj interface {}, path string , isPrefix bool ) error {
@@ -146,15 +165,26 @@ func register(obj interface{}, path string, isPrefix bool) error {
146165 method := rt .Method (i ).Name
147166 //log.Debugf("rt:%v, %d, method:%v", rt, i, method)
148167 switch method {
149- case POST . String () :
150- case GET . String () :
151- case PUT . String () :
152- case DELETE . String () :
168+ case http . MethodPost :
169+ case http . MethodGet :
170+ case http . MethodPut :
171+ case http . MethodDelete :
153172 default :
154- log .Warnf ("ignore %v %v %v" , method , path , rt )
173+ log .Warnf ("ignore func: %v %v %v" , method , path , rt )
155174 continue
156175 }
157176
177+ mt := rv .MethodByName (method )
178+ if mt .Type ().NumIn () != 2 || mt .Type ().In (0 ).String () != "http.ResponseWriter" || mt .Type ().In (1 ).String () != "*http.Request" {
179+ log .Debugf ("ignore func:%v %v %v" , method , path , mt .Type ())
180+ continue
181+ }
182+
183+ h := handler {
184+ path : fmt .Sprintf ("%v%v" , method , path ),
185+ call : mt .Interface ().(func (http.ResponseWriter , * http.Request )),
186+ }
187+
158188 //前缀匹配
159189 if isPrefix {
160190 p := prefix {
@@ -166,32 +196,26 @@ func register(obj interface{}, path string, isPrefix bool) error {
166196 }
167197
168198 // log.Debugf("path:%v", p.path)
169-
170199 if server .prefix .Has (& p ) {
171200 p = * (server .prefix .Get (& p ).(* prefix ))
172201 }
173202
174- exp := newURIRegexp ( path , rt . Elem () )
203+ exp := newHandlerRegexp ( h )
175204
176- p .uriExps = append (p .uriExps , exp )
205+ p .exps = append (p .exps , exp )
177206
178207 server .prefix .ReplaceOrInsert (& p )
179208
180209 log .Infof ("add prefix %v %v %v %v" , method , exp .path , exp .keys , rt )
181-
182210 continue
183211 }
184212
185- ifc := iface {
186- path : fmt .Sprintf ("%v%v" , method , path ),
187- source : rt .Elem (),
188- }
189213 //全路径匹配
190- if _ , ok := server .path [ifc .path ]; ok {
191- panic ( fmt . Sprintf ("exist url:%v %v" , method , path ) )
214+ if _ , ok := server .path [h .path ]; ok {
215+ return errors . Errorf ("exist url:%v %v" , method , path )
192216 }
193217
194- server .path [ifc .path ] = ifc
218+ server .path [h .path ] = h
195219 log .Infof ("add path %v %v %v" , method , path , rt )
196220 }
197221
@@ -205,7 +229,7 @@ func AddFilter(filter Filter) {
205229 server .filter = filter
206230}
207231
208- func parseRequestValues (path string , ur uriRegexp ) context.Context {
232+ func parseRequestValues (path string , ur handlerRegexp ) context.Context {
209233 ctx := context .Background ()
210234 for i , v := range ur .exp .FindAllStringSubmatch (path , - 1 ) {
211235 //log.Debugf("i:%v, v:%#v, keys:%#v", i, v, ur.keys)
@@ -214,15 +238,15 @@ func parseRequestValues(path string, ur uriRegexp) context.Context {
214238 return ctx
215239}
216240
217- func getInterface (method , path string ) (reflect. Type , context.Context ) {
241+ func getHandler (method , path string ) (func (http. ResponseWriter , * http. Request ) , context.Context ) {
218242 server .RLock ()
219243 defer server .RUnlock ()
220244
221245 path = method + path
222246
223247 if i , ok := server .path [path ]; ok {
224248 //log.Debugf("find path:%v", path)
225- return i .source , nil
249+ return i .call , nil
226250 }
227251
228252 var p prefix
@@ -235,12 +259,20 @@ func getInterface(method, path string) (reflect.Type, context.Context) {
235259 return ! ok
236260 })
237261
238- for _ , ue := range p .uriExps {
262+ if ! ok {
263+ return nil , nil
264+ }
265+
266+ for _ , ue := range p .exps {
239267 if ue .exp .MatchString (path ) {
268+ if len (ue .keys ) == 0 {
269+ return ue .call , nil
270+ }
240271 // log.Debugf("uri exp:%v, path:%v", ue, path)
241- return ue .source , parseRequestValues (path , ue )
272+ return ue .call , parseRequestValues (path , ue )
242273 }
243274 }
275+
244276 return nil , nil
245277}
246278
@@ -260,8 +292,8 @@ func (s *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
260292 return
261293 }
262294
263- tp , ctx := getInterface (r .Method , r .URL .Path )
264- if tp == nil {
295+ h , ctx := getHandler (r .Method , r .URL .Path )
296+ if h == nil {
265297 log .Errorf ("%v %v %v not found." , r .RemoteAddr , r .Method , r .URL )
266298 SendResponse (w , http .StatusNotFound , "invalid request" )
267299 return
@@ -271,10 +303,9 @@ func (s *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
271303 nr = nr .WithContext (ctx )
272304 }
273305
274- log .Debugf ("%v %v %v %v" , r .RemoteAddr , r .Method , r .URL , tp )
306+ log .Debugf ("%v %v %v %v" , r .RemoteAddr , r .Method , r .URL , h )
275307
276- callback := reflect .New (tp ).MethodByName (r .Method ).Interface ().(func (http.ResponseWriter , * http.Request ))
277- callback (w , nr )
308+ h (w , nr )
278309
279310 return
280311}
@@ -297,6 +328,13 @@ func Start(addr string) error {
297328 return http .Serve (ln , server )
298329}
299330
331+ //Listener 获取监听地址.
332+ func Listener () net.Listener {
333+ server .Lock ()
334+ defer server .Unlock ()
335+ return server .listener
336+ }
337+
300338//Stop 停止httpServer监听, 进行中的任务并不会因此而停止.
301339func Stop () error {
302340 server .Lock ()
0 commit comments