- 怎么定义 Handler?
- 怎么定义 Server?
- 怎么定义 Middleware? 如何用?
目录
自定义 Handler
标准库http提供了Handler接口,用于开发者实现自己的handler。只要实现接口的ServeHTTP方法即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
type textHandler struct {
responseText string
}
func (th *textHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, th.responseText)
}
func main() {
mux := http.NewServeMux()
mux.Handle("/", &textHandler{"你好呀!"})
http.ListenAndServe(":8082", mux)
}
|
Note:Server 实例的 Handler 字段最后通过 mux 初始化
自定义 Server
使用 http.Server 创建自定义的 server 对象
1
2
3
4
5
6
7
8
9
10
11
12
13
|
func main() {
mux := http.NewServeMux()
http.HandleFunc("/", textHandler)
server := &http.Server{
Addr: ":8082",
ReadTimeout: 60 * time.Second,
WriteTimeout: 60 * time.Second,
Handler: mux,
}
server.ListenAndServe()
}
|
中间件 Middleware
中间件:一般是指应用程序中封装原始信息,添加额外功能的组件。
- 一个好的中间件拥有单一的功能, 可插拔并且是自我约束的
应用方向:
- 通过隐藏长度缓解BREACH攻击
- 频率限制
- 屏蔽恶意自动程序
- 提供调试信息
- 添加HSTS, X-Frame-Options头
- 从异常中优雅恢复
- 以及其他等等。
前文的 HandleFunc 就能把签名为 func(w http.ResponseWriter, r *http.Reqeust)的函数包裹成handler。这个函数也算是中间件。
Go 的 HTTP 中间件很简单,只要实现一个函数签名为:func(http.Handler) http.Handler
的函数即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func IndexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "你好呀!")
}
func logger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
log.Printf("starting %s %s\n", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
log.Printf("finished %s in %v\n", r.URL.Path, time.Since(start))
})
}
func hook(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("before hook")
next.ServeHTTP(w, r)
log.Println("after hook")
})
}
func main() {
http.Handle("/hi", hook(logger(http.HandlerFunc(IndexHandler))))
http.ListenAndServe(":8082", nil)
}
|
如上,函数调用形成了一条链,可以在这条链上做很多事情。loggerHandler 记录请求开始和完成时间,hook 又包裹了 loggerHandler 可以在日志记录之前做对应的处理。
See Also
Thanks to the authors 🙂
返回目录