Skip to content

Commit 449ec2c

Browse files
committed
Remove 03.4.md spaces
1 parent 793af08 commit 449ec2c

File tree

1 file changed

+77
-77
lines changed

1 file changed

+77
-77
lines changed

zh/03.4.md

+77-77
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ Go的http有两个核心功能:Conn、ServeMux
99
Go在等待客户端请求里面是这样写的:
1010
```Go
1111

12-
c, err := srv.newConn(rw)
13-
if err != nil {
14-
continue
15-
}
16-
go c.serve()
12+
c, err := srv.newConn(rw)
13+
if err != nil {
14+
continue
15+
}
16+
go c.serve()
1717

1818
```
1919
这里我们可以看到客户端的每次请求都会创建一个Conn,这个Conn里面保存了该次请求的信息,然后再传递到对应的handler,该handler中便可以读取到相应的header信息,这样保证了每个请求的独立性。
@@ -24,85 +24,85 @@ Go在等待客户端请求里面是这样写的:
2424
它的结构如下:
2525
```Go
2626

27-
type ServeMux struct {
28-
mu sync.RWMutex //锁,由于请求涉及到并发处理,因此这里需要一个锁机制
29-
m map[string]muxEntry // 路由规则,一个string对应一个mux实体,这里的string就是注册的路由表达式
30-
hosts bool // 是否在任意的规则中带有host信息
31-
}
27+
type ServeMux struct {
28+
mu sync.RWMutex //锁,由于请求涉及到并发处理,因此这里需要一个锁机制
29+
m map[string]muxEntry // 路由规则,一个string对应一个mux实体,这里的string就是注册的路由表达式
30+
hosts bool // 是否在任意的规则中带有host信息
31+
}
3232

3333
```
3434
下面看一下muxEntry
3535
```Go
3636

37-
type muxEntry struct {
38-
explicit bool // 是否精确匹配
39-
h Handler // 这个路由表达式对应哪个handler
40-
pattern string //匹配字符串
41-
}
37+
type muxEntry struct {
38+
explicit bool // 是否精确匹配
39+
h Handler // 这个路由表达式对应哪个handler
40+
pattern string //匹配字符串
41+
}
4242

4343
```
4444
接着看一下Handler的定义
4545
```Go
4646

47-
type Handler interface {
48-
ServeHTTP(ResponseWriter, *Request) // 路由实现器
49-
}
47+
type Handler interface {
48+
ServeHTTP(ResponseWriter, *Request) // 路由实现器
49+
}
5050

5151
```
5252
Handler是一个接口,但是前一小节中的`sayhelloName`函数并没有实现ServeHTTP这个接口,为什么能添加呢?原来在http包里面还定义了一个类型`HandlerFunc`,我们定义的函数`sayhelloName`就是这个HandlerFunc调用之后的结果,这个类型默认就实现了ServeHTTP这个接口,即我们调用了HandlerFunc(f),强制类型转换f成为HandlerFunc类型,这样f就拥有了ServeHTTP方法。
5353
```Go
5454

55-
type HandlerFunc func(ResponseWriter, *Request)
55+
type HandlerFunc func(ResponseWriter, *Request)
5656

57-
// ServeHTTP calls f(w, r).
58-
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
59-
f(w, r)
60-
}
57+
// ServeHTTP calls f(w, r).
58+
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
59+
f(w, r)
60+
}
6161
```
6262
路由器里面存储好了相应的路由规则之后,那么具体的请求又是怎么分发的呢?请看下面的代码,默认的路由器实现了`ServeHTTP`
6363
```Go
6464

65-
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
66-
if r.RequestURI == "*" {
67-
w.Header().Set("Connection", "close")
68-
w.WriteHeader(StatusBadRequest)
69-
return
70-
}
71-
h, _ := mux.Handler(r)
72-
h.ServeHTTP(w, r)
65+
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
66+
if r.RequestURI == "*" {
67+
w.Header().Set("Connection", "close")
68+
w.WriteHeader(StatusBadRequest)
69+
return
7370
}
71+
h, _ := mux.Handler(r)
72+
h.ServeHTTP(w, r)
73+
}
7474
```
7575
如上所示路由器接收到请求之后,如果是`*`那么关闭链接,不然调用`mux.Handler(r)`返回对应设置路由的处理Handler,然后执行`h.ServeHTTP(w, r)`
7676

