gin源码-获取请求参数

未匹配的标注

gin框架是如何获取请求参数的,我们以获取get参数为例,写一个简单的demo如下,最终得到调用链路

func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.String(200, c.Query("phone"))
    })
    _ = r.Run(":8000")
}

把关注点放在获取phone这个get参数上,得到的调用链路如下:

|-goroutine-50 created by net/http.(*Server).Serve.func3
  |-net/http.(*conn).serve
    |-w = net/http.(*conn).readRequest()                    // 获取请求
    |-net/http.serverHandler.ServeHTTP(w, w.req)            // 传递w.req
      |-github.com/gin-gonic/gin.(*Engine).ServeHTTP        // c.Request=w.req
        |-github.com/gin-gonic/gin.(*Engine).handleHTTPRequest
          |-github.com/gin-gonic/gin.LoggerWithConfig.func1
            |-github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1
              |-main.main.func1
                |-github.com/gin-gonic/gin.(*Context).Query // 最终解析c.Request.URL获取所有get参数
                  |-github.com/gin-gonic/gin.(*Context).GetQueryArray
                    |-net/url.(*URL).Query
        |-sync.(*Pool).Put
    |-net/http.(*response).finishRequest

可以看到主要是解析c.Request.URL得到get参数,而c.Request是通过net/http包的readRequest方法获取的。把关注点放在net/http.(*conn).readRequest()的执行流程上,得到:

|-w = net/http.(*conn).readRequest()
  |-w.req = net/http.readRequest()
    |-tp := net/http.newTextprotoReader()
    |-s = tp.ReadLine()                                           // 读取请求体的第一行
    |-req.Method, req.RequestURI, req.Proto = parseRequestLine(s) // 解析"GET /index.html HTTP/1.1"
    |-req.URL = url.ParseRequestURI(req.RequestURI)               // 设置req.URL
    |-mimeHeader := tp.ReadMIMEHeader()                           // 解析请求体的其他Key:value
    |-req.Header = Header(mimeHeader)                             // 设置req.Header
    |-readTransfer(req, b)                                        // 设置req.Body

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~