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 }
mux.m[pattern] = e if pattern[len(pattern)-1] == '/' { mux.es = appendSorted(mux.es, e) }
appendSorted详细逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funcappendSorted(es []muxEntry, e muxEntry) []muxEntry { n := len(es) i := sort.Search(n, func(i int)bool { returnlen(es[i].pattern) < len(e.pattern) }) if i == n { returnappend(es, e) } // we now know that i points at where we want to insert es = append(es, muxEntry{}) // try to grow the slice in place, any entry works. copy(es[i+1:], es[i:]) // Move shorter entries down es[i] = e return es }
在es中,api前缀的加入是根据parttern的len递减顺序来进行存储的
1 2 3 4 5 6 7 8 9 10 11 12
http.HandleFunc("/api/hello/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World")) }) http.HandleFunc("/api/hello1/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World")) }) http.HandleFunc("/api/hello12/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World")) }) http.HandleFunc("/api/hello3/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World")) })
if engine.isUnsafeTrustedProxies() { debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") }
address := resolveAddress(addr) debugPrint("Listening and serving HTTP on %s\n", address) err = http.ListenAndServe(address, engine.Handler()) return }