7777
也就是调用对应路由的handler的ServerHTTP接口,那么mux.Handler(r)怎么处理的呢?
7878
```Go
7979

80-
func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
81-
if r.Method != "CONNECT" {
82-
if p := cleanPath(r.URL.Path); p != r.URL.Path {
83-
_, pattern = mux.handler(r.Host, p)
84-
return RedirectHandler(p, StatusMovedPermanently), pattern
85-
}
86-
}
87-
return mux.handler(r.Host, r.URL.Path)
88-
}
89-
90-
func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
91-
mux.mu.RLock()
92-
defer mux.mu.RUnlock()
93-
94-
// Host-specific pattern takes precedence over generic ones
95-
if mux.hosts {
96-
h, pattern = mux.match(host + path)
97-
}
98-
if h == nil {
99-
h, pattern = mux.match(path)
80+
func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
81+
if r.Method != "CONNECT" {
82+
if p := cleanPath(r.URL.Path); p != r.URL.Path {
83+
_, pattern = mux.handler(r.Host, p)
84+
return RedirectHandler(p, StatusMovedPermanently), pattern
10085
}
101-
if h == nil {
102-
h, pattern = NotFoundHandler(), ""
103-
}
104-
return
86+
}
87+
return mux.handler(r.Host, r.URL.Path)
88+
}
89+
90+
func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
91+
mux.mu.RLock()
92+
defer mux.mu.RUnlock()
93+
94+
// Host-specific pattern takes precedence over generic ones
95+
if mux.hosts {
96+
h, pattern = mux.match(host + path)
97+
}
98+
if h == nil {
99+
h, pattern = mux.match(path)
105100
}
101+
if h == nil {
102+
h, pattern = NotFoundHandler(), ""
103+
}
104+
return
105+
}
106106
```
107107
原来他是根据用户请求的URL和路由器里面存储的map去匹配的,当匹配到之后返回存储的handler,调用这个handler的ServeHTTP接口就可以执行到相应的函数了。
108108

@@ -111,33 +111,33 @@ Handler是一个接口,但是前一小节中的`sayhelloName`函数并没有
111111
如下代码所示,我们自己实现了一个简易的路由器
112112
```Go
113113

114-
package main
114+
package main
115115

116-
import (
117-
"fmt"
118-
"net/http"
119-
)
116+
import (
117+
"fmt"
118+
"net/http"
119+
)
120120

121-
type MyMux struct {
122-
}
121+
type MyMux struct {
122+
}
123123

124-
func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
125-
if r.URL.Path == "/" {
126-
sayhelloName(w, r)
127-
return
128-
}
129-
http.NotFound(w, r)
124+
func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
125+
if r.URL.Path == "/" {
126+
sayhelloName(w, r)
130127
return
131128
}
132-
133-
func sayhelloName(w http.ResponseWriter, r *http.Request) {
134-
fmt.Fprintf(w, "Hello myroute!")
135-
}
136-
137-
func main() {
138-
mux := &MyMux{}
139-
http.ListenAndServe(":9090", mux)
140-
}
129+
http.NotFound(w, r)
130+
return
131+
}
132+
133+
func sayhelloName(w http.ResponseWriter, r *http.Request) {
134+
fmt.Fprintf(w, "Hello myroute!")
135+
}
136+
137+
func main() {
138+
mux := &MyMux{}
139+
http.ListenAndServe(":9090", mux)
140+
}
141141
```
142142
## Go代码的执行流程
143143

0 commit comments

Comments
 (0)