Golang http之server源码详解

我会带着你远行 2022-02-17 12:14 374阅读 0赞
  1. http 是典型的 C/S 架构,客户端向服务端发送请求(request),服务端做出应答(response)。HTTP server–简而言之就是一个支持http协议的服务,http是一个相对简单的请求—响应的协议,通常是运行在TCP连接之上, 通过客户端发送请求到服务端,获取服务端的响应。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NraDIwMTVqYXZh_size_16_color_FFFFFF_t_70

我们先看一个简单的http server例子

  1. package main
  2. import (
  3. "io"
  4. "net/http"
  5. "log"
  6. )
  7. // hello world, the web server
  8. func HelloServer(w http.ResponseWriter, req *http.Request) {
  9. io.WriteString(w, "hello, world!\n")
  10. }
  11. func main() {
  12. //路由注册
  13. http.HandleFunc("/hello", HelloServer)
  14. //开启一个http服务
  15. log.Fatal(http.ListenAndServe(":8086", nil))
  16. }

当服务器启动后,浏览器访问:http://127.0.0.1:8086/hello

网页上会显示:

20190419155204779.png

以上就是http 服务的一个简单demo,下面我们主要从源码来分析http server

源码分析

一、 常用概念

1.Handler接口

  1. type Handler interface {
  2. ServeHTTP(ResponseWriter, *Request)
  3. }

作用:Handler封装了处理客户端的请求逻辑及创建返回响应的逻辑,一个http server需要实现Handler接口。

2.Server结构体

  1. //Server定义一个HTTP 服务
  2. type Server struct {
  3. //监听的TCP地址
  4. Addr string // TCP address to listen on, ":http" if empty
  5. //要调用的处理函数,如果为nil,则默认用http.DefaultServeMux
  6. Handler Handler // handler to invoke, http.DefaultServeMux if nil
  7. // TLSConfig optionally provides a TLS configuration for use
  8. // by ServeTLS and ListenAndServeTLS. Note that this value is
  9. // cloned by ServeTLS and ListenAndServeTLS, so it's not
  10. // possible to modify the configuration with methods like
  11. // tls.Config.SetSessionTicketKeys. To use
  12. // SetSessionTicketKeys, use Server.Serve with a TLS Listener
  13. // instead.
  14. /*
  15. TLSConfig可以选择提供TLS 配置 用于使用ServeTLS 和 ListenAndServeTLS
  16. */
  17. TLSConfig *tls.Config
  18. // ReadTimeout is the maximum duration for reading the entire
  19. // request, including the body.
  20. //
  21. // Because ReadTimeout does not let Handlers make per-request
  22. // decisions on each request body's acceptable deadline or
  23. // upload rate, most users will prefer to use
  24. // ReadHeaderTimeout. It is valid to use them both.
  25. //ReadTimeout读取请求的最长时间,包括正文
  26. ReadTimeout time.Duration
  27. // ReadHeaderTimeout is the amount of time allowed to read
  28. // request headers. The connection's read deadline is reset
  29. // after reading the headers and the Handler can decide what
  30. // is considered too slow for the body.
  31. //ReadHeaderTimeout是允许读取请求头的最长时间
  32. //读完请求头后会重置超时间,并且Handler可以判断太慢的body
  33. ReadHeaderTimeout time.Duration
  34. // WriteTimeout is the maximum duration before timing out
  35. // writes of the response. It is reset whenever a new
  36. // request's header is read. Like ReadTimeout, it does not
  37. // let Handlers make decisions on a per-request basis.
  38. //WriteTimeout是写入响应之前的最大持续时间。 只要读取新请求的标头,它就会重置。 与ReadTimeout一样,它不允许处理程序根据请求做出决策。
  39. WriteTimeout time.Duration
  40. // IdleTimeout is the maximum amount of time to wait for the
  41. // next request when keep-alives are enabled. If IdleTimeout
  42. // is zero, the value of ReadTimeout is used. If both are
  43. // zero, ReadHeaderTimeout is used.
  44. //当开启keep-alives时,IdleTimeout是等待下个请求的最长时间,如果IdleTimeout是0,则使用ReadTimeout,如果ReadTimeout也是0,则使用ReadHeaderTimeout
  45. IdleTimeout time.Duration
  46. // MaxHeaderBytes controls the maximum number of bytes the
  47. // server will read parsing the request header's keys and
  48. // values, including the request line. It does not limit the
  49. // size of the request body.
  50. // If zero, DefaultMaxHeaderBytes is used.
  51. //请求头的最大字节数,如果是0,则使用默认值DefaultMaxHeaderBytes
  52. MaxHeaderBytes int
  53. // TLSNextProto optionally specifies a function to take over
  54. // ownership of the provided TLS connection when an NPN/ALPN
  55. // protocol upgrade has occurred. The map key is the protocol
  56. // name negotiated. The Handler argument should be used to
  57. // handle HTTP requests and will initialize the Request's TLS
  58. // and RemoteAddr if not already set. The connection is
  59. // automatically closed when the function returns.
  60. // If TLSNextProto is not nil, HTTP/2 support is not enabled
  61. // automatically.
  62. /*
  63. TLSNextProto可选地指定在发生NPN / ALPN协议升级时接管所提供的TLS连接的所有权的函数。 映射键是协商的协议名称。
  64. */
  65. TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
  66. // ConnState specifies an optional callback function that is
  67. // called when a client connection changes state. See the
  68. // ConnState type and associated constants for details.
  69. /*
  70. ConnState指定在客户端连接更改状态时调用的可选回调函数。
  71. */
  72. ConnState func(net.Conn, ConnState)
  73. // ErrorLog specifies an optional logger for errors accepting
  74. // connections, unexpected behavior from handlers, and
  75. // underlying FileSystem errors.
  76. // If nil, logging is done via the log package's standard logger.
  77. ErrorLog *log.Logger
  78. disableKeepAlives int32 // accessed atomically.原子访问
  79. inShutdown int32 // accessed atomically (non-zero means we're in Shutdown) 原子访问,非零意味着已关闭
  80. nextProtoOnce sync.Once // guards setupHTTP2_* init
  81. nextProtoErr error // result of http2.ConfigureServer if used 如果使用http2.ConfigureServer的结果
  82. mu sync.Mutex
  83. listeners map[net.Listener]struct{} //记录所有监听net.Listener信息
  84. activeConn map[*conn]struct{} //记录所有处于active状态的连接
  85. doneChan chan struct{}
  86. onShutdown []func()
  87. }

