Go HTTP Server 使用分析
文章目录
Go 分类文章,学习笔记,会不定时修改,补充,纠错,增加内容,路漫漫。
使用 net/http 包处理 http request
GoDoc - https://godoc.org/net/http
net/http 主要包括两部分
- client
- server
这里就是关于 server 部分
Tip: go version go1.12.4 darwin/amd64
Handler interface
查看 http.ListenAndServe 定义
1 | func ListenAndServe(addr string, handler Handler) error { |
会发现第二个参数是 Handler 类型1
2
3type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
Handler 是一个接口定义,只要实现了 ServeHTTP(ResponseWriter, *Request) 方法的类型,都可以
http.ListenAndServe 执行流程
查看源码 net/http server.go 可以发现执行流程
1 | 3035: http.ListenAndServe() 的 func 内调用 server.ListenAndServe(),把 handler 赋值给了 Server.Handler 属性 |
查看 serverHandler 的定义
1 | // net/http server.go 2672 - 2775 |
http.HandlerFunc
1 | // net/http server.go 1991 - 1996 |
HandlerFunc 是一个函数值,值是 func(ResponseWriter, *Request) ,实现了 ServeHTTP func ,也就是实现了 Handler interface
常见的使用方式类似
1 | f := func(w http.ResponseWriter, r *http.Request) { |
http.NewServeMux
1 | // net/http server.go 2180 - 2193 |
通过调用 http.NewServeMux()
返回的是 *ServeMux
类型,而这个类型实现了对外的方法有
- func (mux *ServeMux) Handle(pattern string, handler Handler)
- func (mux ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, Request))
- func (mux ServeMux) Handler(r Request) (h Handler, pattern string)
- func (mux ServeMux) ServeHTTP(w ResponseWriter, r Request)
其中 Handle 和 HandleFunc 用于给 mux 添加对应 pattern 的对应的处理方法,这个两个的区别是
- Handle 直接传入满足 http.Handler interface 的参数
- HandleFunc 是传入了一个 func ,然后内部使用 http.HandlerFunc 转一下,就变成 http.Handler interface 了
mux 实现了 ServeHTTP 意味着,可以作为参数传入 http.ListenAndServe
mux 的 Handler 是用于根据请求,尤其是请求的 url ,找到对应的处理的 http.Handler,找不到对应的,默认都是匹配 /
的
DefaultServeMux
1 | // DefaultServeMux is the default ServeMux used by Serve. |
DefaultServeMux 这个就是 http 包默认的一个 ServeMux 处理,其实就是 *http.ServeMux 类型,完全可以参考 【http.NewServeMux】部分
对应 【http.ListenAndServe 执行流程】 可以得到如果 http.ListenAndServe 的第二个参数为 nil,调用的就是 DefaultServeMux 作为 handler
查看 http 对外暴露的 func
1 | func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) } |
DefaultServeMux 使用上的安全风险
由于 DefaultServeMux 是全局变量,因此任何程序都可以访问并注册路由 - 包括应用程序导入的任何第三方程序包。如果其中一个第三方包遭到破坏,他们可以使用 DefaultServeMux 向 Web 公开恶意 handler。
一般来说,建议使用 http.NewServeMux
手动创建
gorilla mux 使用
net/http 提供的 Handle 功能,通过传入 pattern 匹配 url 的方法,在简单使用场景下是足够的,但是不免有复杂的情况,提供功能强大的路由分发,这里推荐 mux
简单分析1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 查看源码
func NewRouter() *Router {
return &Router{namedRoutes: make(map[string]*Route)}
}
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// ....
}
// 本质上就是使用了 http.Handler interface
// 调用
r := mux.NewRouter()
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// code
})
http.ListenAndServe("***", r)
当然具体完整使用,还是看这个项目的文档吧
总结
这次,终于理清了 http server 的处理流程了 。
原文作者: dryyun
原文链接: https://dryyun.com/2019/06/06/go-http-server/
发布日期: 2019-06-06 23:28
许可协议: 知识共享署名-非商业性使用 4.0 国际许可协议