🌶️
golang net/httpパッケージのソースコードを読んでみます
サンプルコード
package main
import (
"fmt
"net/http"
)
type Handler struct {
}
func NewHandler() *Handler {
return &Handler{}
}
func (h *Handler) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
fmt.Println(req.Header)
writer.WriteHeader(200)
}
func main() {
server := &http.Server{
Handler: NewHandler(),
Addr: "localhost:8080",
}
server.ListenAndServe()
}
起動流れ
- main関数の以下の行を実行します
server.ListenAndServe()
- net/httpパッケージのListenAndServeを実行します
中にはtcp通信のListenerリソースを用意します
- tcp通信のListenerリソースが検知したconnectionを処理するためnet/httpパッケージのserveを呼びます
- main go routineでfor分を立ち上げます。tcp/ip通信のconnectionをずっと処理しておくためです。
- connectionが来たら、受け取ります
- 受け取ったconnectionを別なgoroutineをたちあげて、単独に処理します。
ここまではmain goroutineで行うものです
各connectionの処理流れ
ここからはmain goroutineではなく、別なgoroutineになります
- connのServeを呼びます
コメントのように各connectionに対する処理です
- 異例処理します
ここがあるから、各connectionに対して、ハンドリングするときに、nilエラーになるときに、panicされても、main go routineが止まりなく、走り続けられます。
- serverHandlerを作成し、serverHandlerのserveHttpを呼びます
- serverHandlerのserveHttpを呼びます
4-1. handlerを用意していないばあい、defaultServeMuxをhanlderとして使います。
サンプルコードにはNewHandler()を呼び出して、カスタマイズのhandlerを作っていますので、ここには入りません。
- handlerのserveHttpを呼びます
ここまではnet/httpパッケージがやっていることです。
- カスタマイズのhandlerのserveHttpを呼びます。
func (h *Handler) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
fmt.Println(req.Header)
writer.WriteHeader(200)
}
Discussion