Server定义了一个HTTP服务,里面包含了监听的TCP地址Addr,处理客户端请求的Handler,以及其他相关的配置信息

3.conn结构体

  1. // A conn represents the server side of an HTTP connection.
  2. //conn表示HTTP连接的服务器端。
  3. type conn struct {
  4. // server is the server on which the connection arrived.
  5. // Immutable; never nil.
  6. //server是连接到达的服务器,不能改变,不能为空。
  7. server *Server
  8. // cancelCtx cancels the connection-level context.
  9. //用于取消连接的上下文
  10. cancelCtx context.CancelFunc
  11. // rwc is the underlying network connection.
  12. // This is never wrapped by other types and is the value given out
  13. // to CloseNotifier callers. It is usually of type *net.TCPConn or
  14. // *tls.Conn.
  15. //rwc是网络底层连接,不能被其他类型包装
  16. //常用类型是 *net.TCPConn *tls.Conn
  17. rwc net.Conn
  18. // remoteAddr is rwc.RemoteAddr().String(). It is not populated synchronously
  19. // inside the Listener's Accept goroutine, as some implementations block.
  20. // It is populated immediately inside the (*conn).serve goroutine.
  21. // This is the value of a Handler's (*Request).RemoteAddr.
  22. //rwc.RemoteAddr().String() 客户端连接地址
  23. /*
  24. 它不会在Listener的Accept goroutine中同步填充,因为某些实现会阻塞。 它立即填充在(* conn).serve goroutine中。
  25. 这是Handler's(* Request).RemoteAddr的值。
  26. */
  27. remoteAddr string
  28. // tlsState is the TLS connection state when using TLS.
  29. // nil means not TLS.
  30. //如果使用的是TLS,则表示TLS连接状态,nil表示没有TLS
  31. tlsState *tls.ConnectionState
  32. // werr is set to the first write error to rwc.
  33. // It is set via checkConnErrorWriter{w}, where bufw writes.
  34. //werr设置为rwc的第一个写入错误。 它通过checkConnErrorWriter {w}设置,其中bufw写入。
  35. werr error
  36. // r is bufr's read source. It's a wrapper around rwc that provides
  37. // io.LimitedReader-style limiting (while reading request headers)
  38. // and functionality to support CloseNotifier. See *connReader docs.
  39. //是数据源用于bufr读取数据,它包装了rwc,提供o.LimitedReader-style
  40. r *connReader
  41. // bufr reads from r.
  42. //从r中读取数据
  43. bufr *bufio.Reader
  44. // bufw writes to checkConnErrorWriter{c}, which populates werr on error.
  45. //给 checkConnErrorWriter{c} 写
  46. bufw *bufio.Writer
  47. // lastMethod is the method of the most recent request
  48. // on this connection, if any.
  49. lastMethod string
  50. curReq atomic.Value // 记录Request个数
  51. curState atomic.Value // 记录连接状态 ConnState
  52. // mu guards hijackedv
  53. mu sync.Mutex
  54. // hijackedv is whether this connection has been hijacked
  55. // by a Handler with the Hijacker interface.
  56. // It is guarded by mu.
  57. //判断Handler中是否实现Hijacker接口
  58. hijackedv bool
  59. }

