Go http原始碼解析(一)
阿新 • • 發佈:2019-01-02
Go web之旅
此篇開始將開啟Go web之旅,我將這趟旅途分為三個子旅程:
- 原始碼解析
- 框架解讀
- 中介軟體使用
所以在這趟旅途中我們將領略原始碼之雄偉,框架之奇豔,中介軟體之靈秀。在接下來的時間裡我會按照上面的目錄依次講解。
現在開始踏上Go web的旅程。
func firstHandler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello,world")
}
func main() {
http.HandleFunc("/hello", firstHandler)
http.ListenAndServe (":8080", nil)
}
在main函式中,http.HandleFunc設定所有對路徑為/hello請求的處理函式為firstHandler.
接下來呼叫http.ListenAndServe,在8080埠開始監聽將阻塞,直到退出。
我們將以原始碼解析作為整個旅程的開篇。
Go語言作為網際網路中的c語言,他讓web開發簡潔到不能再簡潔了。首先我們來介紹他讓web開發變得簡易所涉及的最重要的包(package)(當遇到包時一般直接用package表示)之一http.
package http在service.go中。
// HTTP server. See RFC 2616.
package http
//宣告一個Handler介面,若某函式實現了ServeHTTP函式就實現了該介面
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
那我們該如何實現該介面呢?
其實在service.go中他已經預設實現了該函式
type ServeMux struct {//定義路由規則
mu sync.RWMutex//鎖機制,因為併發處理需要一個鎖
m map[string]muxEntry//路由,採用map結構
hosts bool // whether any patterns contain hostnames
}
type muxEntry struct {//路由
explicit bool //是否精準匹配
h Handler//路由匹配後,所選擇的處理
pattern string //匹配字串
}
// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
//路由結構ServeMux實現ServeHTTP函式
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)
}
從godoc提示可以知道,當一個請求來時,先進行路由匹配,這一過程由ServeMux.m中的string來匹配完成。
匹配成功後選擇muxEntry.h所對應的handler進行處理,而這一步是呼叫ServeHTTP實現。