@@ -18,37 +18,27 @@ var (
1818)
1919
2020type server struct {
21- post map [string ]iface
22- get map [string ]iface
23- put map [string ]iface
24- delete map [string ]iface
21+ path map [string ]iface
2522 prefix * btree.BTree
2623 filter Filter
2724 mu sync.RWMutex
2825}
2926
3027func newHTTPServer () * server {
3128 return & server {
32- post : make (map [string ]iface ),
33- get : make (map [string ]iface ),
34- put : make (map [string ]iface ),
35- delete : make (map [string ]iface ),
29+ path : make (map [string ]iface ),
3630 prefix : btree .New (3 ),
3731 filter : defaultFilter ,
3832 }
3933}
4034
41- // Callback 用户接口
42- type Callback func (http.ResponseWriter , * http.Request )
43-
4435// Filter 请求过滤, 如果返回结果为nil,直接返回,不再进行后续处理.
4536type Filter func (http.ResponseWriter , * http.Request ) * http.Request
4637
47- // iface 对外服务接口
38+ // iface 对外服务接口, path格式:Method/URI
4839type iface struct {
49- method Method
5040 path string
51- call Callback
41+ source reflect. Type
5242}
5343
5444func (i * iface ) Less (bi btree.Item ) bool {
@@ -73,31 +63,59 @@ func NameToPath(name string, depth int) string {
7363}
7464
7565//AddInterface 自动注册接口
76- //只要struct实现了DoGet (),DoPost (),DoDelete (),DoPut ()接口就可以自动注册
77- func (s * server ) AddInterface (iface interface {}, path string ) error {
78- rt := reflect .TypeOf (iface )
66+ //只要struct实现了Get (),Post (),Delete (),Put ()接口就可以自动注册
67+ func (s * server ) AddInterface (obj interface {}, path string , isPrefix bool ) error {
68+ rt := reflect .TypeOf (obj )
7969 if rt .Kind () != reflect .Ptr {
8070 return fmt .Errorf ("need ptr" )
8171 }
82- rv := reflect .ValueOf (iface )
72+
73+ if path == "" {
74+ path = NameToPath (rt .String (), 0 ) + "/"
75+ }
76+
77+ if ! strings .HasPrefix (path , "/" ) {
78+ path = "/" + path
79+ }
80+
81+ s .mu .Lock ()
82+ defer s .mu .Unlock ()
83+
84+ rv := reflect .ValueOf (obj )
8385 for i := 0 ; i < rv .NumMethod (); i ++ {
84- mt := rt .Method (i )
85- mv := rv .Method (i )
86- if path == "" {
87- path = NameToPath (rt .String (), 0 ) + "/"
86+ method := rt .Method (i ).Name
87+ log .Debugf ("rt:%v, %d, method:%v" , rt , i , method )
88+ switch method {
89+ case POST .String ():
90+ case GET .String ():
91+ case PUT .String ():
92+ case DELETE .String ():
93+ default :
94+ log .Debugf ("ignore method:%v path:%v" , method , path )
95+ continue
8896 }
8997
90- switch mt .Name {
91- case "DoPost" :
92- s .AddHandler (POST , path , false , mv .Interface ().(func (http.ResponseWriter , * http.Request )))
93- case "DoGet" :
94- s .AddHandler (GET , path , false , mv .Interface ().(func (http.ResponseWriter , * http.Request )))
95- case "DoPut" :
96- s .AddHandler (PUT , path , false , mv .Interface ().(func (http.ResponseWriter , * http.Request )))
97- case "DoDelete" :
98- s .AddHandler (DELETE , path , false , mv .Interface ().(func (http.ResponseWriter , * http.Request )))
98+ ifc := iface {
99+ path : fmt .Sprintf ("%v%v" , method , path ),
100+ source : rt .Elem (),
99101 }
100- log .Debugf ("%v %v" , mt .Name , path )
102+
103+ //前缀匹配
104+ if isPrefix {
105+ if s .prefix .Has (& ifc ) {
106+ panic (fmt .Sprintf ("exist url:%v %v" , method , path ))
107+ }
108+ s .prefix .ReplaceOrInsert (& ifc )
109+ log .Debugf ("add prefix:%v" , path )
110+ continue
111+ }
112+
113+ //全路径匹配
114+ if _ , ok := s .path [ifc .path ]; ok {
115+ panic (fmt .Sprintf ("exist url:%v %v" , method , path ))
116+ }
117+
118+ s .path [ifc .path ] = ifc
101119 }
102120
103121 return nil
@@ -110,60 +128,26 @@ func (s *server) AddFilter(filter Filter) {
110128 s .filter = filter
111129}
112130
113- //AddHandler 注册接口
114- func (s * server ) AddHandler (method Method , path string , isPrefix bool , call Callback ) {
115- s .mu .Lock ()
116- defer s .mu .Unlock ()
117-
118- i := iface {method , path , call }
119- if isPrefix {
120- s .prefix .ReplaceOrInsert (& i )
121- }
122-
123- var ms map [string ]iface
124- switch method {
125- case GET :
126- ms = s .get
127- case POST :
128- ms = s .post
129- case PUT :
130- ms = s .put
131- case DELETE :
132- ms = s .delete
133- }
134-
135- if _ , ok := ms [path ]; ok {
136- panic (fmt .Sprintf ("exist url:%v %v" , method , path ))
137- }
138-
139- ms [path ] = i
140- }
141-
142131func (s * server ) iface (w http.ResponseWriter , r * http.Request ) (i iface , ok bool ) {
143132 s .mu .RLock ()
144133 defer s .mu .RUnlock ()
145134
146- switch r .Method {
147- case "GET" :
148- i , ok = s .get [r .URL .Path ]
149- case "POST" :
150- i , ok = s .post [r .URL .Path ]
151- case "PUT" :
152- i , ok = s .put [r .URL .Path ]
153- case "DELETE" :
154- i , ok = s .delete [r .URL .Path ]
155- }
135+ path := r .Method + r .URL .Path
156136
157- if ok {
137+ if i , ok = s .path [path ]; ok {
138+ log .Debugf ("find path:%v" , path )
158139 return
159140 }
160141
161142 //如果完全匹配没找到,再找前缀的
162- s .prefix .AscendGreaterOrEqual (& iface {path : r . URL . Path }, func (item btree.Item ) bool {
143+ s .prefix .AscendGreaterOrEqual (& iface {path : path }, func (item btree.Item ) bool {
163144 i = * (item .(* iface ))
164- ok = strings .HasPrefix (r .URL .Path , i .path )
145+ ok = strings .HasPrefix (path , i .path )
146+ log .Debugf ("path:%v, ipath:%v, ok:%v" , path , i .path , ok )
165147 return ! ok
166148 })
149+
150+ log .Debugf ("find prefix:%v, ok:%v" , path , ok )
167151 return
168152}
169153
@@ -189,9 +173,23 @@ func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
189173 SendResponse (w , http .StatusNotFound , "invalid request" )
190174 return
191175 }
176+
192177 log .Debugf ("%v %v %v %v" , r .RemoteAddr , r .Method , r .URL , i .path )
193178
194- i .call (w , nr )
179+ for j := 0 ; j < 10 ; j ++ {
180+ fmt .Printf ("========%p\n " , reflect .New (i .source ).Interface ())
181+ log .Debugf ("new:%p" , reflect .New (i .source ).Interface ())
182+ }
183+
184+ newObj := reflect .New (i .source )
185+ fmt .Printf ("obj:%p\n " , newObj )
186+ method := newObj .MethodByName (r .Method )
187+ callback := method .Interface ().(func (http.ResponseWriter , * http.Request ))
188+
189+ // callback := .MethodByName(r.Method).Interface()
190+
191+ callback (w , nr )
192+
195193 return
196194}
197195
0 commit comments