conn表示HTTP连接,它将底层的连接如:*net.TCPConn和 *tls.Conn进行封装

4.response结构体

  1. type response struct {
  2. conn *conn //网络连接
  3. req *Request // 客户端的请求信息
  4. reqBody io.ReadCloser
  5. cancelCtx context.CancelFunc // when ServeHTTP exits 当ServeHTTP退出时调用
  6. wroteHeader bool // reply header has been (logically) written header是否已经写入
  7. wroteContinue bool // 100 Continue response was written 100 Continue 响应已写入
  8. wants10KeepAlive bool // HTTP/1.0 w/ Connection "keep-alive" 是否保持长连接
  9. wantsClose bool // HTTP request has Connection "close" 客户端想要断开连接
  10. w *bufio.Writer // buffers output in chunks to chunkWriter 将缓冲区块输出到chunkWriter
  11. cw chunkWriter
  12. // handlerHeader is the Header that Handlers get access to,
  13. // which may be retained and mutated even after WriteHeader.
  14. // handlerHeader is copied into cw.header at WriteHeader
  15. // time, and privately mutated thereafter.
  16. handlerHeader Header
  17. calledHeader bool // handler accessed handlerHeader via Header
  18. written int64 // number of bytes written in body 写入到body中的字节数
  19. contentLength int64 // explicitly-declared Content-Length; or -1 声明的Content-Length
  20. status int // status code passed to WriteHeader 传递给WriteHeader的状态码
  21. // close connection after this reply. set on request and
  22. // updated after response from handler if there's a
  23. // "Connection: keep-alive" response header and a
  24. // Content-Length.
  25. closeAfterReply bool //判断在响应后是否关闭连接
  26. // requestBodyLimitHit is set by requestTooLarge when
  27. // maxBytesReader hits its max size. It is checked in
  28. // WriteHeader, to make sure we don't consume the
  29. // remaining request body to try to advance to the next HTTP
  30. // request. Instead, when this is set, we stop reading
  31. // subsequent requests on this connection and stop reading
  32. // input from it.
  33. requestBodyLimitHit bool
  34. // trailers are the headers to be sent after the handler
  35. // finishes writing the body. This field is initialized from
  36. // the Trailer response header when the response header is
  37. // written.
  38. trailers []string
  39. handlerDone atomicBool // set true when the handler exits
  40. // Buffers for Date, Content-Length, and status code
  41. dateBuf [len(TimeFormat)]byte
  42. clenBuf [10]byte
  43. statusBuf [3]byte
  44. // closeNotifyCh is the channel returned by CloseNotify.
  45. // TODO(bradfitz): this is currently (for Go 1.8) always
  46. // non-nil. Make this lazily-created again as it used to be?
  47. closeNotifyCh chan bool
  48. didCloseNotify int32 // atomic (only 0->1 winner should send)
  49. }

#

二、http服务创建过程

  1. 我们根据上面提到过的demo来分析http服务创建的过程
  2. // hello world, the web server
  3. func HelloServer(w http.ResponseWriter, req *http.Request) {
  4. io.WriteString(w, "hello, world!\n")
  5. }
  6. func main() {
  7. //路由注册
  8. http.HandleFunc("/hello", HelloServer)
  9. //开启一个http服务
  10. log.Fatal(http.ListenAndServe(":8086", nil))
  11. }

大致流程如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NraDIwMTVqYXZh_size_16_color_FFFFFF_t_70 1

第一步:路由注册

  1. // HandleFunc registers the handler function for the given pattern
  2. // in the DefaultServeMux.
  3. // The documentation for ServeMux explains how patterns are matched.
  4. func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
  5. DefaultServeMux.HandleFunc(pattern, handler)
  6. }

