日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go Web:自带的ServeMux multiplexer

發布時間:2024/3/24 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go Web:自带的ServeMux multiplexer 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ServeMux簡介

ServeMux扮演的角色是Multiplexer,它用來將將請求根據url路由給已注冊的handler。如下圖:

上圖中為3個路徑注冊了handler,一個是"/",另外兩個是"/hello"和"/world"。這表示訪問http://hostname/hello時,multiplexer會調用上圖中對應的第二個handler,當訪問http://hostname/world時,multiplexer會調用上圖中對應的第三個handler,當不是這兩個路徑時,將調用第一個綁定在"/"上的handler。

注意,go的mux路由請求時,handler綁定的路徑是否帶尾隨"/"是不一樣的。帶上尾隨"/",表示此路徑以及此路徑下的子路徑,都會調用注冊在此路徑上的handler

例如,當請求uri為"/hello/abc"的時候,不會調用"/hello"對應的handler,而是調用"/"對應的handler。只有注冊handler的路徑為"/hello/"時,uri為"/hello/abc"才會調用此handler。

實際上,當注冊handler的路徑帶上尾隨斜"/"時,在發起此路徑的請求時,會通過301重定向的方式自動補齊這個尾隨斜線,讓瀏覽器發起第二次請求。例如,下面是注冊handler的路徑:

http.Handle("/hello/", &myHandler)

發起http://hostname/hello的請求時,會自動補齊為http://hostname/hello/,然后瀏覽器自動發起第二次請求。

ServeMux的匹配規則

ServeMux對每次流入的http請求的URL進行模式(pattern)匹配,然后調用注冊在此pattern上的handler來處理這個請求。

Pattern部分可以定義為匹配host的模式。如果pattern以"/"開頭,表示匹配URL的路徑部分,如果不以"/"開頭,表示從host開始匹配。

匹配時選擇匹配匹配度最高(長匹配優先于短匹配)。例如為"/images/"注冊了handler1,"/images/thumbnails/"注冊了handler2,如果請求的URL路徑部分為"/images/thumbnails/",將會調用handler2處理這個請求,如果請求的URL路徑部分為"/images/foo/",將調用handler1處理。

注意,注冊在"/"上的pattern會在其它模式匹配不上時被選中,因為所有請求都可以匹配這個pattern,只不過能匹配到的長度最短。

如果pattern帶上了尾隨斜線"/",ServeMux將會對請求不帶尾隨斜線的URL進行301重定向。例如,在"/images/"模式上注冊了一個handler,當請求的URL路徑為"/images"時,將自動重定向為"/images/"。除非再單獨為"/images"模式注冊一個handler。

如果為"/images"注冊了handler,當請求URL路徑為"/images/"時,將無法匹配該模式。

ServeMux詳細解釋

看看net/http/server.go文件中ServeMux的結構:

type ServeMux struct {mu sync.RWMutexm map[string]muxEntryhosts bool // whether any patterns contain hostnames }type muxEntry struct {h Handlerpattern string }

結構看上去很簡單。一個字段mu是RWMutex,m是注冊handler和pattern的,hosts用于判斷pattern是否包含了host的匹配。看看Handle()函數的定義會更清晰:

func (mux *ServeMux) Handle(pattern string, handler Handler) {mux.mu.Lock()defer mux.mu.Unlock()if pattern == "" {panic("http: invalid pattern")}if handler == nil {panic("http: nil handler")}if _, exist := mux.m[pattern]; exist {panic("http: multiple registrations for " + pattern)}if mux.m == nil {mux.m = make(map[string]muxEntry)}mux.m[pattern] = muxEntry{h: handler, pattern: pattern}if pattern[0] != '/' {mux.hosts = true} }// HandleFunc registers the handler function for the given pattern. func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {mux.Handle(pattern, HandlerFunc(handler)) }

pattern為空或者handler為空時,都會panic。此外,想要定義重復的pattern,也會panic。如果pattern的第一個字符不是"/",則表示這個pattern是從主機名開始匹配的。

唯一需要注意的是,每個Handle()都會對ServeMux實例加上寫鎖。

以常用的DefaultServeMux為例,它是ServeMux的一個實例。當使用DefualtServeMux時,每調用一次Handle()或HandleFunc(),都意味著向這個DefaultServeMux的結構中的m字段添加pattern和對應的handler。由于加了寫鎖,如果使用多個goroutine同時啟動多個web服務,在同一時刻將只能有一個goroutine啟動的web服務能設置DefaultServeMux。當然,一般情況下不會使用goroutine的方式同時啟動多個web服務。

第三方ServeMux

自帶的默認的DefaultServeMux其實功能限制很大。比如請求的URL路徑為"/images/123.png",想要匹配這個確實容易,但是想要取出其中的"123.png"字符串,DefaultServeMux就沒法實現。

有一個非常強大的Gorilla工具包(www.gorillatoolkit.org),它有好幾個功能,其中一個功能是提供multiplexer。

總結

以上是生活随笔為你收集整理的Go Web:自带的ServeMux multiplexer的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。