Go的http源码阅读笔记
2017-11-07 00:00
726 查看
Handler是Go实现http请求处理逻辑的入口,Handler是一个接口,该接口要求实现ServeHTTP方法。具体定义如下。
如果我们自定义了Handler的接口实现,便可以调用ListenAndServe函数进行http请求。
http.ListenAndServe封装了Server的ListenAndServe方法。
Server定义了运行http server的一些参数。
Server.ListenAndServe函数,监听addr中的tcp链接,并调用Serve函数。两个函数定义如下:
在Accept处阻塞,直到有客户端连接,当请求到来时,Accept会从Listener l中接收一个到来的连接并创建一个新的goroutine处理请求。
其中,c := srv.newConn(rw) 是创建了一个http.conn。
http.conn结构体如下:
conn的serve中最重要的是serverHandler{c.server}.ServeHTTP(w, w.req)
serverHandler的ServeHTTP是真正调用我们自定义的Handler的ServeHTTP函数的地方。
type Handler interface { ServeHTTP(ResponseWriter, *Request) }
如果我们自定义了Handler的接口实现,便可以调用ListenAndServe函数进行http请求。
func ListenAndServe(addr string, handler Handler) error { server := &Server{Addr: addr, Handler: handler} return server.ListenAndServe() }
http.ListenAndServe封装了Server的ListenAndServe方法。
Server定义了运行http server的一些参数。
type Server struct { Addr string // TCP address to listen on, ":http" if empty Handler Handler // handler to invoke, http.DefaultServeMux if nil ReadTimeout time.Duration // maximum duration before timing out read of the request WriteTimeout time.Duration // maximum duration before timing out write of the response MaxHeaderBytes int // maximum size of request headers, DefaultMaxHeaderBytes if 0 TLSConfig *tls.Config // optional TLS config, used by ListenAndServeTLS // TLSNextProto optionally specifies a function to take over // ownership of the provided TLS connection when an NPN // protocol upgrade has occurred. The map key is the protocol // name negotiated. The Handler argument should be used to // handle HTTP requests and will initialize the Request's TLS // and RemoteAddr if not already set. The connection is // automatically closed when the function returns. // If TLSNextProto is nil, HTTP/2 support is enabled automatically. TLSNextProto map[string]func(*Server, *tls.Conn, Handler) // ConnState specifies an optional callback function that is // called when a client connection changes state. See the // ConnState type and associated constants for details. ConnState func(net.Conn, ConnState) // ErrorLog specifies an optional logger for errors accepting // connections and unexpected behavior from handlers. // If nil, logging goes to os.Stderr via the log package's // standard logger. ErrorLog *log.Logger disableKeepAlives int32 // accessed atomically. nextProtoOnce sync.Once // guards initialization of TLSNextProto in Serve nextProtoErr error }
Server.ListenAndServe函数,监听addr中的tcp链接,并调用Serve函数。两个函数定义如下:
func (srv *Server) ListenAndServe() error { addr := srv.Addr if addr == "" { addr = ":http" } ln, err := net.Listen("tcp", addr) if err != nil { return err } return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) } func (srv *Server) Serve(l net.Listener) error { defer l.Close() if fn := testHookServerServe; fn != nil { fn(srv, l) } var tempDelay time.Duration // how long to sleep on accept failure if err := srv.setupHTTP2(); err != nil { return err } for { rw, e := l.Accept() if e != nil { if ne, ok := e.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay) time.Sleep(tempDelay) continue } return e } tempDelay = 0 c := srv.newConn(rw) c.setState(c.rwc, StateNew) // before Serve can return go c.serve() } }
在Accept处阻塞,直到有客户端连接,当请求到来时,Accept会从Listener l中接收一个到来的连接并创建一个新的goroutine处理请求。
其中,c := srv.newConn(rw) 是创建了一个http.conn。
// Create new connection from rwc. func (srv *Server) newConn(rwc net.Conn) *conn { c := &conn{ server: srv, rwc: rwc, } if debugServerConnections { c.rwc = newLoggingConn("server", c.rwc) } return c }
http.conn结构体如下:
type conn struct { // server is the server on which the connection arrived. // Immutable; never nil. server *Server // rwc is the underlying network connection. // This is never wrapped by other types and is the value given out // to CloseNotifier callers. It is usually of type *net.TCPConn or // *tls.Conn. rwc net.Conn // remoteAddr is rwc.RemoteAddr().String(). It is not populated synchronously // inside the Listener's Accept goroutine, as some implementations block. // It is populated immediately inside the (*conn).serve goroutine. // This is the value of a Handler's (*Request).RemoteAddr. remoteAddr string // tlsState is the TLS connection state when using TLS. // nil means not TLS. tlsState *tls.ConnectionState // werr is set to the first write error to rwc. // It is set via checkConnErrorWriter{w}, where bufw writes. werr error // r is bufr's read source. It's a wrapper around rwc that provides // io.LimitedReader-style limiting (while reading request headers) // and functionality to support CloseNotifier. See *connReader docs. r *connReader // bufr reads from r. // Users of bufr must hold mu. bufr *bufio.Reader // bufw writes to checkConnErrorWriter{c}, which populates werr on error. bufw *bufio.Writer // lastMethod is the method of the most recent request // on this connection, if any. lastMethod string // mu guards hijackedv, use of bufr, (*response).closeNotifyCh. mu sync.Mutex // hijackedv is whether this connection has been hijacked // by a Handler with the Hijacker interface. // It is guarded by mu. hijackedv bool }
conn的serve中最重要的是serverHandler{c.server}.ServeHTTP(w, w.req)
// Serve a new connection. func (c *conn) serve() { c.remoteAddr = c.rwc.RemoteAddr().String() defer func() { ... // defer处理 }() ... // tls connection c.r = &connReader{r: c.rwc} c.bufr = newBufioReader(c.r) c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10) for { w, err := c.readRequest() //读取请求 ... if err != nil { .... return } ... // HTTP cannot have multiple simultaneous active requests.[*] // Until the server replies to this request, it can't read another, // so we might as well run the handler in this goroutine. // [*] Not strictly true: HTTP pipelining. We could let them all process // in parallel even if their responses need to be serialized. serverHandler{c.server}.ServeHTTP(w, w.req) ... // finish operation } }
// serverHandler delegates to either the server's Handler or // DefaultServeMux and also handles "OPTIONS *" requests. type serverHandler struct { srv *Server } func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) { handler := sh.srv.Handler if handler == nil { handler = DefaultServeMux } if req.RequestURI == "*" && req.Method == "OPTIONS" { handler = globalOptionsHandler{} } handler.ServeHTTP(rw, req) }
serverHandler的ServeHTTP是真正调用我们自定义的Handler的ServeHTTP函数的地方。
相关文章推荐
- Go语言Http Server源码阅读
- Go 1.9 sync Map 源码阅读笔记
- nsq源码阅读 nsqlookupd源码五 http.go http_server.go
- Nginx 源码阅读笔记9 http 模块初始化
- Go net/http 主要功能及部分源码阅读
- go源码阅读笔记(math.1)
- go源码阅读笔记(math.3)
- 比特币源码阅读笔记【矿工共识篇】【草稿】
- Spark源码阅读笔记之Broadcast(二)
- linux-Tcp IP协议栈源码阅读笔记(转)
- Yii源码阅读笔记 - 自定义类自动加载
- jvm源码阅读笔记[1]:如何触发一次CMS回收
- JAVA 集合类(java.util)源码阅读笔记------ArrayList
- YunTable源码阅读笔记(1)
- werkzeug源码阅读笔记(二) 下
- android源码阅读笔记1-配置源码路径/阅读源码方法讨论
- java源码阅读笔记(1)- Object
- linux源码阅读笔记 数组定义
- CI框架源码阅读笔记1 - 环境准备、基本术语和框架流程