2.Golang http source Reading (handler registration)

Source: Internet
Author: User

Put a piece of code first

package mainimport (    "net/http"    "fmt"    "log")func hello(w http.ResponseWriter, r *http.Request)  {    r.ParseForm()    fmt.Printf("%+v\n", *r.URL)    fmt.Fprintln(w, "Hello world")}func main() {    http.HandleFunc("/", hello)    err := http.ListenAndServe(":9090", nil)    if err != nil {        log.Fatal(err)    }}

Here, listen to the local 9090 port, using HTTP. Handlefunc a request with a URL of "/" to the method named Hello. This is a more common golang simple web implementation, but it would be very strange to look at, it is recommended to run the code first, and then we will look at the source of the handler definition first.

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

As shown in the code, handler is actually an interface that implements the Servehttp (Responsewriter, *request) function, which is equivalent to implementing a handler. Popular speaking handler is the function of processing input and output stream, registering handler to the router, the equivalent of binding a specific URL to this function, when the client requests access to the URL, the router will use this function to operate.
There may be children's shoes will be questioned, hello this function is not a handler, why you can register a URL as handler. This is because there is a function called Handlefunc, here is the principle of handlefunc. First list the source code:

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

Handlefunc Pass in a string (URL) and a func (Responsewriter, request ), hello this function is compliant with func (Responsewriter, request), Then use Defaultservemux for processing, what is Defaultservemux? The definition of Defaultservemux can be easily found in the source code of Server.go.

type ServeMux struct {    mu    sync.RWMutex    m     map[string]muxEntry    hosts bool // whether any patterns contain hostnames}....// DefaultServeMux is the default ServeMux used by Serve.var DefaultServeMux = &defaultServeMuxvar defaultServeMux ServeMux

From the source can know Defaultservemux equivalent to a public route, a public variable, URL and handle is registered to this route. It is important to note that the SERVEMUX member variable has a sync. Rwmutex, know Golang concurrency should know, this is a read-write lock (mutiple Read,single write lock, read single write lock, allows multiple read operations to execute in parallel, but the write operation is completely mutually exclusive, when the read operation is more frequent than sync. Mutex has better performance), this should also be considered as a Web server, read operations will be more frequent. Next look at the MUX. Handle (Pattern, Handlerfunc (handler)) to which step you should see a function Handlerfunc (handler):

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

See here you should understand why hello this function does not implement the handler method is also a handler, because handlerfunc the Hello Force implementation servehttp (W Responsewriter, R *request), So hello this function is also a handler.

This is the last step of the route.

type muxEntry struct {    h       Handler    pattern string}// Handle registers the handler for the given pattern.// If a handler already exists for pattern, Handle panics.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)    }    mux.m[pattern] = muxEntry{h: handler, pattern: pattern}    if pattern[0] != '/' {        mux.hosts = true    }}

The public variable Defaultservemux registers the handler, where a read-write lock is used and a private structure muxentry, where the routing registration is over.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.