go net/http関連メモ
http.Handler, http.(*ServeMux).ServeHTTP, http.Handle, http.HandleFuncあたりが毎回混乱するのでまとめておく
http.HandlerはServeHTTPメソッドをもつinterface
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
cf. https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/net/http/server.go;l=86
Handler interfaceを満たすものは3つ
- http.(*ServeMux).ServeHTTP
- http.(serverHandler).ServeHTTP(これは実質的にServeMuxを指すと思っていてよさそう?)
- http.(HandlerFunc).ServeHTTP
http.HandlerFuncはResponseWriter, *Requestを引数にとる関数型
type HandlerFunc func(ResponseWriter, *Request)
cf. https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/net/http/server.go;l=2132
http.Handleはparttenとhandlerを引数にとる関数.
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
cf. https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/net/http/server.go;l=2573
http.(*ServeMux).ServeHTTPは
- mux.Handler()を実行し,requestに対応するhandlerを特定する.
- 特定したhttp.(Handler).ServeHTTPに処理を委譲する
// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
if r.RequestURI == "*" {
if r.ProtoAtLeast(1, 1) {
w.Header().Set("Connection", "close")
}
w.WriteHeader(StatusBadRequest)
return
}
h, _ := mux.Handler(r)
h.ServeHTTP(w, r)
}
cf. https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/net/http/server.go;l=2503-2515
golangのhttpのrouterライブラリがやっているのはdefaultServeMuxを差し替えた上で,機能を追加しつつ,いかに高速にrequestに対応するhandlerを探し出すか?ということなのだと理解した.
各ライブラリが提供する機能群は以下のようなもの
- path parameter parsing
- regex routing
- method routing
- host/domain routing
- middleware
- some default middlewares(logging, cors, basic auth, etc...)