This is a creation in Article, where the information may have evolved or changed.
Here we analyze the default Handler–defaultservemux
Before all the introductions, we'll give you two classes:
typestruct { mu sync.RWMutex m map[string]muxEntry bool// whether any patterns contain hostnames}typestruct { bool h Handler pattern string}
Servemux implements the Servehttp function of the handler excuse; we know that in the go language, all the functions of the interface are implemented, the interface is implemented
thetothe handler whose// pattern most closely matches the request URL.func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { if"*" { if r.ProtoAtLeast(11) { w.Header().Set("Connection""close") } w.WriteHeader(StatusBadRequest) return } h, _ := mux.Handler(r) h.ServeHTTP(w, r)}
。 Then we continue to Defaultservemux, we have not passed the handler object in the example of the previous article, but we have such a line of code:
http.HandleFunc("/hello", SayHello)
In fact, this line of code is the default handler object Defaultservemux, which sets the handler function for a specific URL. Let's take a look at the function and do exactly what:
funcstringfunc(ResponseWriter, *Request)) { DefaultServeMux.HandleFunc(pattern, handler)}
Simple rude, is directly called the Defaultservemux object Handlefunc function, in fact Defaultservemux is a Servemux object:
// NewServeMux allocates and returns a new ServeMux.funcreturnmake(map[string]muxEntry)} }// DefaultServeMux is the default ServeMux used by Serve.var DefaultServeMux = NewServeMux()
The Handlefunc function of the Defaultservemux object, which is also the member function of the SERVEMUX:
function for the given pattern.func (mux *ServeMux)string, handler func(ResponseWriter, *Request)) { mux.Handle(pattern, HandlerFunc(handler))}
The function is encapsulated in handle (pattern, Handlerfunc (handler)):
Handle registers theHandler forThe given pattern.//IfAHandlerAlreadyexists forPattern, Handle panics.func (Mux *servemux) Handle (pattern string,Handler Handler) {mux.mu.Lock() defer Mux.mu.Unlock ()ifPattern = =""{Panic ("Http:invalid pattern"+ pattern)}if Handler= = Nil {Panic ("Http:nil handler") }ifmux.m[pattern].explicit {Panic ("Http:multiple registrations for"+ pattern)} Mux.m[pattern] = muxentry{explicit:trueH:Handler, Pattern:pattern}ifpattern[0] !='/'{mux.hosts =true}//Helpful behavior://IfPattern is/tree/,InsertAn implicit permanent redirect for/tree. It can be overridden byAn explicit registration. N: = Len (pattern)ifn >0&& pattern[n-1] =='/'&&!mux.m[pattern[0: N-1]].explicit {//IfPattern contains a host name, strip it andUse remaining//path forredirect. Path: = Patternifpattern[0] !='/'{ //inchPattern atLeast the Last character isA'/', so//strings. Index can' t be-1. Path = pattern[strings. Index (Pattern, "/"):]} URL: = &url. Url{path:path} mux.m[pattern[0:n-1]] = Muxentry{h:redirecthandler (URL. String (), statusmovedpermanently), Pattern:pattern} }}
In fact, it is a map that constructs a pattern and function handler. It seems that the implementation of the native library routing is very simple, is a map, so the practical application of the limitations are relatively large. In practical applications, we often use other routes to implement, it is necessary or possible to implement them.