美文网首页
Go之net/http/server.go中Handler、Se

Go之net/http/server.go中Handler、Se

作者: 日落_3d9f | 来源:发表于2019-12-30 10:43 被阅读0次

    1、Handler是什么?

    A Handler responds to an HTTP request. 这是源码中的注释,说的就是:一个Handler响应一个HTTP请求。

    type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
    }
    

    ServeHTTP should write reply headers and data to the ResponseWriter and then return. Returning signals that the request is finished; it is not valid to use the ResponseWriter or read from the Request.Body after or concurrently with the completion of the ServeHTTP call.

    Depending on the HTTP client software, HTTP protocol version, and
    any intermediaries between the client and the Go server, it may not
    be possible to read from the Request. Body after writing to the
    ResponseWriter. Cautious handlers should read the Request.Body
    first, and then reply.

    Except for reading the body, handlers should not modify the provided Request.

    If ServeHTTP panics, the server (the caller of ServeHTTP) assumes that the effect of the panic was isolated to the active request. It recovers the panic, logs a stack trace to the server error log, and either closes the network connection or sends an HTTP/2 RST_STREAM, depending on the HTTP protocol. To abort a handler so the client sees an interrupted response but the server doesn't log an error, panic with the value ErrAbortHandler.

    A ResponseWriter interface is used by an HTTP handler to construct an HTTP response.

    type ResponseWriter interface {
        Header() Header
        Write([]byte) (int, error)
        WriteHeader(statusCode int)
    }
    

    2. Handler的实现者及他们之间的关系

    实现一:HandlerFunc
    HandlerFunc是对是用户定义的处理函数的包装,实现了ServeHTTP方法,在方法内执行HandlerFunc对象

    type HandlerFunc func(ResponseWriter, *Request)
    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
        f(w, r)
    }
    

    实现二:ServeMux

    ServeMux是管理http请求pattern和handler的,实现了ServeHTTP方法,在其内根据请求匹配HandlerFunc,并执行其ServeHTTP方法

    type ServeMux struct {
        mu    sync.RWMutex
        m     map[string]muxEntry
        es    []muxEntry // slice of entries sorted from longest to shortest.
        hosts bool       // whether any patterns contain hostnames
    }
    func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
        h, _ := mux.Handler(r)
        h.ServeHTTP(w, r) // 调用的是HandlerFunc的ServeHTTP
    }
    

    // 实现三:serverHandler

    serverHandler是对Server的封装,实现了ServeHTTP方法,并在其内执行ServeMux的ServeHTTP方法

    type serverHandler struct {
        srv *Server
    }
    func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
        handler := sh.srv.Handler
        if handler == nil {
            handler = DefaultServeMux
        }
        ...
        handler.ServeHTTP(rw, req) // 调用的是ServerMux的ServeHTTP
    }
    

    3. ServeMux是干什么的

    ServeMux是一个HTTP请求多路复用器。它根据已注册模式(pattern)列表匹配每个传入请求的URL,并调用与URL最匹配的模式的处理程序(handler)。

    // ServeMux 是 server multiplexer 简写
    type ServeMux struct {
        mu    sync.RWMutex
        m     map[string]muxEntry
        es    []muxEntry // slice of entries sorted from longest to shortest.
        hosts bool       // whether any patterns contain hostnames
    }
    
    type muxEntry struct {
        h       Handler
        pattern string
    }
    
    // DefaultServeMux是被Serve使用的默认的ServeMux
    var DefaultServeMux = &defaultServeMux
    var defaultServeMux ServeMux
    
    // 服务HTTP
    func (mux *ServeMux) ServeHTTP(W ResponseWriter, r *Request) {
        ...
        h, _ := mux.Handler(r) // 根据请求获取用户定义的handler
        h.ServeHTTP(w, r) // 执行用户定义的handler
    }
    
    // ServeMux处理http请求
    func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
        ...
        return mux.handler(host, r.URL.Path)
    }
    
    // 根据host和path获取Handler
    func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
        mux.mu.RLock()
        defer mux.mu.RUnlock()
        // Host-specific pattern takes precedence over generic ones
        if mux.hosts {
            h, pattern = mux.match(host + path)
        }
        if h == nil {
            h, pattern = mux.match(path)
        }
        if h == nil {
            h, pattern = NotFoundHandler(), ""
        }
        return
    }
    
    
    // 根据path在hanlder map中寻找handler(最长匹配)
    func (mux *ServeMux) match(path string) (h Handler, pattern string) {
        // Check for exact match first.
        v, ok := mux.m[path]
        if ok {
            return v.h, v.pattern
        }
        // Check for longest valid match.  mux.es contains all patterns
        // that end in / sorted from longest to shortest.
        for _, e := range mux.es {
            if strings.HasPrefix(path, e.pattern) {
                return e.h, e.pattern
            }
        }
        return nil, ""
    }
    
    
    // 为pattern注册对应的Handler,如果handler已存在,则panic
    func (mux *ServeMux) Handle(pattern string, handler Handler) {
        mux.mu.Lock()
        defer mux.mu.Unlock()
    
        if pattern == "" {
            panic("http: invalid pattern")
        }
        if handler == nil {
            panic("http: nil handler")
        }
        if _, exist := mux.m[pattern]; exist {
            panic("http: multiple registrations for " + pattern)
        }
    
        if mux.m == nil {
            mux.m = make(map[string]muxEntry)
        }
        e := muxEntry{h: handler, pattern: pattern}
        mux.m[pattern] = e
        if pattern[len(pattern)-1] == '/' {
            mux.es = appendSorted(mux.es, e)
        }
    
        if pattern[0] != '/' {
            mux.hosts = true
        }
    }
    
    // 为pattern注册对应的handler function
    func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        if handler == nil {
            panic("http: nil handler")
        }
        mux.Handle(pattern, HandlerFunc(handler))
    }
    

    4. 处理函数的注册过程

    http.HandleFunc(pattern, handler)
    
    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        DefaultServeMux.HandleFunc(pattern, handler)
    
        func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
            if handler == nil {
                panic("http: nil handler")
            }
            mux.Handle(pattern, HandlerFunc(handler))
        }
    }
    

    5. Handle & HandleFunc区别

    HandleFunc内部实际调用的是Handle,HandleFunc将func转化为handler

    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        DefaultServeMux.HandleFunc(pattern, handler)
    }
    func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
    

    6. 从Server到conn再到ServeMux的调用逻辑

    服务启动过程

    http.ListenAndServe(addr, handler) // 这里的handler如果为空,在serverHander执行ServeHTTP内使用DefaultServeMux作为默认的handler
    
    func ListenAndServe(addr string, handler Handler) error {
        server := &Server{Addr: addr, Handler: handler}
        server.ListenAndServe() // 这里的server是在函数内部新创建的
    
        func (srv *Server) ListenAndServe() error {
            ln, err := net.Listen("tcp", addr) // 创建一个监听者
            srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) // 启动服务
    
            func (srv *Server) Serve(l net.Listener) error {
                for { // 死循环处理
                    rw, e := l.Accept() // 接收连接
                    ...
                    c := srv.newConn(rw)
                    c.setState(c.rwc, StateNew) // before Serve can return
                    go c.serve(ctx) // 处理连接
    
                    // Serve a new connection.
                    func (c *conn) serve(ctx context.Context) {
                        for {
                            w, err := c.readRequest(ctx)
                            ...
                            serverHandler{c.server}.ServeHTTP(w, w.req) // Server层服务处理
    
                            func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
                                handler := sh.srv.Handler
                                if handler == nil {
                                    handler = DefaultServeMux
                                }
                                handler.ServeHTTP(rw, req)
    
                                func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { // ServeMux层服务处理
                                    h, _ := mux.Handler(r)
                                    h.ServeHTTP(w, r)
    
                                    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { // HandlerFunc层服务处理
                                        f(w, r) // 至此,会执行用户自定义的请求处理函数
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Go之net/http/server.go中Handler、Se

          本文链接:https://www.haomeiwen.com/subject/xvepoctx.html