@@ -24,13 +24,15 @@ Go在等待客户端请求里面是这样写的:
2424 type ServeMux struct {
2525 mu sync.RWMutex //锁,由于请求涉及到并发处理,因此这里需要一个锁机制
2626 m map[string]muxEntry // 路由规则,一个string对应一个mux实体,这里的string就是注册的路由表达式
27+ hosts bool // 是否在任意的规则中带有host信息
2728 }
2829
2930下面看一下muxEntry
3031
3132 type muxEntry struct {
3233 explicit bool // 是否精确匹配
3334 h Handler // 这个路由表达式对应哪个handler
35+ pattern string //匹配字符串
3436 }
3537
3638接着看一下Handler的定义
@@ -48,25 +50,47 @@ Handler是一个接口,但是前一小节中的`sayhelloName`函数并没有
4850 f(w, r)
4951 }
5052
51- 路由器里面存储好了相应的路由规则之后,那么具体的请求又是怎么分发的呢?
53+ 路由器里面存储好了相应的路由规则之后,那么具体的请求又是怎么分发的呢?请看下面的代码,默认的路由器实现了 ` ServeHTTP ` :
5254
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) `
5466
55- 也就是调用对应路由的handler的ServerHTTP接口,那么mux.handler (r)怎么处理的呢?
67+ 也就是调用对应路由的handler的ServerHTTP接口,那么mux.Handler (r)怎么处理的呢?
5668
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) {
5880 mux.mu.RLock()
5981 defer mux.mu.RUnlock()
60-
82+
6183 // 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+ }
6387 if h == nil {
64- h = mux.match(r.URL.Path )
88+ h, pattern = mux.match(path )
6589 }
6690 if h == nil {
67- h = NotFoundHandler()
91+ h, pattern = NotFoundHandler(), ""
6892 }
69- return h
93+ return
7094 }
7195
7296原来他是根据用户请求的URL和路由器里面存储的map去匹配的,当匹配到之后返回存储的handler,调用这个handler的ServHTTP接口就可以执行到相应的函数了。
0 commit comments