簡析 Golang net/http 包
阿新 • • 發佈:2019-08-26
net/http 包涵蓋了與 HTTP 請求傳送和處理的相關程式碼。雖然包中定義了大量型別、函式,但最重要、最基礎的概念只有兩個:ServeMux 和 Handler。
ServeMux 是 HTTP 請求多路複用器(即路由器,HTTP request router),記錄著請求路由表。對於每一個到來的請求,它都會比較請求路徑和路由表中定義的 URL 路徑,並呼叫指定的 handler 來處理請求。
Handler 的任務是返回一個 response 訊息,並把 header 和 body 寫入訊息中。任何物件只要實現了 http.Handler 介面的介面方法 ServeHTTP 就可以成為 handler。ServeHTTP 的方法簽名是:ServeHTTP(ResponseWriter, *Request)。
我們先通過以下程式碼,快速瞭解它們的功能:
package main import ( "io" "log" "net/http" ) type myHandler struct{} func (h *myHandler) ServeHTTP(w http.ResponseWriter, _ *http.Request) { io.WriteString(w, "Hello world!\n") } func main() { mux := http.NewServeMux() h := new(myHandler) mux.Handle("/foo", h) log.Println("Listening...") http.ListenAndServe(":3000", mux) }
程式碼拆解如下:
- 首先,使用 http.NewServeMux 方法生成一個 HTTP 請求路由器。該方法內部邏輯其實是 return new(ServeMux);
- 然後我們建立了一個自定義 handler,功能是返回 Hello world! 文字;
- 接著,通過 mux.Handle 函式,將該 handler 註冊到新建立的 ServeMux 物件中。這樣 handler 就可以和 URL 路徑 /foo 關聯了;
- 最後,我們建立一個 server 並在 3000 埠監聽請求。這裡 ListenAndServe 的方法簽名是 ListenAndServe(addr string, handler Handler),我們之所以可以 ServeMux 作為第二個引數,是因為 ServeMux 實現了 ServeHTTP 介面方法。
掌握了這兩個概念,基本上其他概念 比如 Server,Client 型別、HandleFunc 函式作為 handler 等, 就都很好理解了。另外, 如果你對包中 HTTP 相關的概念不是很清楚的話,比如 TCP keep-alive、proxy、redirect、cookie、TLS,建議閱讀《 HTTP: The Definitive Guide 》補充知識。
參考文獻:A Recap of Request Handling in