1. 程式人生 > >簡析 Golang net/http 包

簡析 Golang net/http 包

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)
}

程式碼拆解如下:

  1. 首先,使用 http.NewServeMux 方法生成一個 HTTP 請求路由器。該方法內部邏輯其實是 return new(ServeMux);
  2. 然後我們建立了一個自定義 handler,功能是返回 Hello world! 文字;
  3. 接著,通過 mux.Handle 函式,將該 handler 註冊到新建立的 ServeMux 物件中。這樣 handler 就可以和 URL 路徑 /foo 關聯了;
  4. 最後,我們建立一個 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