启动http服务
//使用gin.Run()启动http服务
//使用gin.RunTLS启动https服务
func (engine *Engine) Run(addr ...string) (err error) {
//获取端口,默认:8080
address := resolveAddress(addr)
debugPrint("Listening and serving HTTP on %s\n", address)
//调用go实现好的http功能包,实现http功能
//传入engine.Handler(),返回一个http Handler,由engine实现了该Handler函数ServeHTTP
err = http.ListenAndServe(address, engine.Handler())
return
}
gin.Run()函数调用go的官方包启动了一个http服务,并实现了http服务的回调ServeHTTP函数。当请求来的时候会调用gin的ServeHTTP函数
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
//使用对象池初始化Context
c := engine.pool.Get().(*Context)
//初始化writermem
//writermem继承http.ResponseWriter。用来http回复
c.writermem.reset(w)
c.Request = req
//初始化Context
c.reset()
//处理请求
engine.handleHTTPRequest(c)
//移出对象池
engine.pool.Put(c)
}
func (engine *Engine) handleHTTPRequest(c *Context) {
httpMethod := c.Request.Method
//省略一些参数初始化
// Find root of the tree for the given HTTP method
t := engine.trees
for i, tl := 0, len(t); i < tl; i++ {
if t[i].method != httpMethod {
continue
}
root := t[i].root
// 遍历请求树,找到方法
value := root.getValue(rPath, c.params, c.skippedNodes, unescape)
if value.params != nil {
c.Params = *value.params
}
// 开始调用中间件
if value.handlers != nil {
c.handlers = value.handlers
c.fullPath = value.fullPath
c.Next()
c.writermem.WriteHeaderNow()
return
}
//处理重定向
if httpMethod != http.MethodConnect && rPath != "/" {
if value.tsr && engine.RedirectTrailingSlash {
redirectTrailingSlash(c)
return
}
if engine.RedirectFixedPath && redirectFixedPath(c, root, engine.RedirectFixedPath) {
return
}
}
break
}
//处理404请