这里使用http.HandleFunc是使用http包自带的DefaultServeMux来进行服务的路由注册与管理。DefaultServeMux是全局变量,DefaultServeMux的定义如下:

  1. // DefaultServeMux is the default ServeMux used by Serve.
  2. var DefaultServeMux = &defaultServeMux
  3. var defaultServeMux ServeMux
  4. /*
  5. HandleFunc根据给定的pattern注册handler函数
  6. 路由注册
  7. */
  8. func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
  9. mux.Handle(pattern, HandlerFunc(handler))
  10. }
  11. /*
  12. Handle 根据给定的pattern注册 handler,如果pattern已经注册过,则panic
  13. */
  14. func (mux *ServeMux) Handle(pattern string, handler Handler) {
  15. mux.mu.Lock()
  16. defer mux.mu.Unlock()
  17. /*
  18. 如果pattern为"",或者handler为nil,或者该pattern已经注册,则panic
  19. */
  20. if pattern == "" {
  21. panic("http: invalid pattern")
  22. }
  23. if handler == nil {
  24. panic("http: nil handler")
  25. }
  26. if _, exist := mux.m[pattern]; exist {
  27. panic("http: multiple registrations for " + pattern)
  28. }
  29. if mux.m == nil { //如果m为nil,则初始化
  30. mux.m = make(map[string]muxEntry)
  31. }
  32. //将pattern和handler注册到m中
  33. mux.m[pattern] = muxEntry{h: handler, pattern: pattern}
  34. if pattern[0] != '/' { //pattern第一个字符为'/',则hosts为true。说明该pattern包含主机名
  35. mux.hosts = true
  36. }
  37. }
  38. 从以上代码可以看到路由的注册最后注册到了ServeMux结构体的m字段中,mmap格式储存了patternHandler的对应关系。ServeMux结构体如下:
  39. type ServeMux struct {
  40. mu sync.RWMutex
  41. m map[string]muxEntry //path和muxEntry的对应关系
  42. hosts bool // pattern是否包含主机名
  43. }
  44. type muxEntry struct {
  45. h Handler
  46. pattern string
  47. }
  48. ServeMuxHTTP请求的多路复用路由器,负责接收http handler的注册和路由解析。将所有的路径(pattern)与对应的处理函数映射存入到map表中。它将每个传入请求的URL与已注册模式列表进行匹配,并获取与URL最匹配的handler

