@@ -24,13 +24,15 @@ Go在等待客户端请求里面是这样写的:
24
24
type ServeMux struct {
25
25
mu sync.RWMutex //锁,由于请求涉及到并发处理,因此这里需要一个锁机制
26
26
m map[string]muxEntry // 路由规则,一个string对应一个mux实体,这里的string就是注册的路由表达式
27
+ hosts bool // 是否在任意的规则中带有host信息
27
28
}
28
29
29
30
下面看一下muxEntry
30
31
31
32
type muxEntry struct {
32
33
explicit bool // 是否精确匹配
33
34
h Handler // 这个路由表达式对应哪个handler
35
+ pattern string //匹配字符串
34
36
}
35
37
36
38
接着看一下Handler的定义
@@ -48,25 +50,47 @@ Handler是一个接口,但是前一小节中的`sayhelloName`函数并没有
48
50
f(w, r)
49
51
}
50
52
51
- 路由器里面存储好了相应的路由规则之后,那么具体的请求又是怎么分发的呢?
53
+ 路由器里面存储好了相应的路由规则之后,那么具体的请求又是怎么分发的呢?请看下面的代码,默认的路由器实现了 ` ServeHTTP ` :
52
54
53
- 路由器接收到请求之后调用` mux.handler(r).ServeHTTP(w, r) `
55
+ func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
56
+ if r.RequestURI == "*" {
57
+ w.Header().Set("Connection", "close")
58
+ w.WriteHeader(StatusBadRequest)
59
+ return
60
+ }
61
+ h, _ := mux.Handler(r)
62
+ h.ServeHTTP(w, r)
63
+ }
64
+
65
+ 如上所示路由器接收到请求之后,如果是` * ` 那么关闭链接,不然调用` mux.Handler(r) ` 返回对应设置路由的处理Handler,然后执行` h.ServeHTTP(w, r) `
54
66
55
- 也就是调用对应路由的handler的ServerHTTP接口,那么mux.handler (r)怎么处理的呢?
67
+ 也就是调用对应路由的handler的ServerHTTP接口,那么mux.Handler (r)怎么处理的呢?
56
68
57
- func (mux *ServeMux) handler(r *Request) Handler {
69
+ func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
70
+ if r.Method != "CONNECT" {
71
+ if p := cleanPath(r.URL.Path); p != r.URL.Path {
72
+ _, pattern = mux.handler(r.Host, p)
73
+ return RedirectHandler(p, StatusMovedPermanently), pattern
74
+ }
75
+ }
76
+ return mux.handler(r.Host, r.URL.Path)
77
+ }
78
+
79
+ func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
58
80
mux.mu.RLock()
59
81
defer mux.mu.RUnlock()
60
-
82
+
61
83
// Host-specific pattern takes precedence over generic ones
62
- h := mux.match(r.Host + r.URL.Path)
84
+ if mux.hosts {
85
+ h, pattern = mux.match(host + path)
86
+ }
63
87
if h == nil {
64
- h = mux.match(r.URL.Path )
88
+ h, pattern = mux.match(path )
65
89
}
66
90
if h == nil {
67
- h = NotFoundHandler()
91
+ h, pattern = NotFoundHandler(), ""
68
92
}
69
- return h
93
+ return
70
94
}
71
95
72
96
原来他是根据用户请求的URL和路由器里面存储的map去匹配的,当匹配到之后返回存储的handler,调用这个handler的ServHTTP接口就可以执行到相应的函数了。
0 commit comments