Skip to content

Commit f74b60e

Browse files
committed
test
1 parent 40102f0 commit f74b60e

File tree

6 files changed

+136
-92
lines changed

6 files changed

+136
-92
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fmt:
2424

2525

2626
crab:
27-
go build -o bin/$@ -ldflags '$(LDFLAGS)' ./main.go
27+
go build -gcflags="-N -l" -o bin/$@ -ldflags '$(LDFLAGS)' ./main.go
2828

2929

3030
test:

handler/handler.go

Lines changed: 73 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,27 @@ var (
1818
)
1919

2020
type 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

3027
func 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,直接返回,不再进行后续处理.
4536
type Filter func(http.ResponseWriter, *http.Request) *http.Request
4637

47-
// iface 对外服务接口
38+
// iface 对外服务接口, path格式:Method/URI
4839
type iface struct {
49-
method Method
5040
path string
51-
call Callback
41+
source reflect.Type
5242
}
5343

5444
func (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-
142131
func (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

main.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ package main
22

33
import (
44
"flag"
5+
"fmt"
56
"net"
67
"net/http"
8+
"time"
79

810
"github.com/dearcode/crab/handler"
911
_ "github.com/dearcode/crab/server"
1012
)
1113

14+
type index struct {
15+
}
16+
17+
func (i *index) GET(w http.ResponseWriter, req *http.Request) {
18+
fmt.Printf("index:%p\n", i)
19+
w.Write([]byte("ok"))
20+
time.Sleep(time.Minute)
21+
22+
}
23+
1224
func main() {
1325
addr := flag.String("h", ":9000", "api listen address")
1426
flag.Parse()
@@ -18,6 +30,8 @@ func main() {
1830
panic(err.Error())
1931
}
2032

33+
handler.Server.AddInterface(&index{}, "/index", false)
34+
2135
if err = http.Serve(ln, handler.Server); err != nil {
2236
panic(err.Error())
2337
}

server/init.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ import (
55
)
66

77
func init() {
8-
handler.Server.AddHandler(handler.GET, "/", true, onStaticGet)
9-
handler.Server.AddHandler(handler.GET, "/debug/", true, onDebugGet)
8+
handler.Server.AddInterface(&staticServer{}, "/", true)
9+
handler.Server.AddInterface(&debugServer{}, "/debug/", true)
1010

11-
handler.Server.AddHandler(handler.GET, "/test/", false, onTestGet)
12-
handler.Server.AddHandler(handler.POST, "/test/", false, onTestPost)
13-
handler.Server.AddHandler(handler.DELETE, "/test/", false, onTestDelete)
11+
handler.Server.AddInterface(&testServer{}, "/test/", false)
1412

15-
handler.Server.AddInterface(&user{}, "")
13+
handler.Server.AddInterface(&user{}, "", false)
1614
}

server/server.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,37 @@ import (
66
"net/http/pprof"
77
)
88

9-
//onTestGet 获取配置文件中域名
10-
func onTestGet(w http.ResponseWriter, r *http.Request) {
9+
type testServer struct {
10+
}
11+
12+
func (s *testServer) GET(w http.ResponseWriter, r *http.Request) {
1113
w.Write([]byte("Get test"))
1214
}
1315

14-
//onTestPost 获取配置文件中域名
15-
func onTestPost(w http.ResponseWriter, r *http.Request) {
16+
func (s *testServer) POST(w http.ResponseWriter, r *http.Request) {
1617
w.Write([]byte("Post test"))
1718
}
1819

19-
//onTestDelete 获取配置文件中域名
20-
func onTestDelete(w http.ResponseWriter, r *http.Request) {
20+
func (s *testServer) PUT(w http.ResponseWriter, r *http.Request) {
21+
w.Write([]byte("Put test"))
22+
}
23+
24+
func (s *testServer) DELETE(w http.ResponseWriter, r *http.Request) {
2125
w.Write([]byte("Delete test"))
2226
}
2327

24-
//onStaticGet 静态文件
25-
func onStaticGet(w http.ResponseWriter, r *http.Request) {
28+
type staticServer struct {
29+
}
30+
31+
func (s *staticServer) GET(w http.ResponseWriter, r *http.Request) {
2632
path := fmt.Sprintf("/var/www/html/%s", r.URL.Path)
2733
w.Header().Add("Cache-control", "no-store")
2834
http.ServeFile(w, r, path)
2935
}
3036

31-
//onDebugGet debug接口
32-
func onDebugGet(w http.ResponseWriter, r *http.Request) {
37+
type debugServer struct {
38+
}
39+
40+
func (s *debugServer) GET(w http.ResponseWriter, r *http.Request) {
3341
pprof.Index(w, r)
3442
}

v.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
)
7+
8+
type testServer struct {
9+
A int
10+
}
11+
12+
func test(t reflect.Type) {
13+
for i := 0; i < 10; i++ {
14+
fmt.Printf("new:%p\n", reflect.New(t).Interface())
15+
}
16+
}
17+
18+
func main() {
19+
t := &testServer{}
20+
21+
tt := reflect.TypeOf(t)
22+
23+
test(tt.Elem())
24+
25+
26+
}

0 commit comments

Comments
 (0)