二、开启服务,监听客户端连接

  1. func ListenAndServe(addr string, handler Handler) error {
  2. server := &Server{Addr: addr, Handler: handler}
  3. return server.ListenAndServe()
  4. }
  5. ListenAndServe 监听TCP的网络地址然后调用Servehandler来处理连接上的请求,接收到的连接默认是启用TCPkeep-alives,也就是保持长连接,如果Handlernil,则默认使用DefaultServeMux
  6. 根据addr是监听的tcp地址和Handler创建服务server,然后调用ListenAndServe方法,ListenAndServe方法如下:
  7. func (srv *Server) ListenAndServe() error {
  8. addr := srv.Addr
  9. if addr == "" {
  10. addr = ":http"
  11. }
  12. ln, err := net.Listen("tcp", addr)
  13. if err != nil {
  14. return err
  15. }
  16. return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
  17. }
  18. 监听TCP网络地址srv.Addr,然后调用Serve来处理传入连接上的请求。 接受的连接配置为启用TCP长连接。 如果srv.Addr为空,则使用":http"
  19. func (srv *Server) Serve(l net.Listener) error {
  20. defer l.Close()
  21. //如果testHookServerServe不为nil,则调用
  22. if fn := testHookServerServe; fn != nil {
  23. fn(srv, l)
  24. }
  25. var tempDelay time.Duration // how long to sleep on accept failure 当接收失败休眠多久
  26. //设置HTTP2的相关信息
  27. if err := srv.setupHTTP2_Serve(); err != nil {
  28. return err
  29. }
  30. //添加到srv的listeners中,listeners记录所有的监听器
  31. srv.trackListener(l, true)
  32. defer srv.trackListener(l, false)
  33. //初始化上下文,其父级是emptyCtx,用于保存key为ServerContextKey,value是对应的Server服务
  34. baseCtx := context.Background() // base is always background, per Issue 16220
  35. ctx := context.WithValue(baseCtx, ServerContextKey, srv)
  36. //监听新的tcp连接
  37. for {
  38. rw, e := l.Accept() //rw监听到连接的tcp,rw是net.Conn
  39. if e != nil {
  40. select {
  41. case <-srv.getDoneChan(): //Server已关闭
  42. return ErrServerClosed
  43. default:
  44. }
  45. if ne, ok := e.(net.Error); ok && ne.Temporary() { //如果是接收失败的错误
  46. if tempDelay == 0 { //接收等待时间为0,则给于默认值
  47. tempDelay = 5 * time.Millisecond
  48. } else { //接收等待时间扩大两倍
  49. tempDelay *= 2
  50. }
  51. if max := 1 * time.Second; tempDelay > max { //最大等待时间为1s,如果大于1s,则赋值为1s
  52. tempDelay = max
  53. }
  54. srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
  55. time.Sleep(tempDelay)
  56. continue
  57. }
  58. return e
  59. }
  60. tempDelay = 0 //接收失败等待时间置为0
  61. c := srv.newConn(rw) //将net.Conn封装成http.conn
  62. c.setState(c.rwc, StateNew) // 设置连接状态
  63. go c.serve(ctx) //每一个新的连接,开启一个协程执行serve函数
  64. }
  65. }
  66. Serve方法 接收Listener l 上传入的连接,为每个连接开启一个服的goroutine,新开启的goroutine执行serve方法。也就是读取客户端的请求数据,然后根据URL获取对应的HandlerHandler就是处理请求并响应客户端的请求。
  67. func (c *conn) serve(ctx context.Context) {
  68. c.remoteAddr = c.rwc.RemoteAddr().String() //获取远程地址
  69. ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr()) //创建一个子Context,父Context为ctx
  70. defer func() {
  71. if err := recover(); err != nil && err != ErrAbortHandler { //处理panic
  72. const size = 64 << 10
  73. buf := make([]byte, size)
  74. buf = buf[:runtime.Stack(buf, false)]
  75. c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
  76. }
  77. if !c.hijacked() { //没有hijacked挂住,则关闭连接,改变ConnState
  78. c.close()
  79. c.setState(c.rwc, StateClosed)
  80. }
  81. }()
  82. //处理tls的连接
  83. if tlsConn, ok := c.rwc.(*tls.Conn); ok { //如果该连接是tls.Conn ,常见连接是net.TcpConn 和 tls.Conn
  84. if d := c.server.ReadTimeout; d != 0 { //设置读超时时间
  85. c.rwc.SetReadDeadline(time.Now().Add(d))
  86. }
  87. if d := c.server.WriteTimeout; d != 0 { //设置写超时时间
  88. c.rwc.SetWriteDeadline(time.Now().Add(d))
  89. }
  90. if err := tlsConn.Handshake(); err != nil { //运行客户端或服务器握手协议,如果有错误则返回
  91. c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err)
  92. return
  93. }
  94. c.tlsState = new(tls.ConnectionState)
  95. *c.tlsState = tlsConn.ConnectionState()
  96. if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) { //协商下一个协议
  97. if fn := c.server.TLSNextProto[proto]; fn != nil {
  98. h := initNPNRequest{tlsConn, serverHandler{c.server}} //初始化NPN请求
  99. fn(c.server, tlsConn, h)
  100. }
  101. return
  102. }
  103. }
  104. // HTTP/1.x from here on.
  105. //创建上下文
  106. ctx, cancelCtx := context.WithCancel(ctx)
  107. c.cancelCtx = cancelCtx
  108. defer cancelCtx()
  109. //初始化connReader
  110. c.r = &connReader{conn: c}
  111. //初始化bufioReader用于读数据
  112. c.bufr = newBufioReader(c.r)
  113. //初始化bufw用于写数据
  114. c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
  115. for {
  116. //读取Request,并封装成Response
  117. w, err := c.readRequest(ctx)
  118. if c.r.remain != c.server.initialReadLimitSize() {
  119. // If we read any bytes off the wire, we're active.
  120. c.setState(c.rwc, StateActive)
  121. }
  122. if err != nil { //错误处理
  123. const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
  124. if err == errTooLarge {
  125. // Their HTTP client may or may not be
  126. // able to read this if we're
  127. // responding to them and hanging up
  128. // while they're still writing their
  129. // request. Undefined behavior.
  130. const publicErr = "431 Request Header Fields Too Large"
  131. fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
  132. c.closeWriteAndWait()
  133. return
  134. }
  135. if isCommonNetReadError(err) {
  136. return // don't reply
  137. }
  138. publicErr := "400 Bad Request"
  139. if v, ok := err.(badRequestError); ok {
  140. publicErr = publicErr + ": " + string(v)
  141. }
  142. fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
  143. return
  144. }
  145. // Expect 100 Continue support
  146. req := w.req
  147. if req.expectsContinue() { //如果用户的请求期望 100-continue
  148. if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
  149. // Wrap the Body reader with one that replies on the connection
  150. //将请求的body进行封装
  151. req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
  152. }
  153. } else if req.Header.get("Expect") != "" { //如果Header的Expect的值不是100-continue则返回错误码
  154. w.sendExpectationFailed()
  155. return
  156. }
  157. c.curReq.Store(w) //储存response,并且response中有request
  158. if requestBodyRemains(req.Body) {
  159. registerOnHitEOF(req.Body, w.conn.r.startBackgroundRead)
  160. } else {
  161. if w.conn.bufr.Buffered() > 0 {
  162. w.conn.r.closeNotifyFromPipelinedRequest()
  163. }
  164. w.conn.r.startBackgroundRead()
  165. }
  166. // HTTP cannot have multiple simultaneous active requests.[*]
  167. // Until the server replies to this request, it can't read another,
  168. // so we might as well run the handler in this goroutine.
  169. // [*] Not strictly true: HTTP pipelining. We could let them all process
  170. // in parallel even if their responses need to be serialized.
  171. // But we're not going to implement HTTP pipelining because it
  172. // was never deployed in the wild and the answer is HTTP/2.
  173. //调用自己实现的Handler,用于处理Request,并且返回Response
  174. serverHandler{c.server}.ServeHTTP(w, w.req)
  175. w.cancelCtx() //调用上下文的取消函数
  176. if c.hijacked() { //如果请求被挂住,则返回
  177. return
  178. }
  179. w.finishRequest() //处理一些状态
  180. if !w.shouldReuseConnection() {
  181. if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
  182. c.closeWriteAndWait()
  183. }
  184. return
  185. }
  186. c.setState(c.rwc, StateIdle) //改变请求状态
  187. c.curReq.Store((*response)(nil))
  188. if !w.conn.server.doKeepAlives() { //过了keep alive时间
  189. // We're in shutdown mode. We might've replied
  190. // to the user without "Connection: close" and
  191. // they might think they can send another
  192. // request, but such is life with HTTP/1.1.
  193. return
  194. }
  195. if d := c.server.idleTimeout(); d != 0 {
  196. c.rwc.SetReadDeadline(time.Now().Add(d))
  197. if _, err := c.bufr.Peek(4); err != nil {
  198. return
  199. }
  200. }
  201. c.rwc.SetReadDeadline(time.Time{}) //重置ReadDeadline
  202. }
  203. }
  204. serve用于循环读取用户的请求数据Request,并封装成Response,然后调用调用自己传入的Handler,如果未指定Handler则使用默认的DefaultServeMux
  205. serverHandler{c.server}.ServeHTTP(w, w.req)
  206. func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
  207. handler := sh.srv.Handler
  208. if handler == nil { //如果没有实现handler则用DefaultServeMux
  209. handler = DefaultServeMux
  210. }
  211. if req.RequestURI == "*" && req.Method == "OPTIONS" {
  212. handler = globalOptionsHandler{}
  213. }
  214. handler.ServeHTTP(rw, req)
  215. }
  216. 调用handlerServeHTTP来处理客户端的请求,并响应。
  217. 我们看一下默认的Handler DefaultServeMuxServeHTTP
  218. func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
  219. /*
  220. 处理RequestURI为*的情况
  221. */
  222. if r.RequestURI == "*" {
  223. if r.ProtoAtLeast(1, 1) {
  224. w.Header().Set("Connection", "close")
  225. }
  226. w.WriteHeader(StatusBadRequest)
  227. return
  228. }
  229. //根据请求找到匹配的handler
  230. h, _ := mux.Handler(r)
  231. h.ServeHTTP(w, r)
  232. }
  233. 看到Handler函数根据用户请求去匹配对应的Handler,如以上demo,根据pattern /hello,可以找到注册到路由的handlerHelloServer,由HelloServer处理请求,并写入response

发表评论

表情:
评论列表 (有 0 条评论,374人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Golanghttp server

    基于HTTP构建的网络应用包括两个端,即客户端(Client)和服务端(Server)。两个端的交互行为包括从客户端发出request、服务端接受request进行处理并返回r