Go 的 http 套件詳解
Last updated
type muxEntry struct {
explicit bool // 是否精確匹配
h Handler // 這個路由表示式對應哪個 handler
pattern string //匹配字串
}type Handler interface {
ServeHTTP(ResponseWriter, *Request) // 路由實現器
}type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
if r.RequestURI == "*" {
w.Header().Set("Connection", "close")
w.WriteHeader(StatusBadRequest)
return
}
h, _ := mux.Handler(r)
h.ServeHTTP(w, r)
}func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
if r.Method != "CONNECT" {
if p := cleanPath(r.URL.Path); p != r.URL.Path {
_, pattern = mux.handler(r.Host, p)
return RedirectHandler(p, StatusMovedPermanently), pattern
}
}
return mux.handler(r.Host, r.URL.Path)
}
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
}package main
import (
"fmt"
"net/http"
)
type MyMux struct {
}
func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {
sayhelloName(w, r)
return
}
http.NotFound(w, r)
return
}
func sayhelloName(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello myroute!")
}
func main() {
mux := &MyMux{}
http.ListenAndServe(":9090", mux)
}2 呼叫了 DefaultServeMux 的 Handle
3 往 DefaultServeMux 的 map[string]muxEntry 中增加對應的 handler 和路由規則8 呼叫 handler 的 ServeHttp
9 在這個例子中,下面就進入到 DefaultServeMux.ServeHttp
10 根據 request 選擇 handler,並且進入到這個 handler 的 ServeHTTP
mux.handler(r).ServeHTTP(w, r)
11 選擇 handler:
A 判斷是否有路由能滿足這個 request(迴圈遍歷 ServeMux 的 muxEntry)
B 如果有路由滿足,呼叫這個路由 handler 的 ServeHTTP
C 如果沒有路由滿足,呼叫 NotFoundHandler 的 ServeHTTP