golang HTTP 实例

2021-10-05  本文已影响0人  郭青耀

最近温故了一下go web 编程
看到第一个实例的时候 ,上面写着一段当时没有搞明白的文字

“main 函数中的两个HTTP函数HandleFunc和ListenAndServe 怎么联系起来的?”

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello world,%s!", r.URL.Path)
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8090", nil)
}

书中解释了每一行的含义,却没有说明他们的关系。
这里补充一下当初的疑问:
http.HandleFunc("/", handler) ,这是个回调函数,浏览器访问的时候,才会调用,即便它写在前面,实际调用 handler函数的时候是在后面执行的。所以要先看后面的函数。
http.ListenAndServe(":8090", nil)
看一下它的原型

// ListenAndServe listens on the TCP network address addr and then calls
// Serve with handler to handle requests on incoming connections.
// Accepted connections are configured to enable TCP keep-alives.
//
// The handler is typically nil, in which case the DefaultServeMux is used.
//
// ListenAndServe always returns a non-nil error.
func ListenAndServe(addr string, handler Handler) error {
    server := &Server{Addr: addr, Handler: handler}
    return server.ListenAndServe()
}

这里面注释说handler默认是nil的情况下,handler 的值是DefaultServeMux.

在看一下:http.HandleFunc的原型:

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

http.HandleFunc操作的对象就是DefaultServeMux.

并没有结束,因为很多时候注释是不可靠的,我们要看到源码server的默认handler为什么是DefaultServeMux; 我们需要看看 handler的原型:

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

handler 是一个接口类型,实现了ServeHTTP函数即可的接口类型,server 的实现在这里,当handler为nil时候,handler被赋值为默认值。

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)
}

上一篇下一篇

猜你喜欢

热点阅读