go語言原生http庫分析 (2)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

這裡我們分析預設的Handler–DefaultServeMux
在所有介紹之前,我們先給出兩個類:

type ServeMux struct {    mu    sync.RWMutex    m     map[string]muxEntry    hosts bool // whether any patterns contain hostnames}type muxEntry struct {    explicit bool    h        Handler    pattern  string}

ServeMux實現了Handler借口的ServeHTTP函數;我們知道GO語言中,實現了介面的所有函數,則實現該介面

// ServeHTTP dispatches the request to the handler whose// pattern most closely matches the request URL.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)}

。接著我們繼續DefaultServeMux,我們在上篇的例子中雖然沒有傳入Handler對象,但是我們有這樣一行代碼:

 http.HandleFunc("/hello", SayHello)  

其實這行代碼操作的就是預設的Handler對象DefaultServeMux,為特定的URL設定處理函數。我們看下該函數,具體做了哪些操作:

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {    DefaultServeMux.HandleFunc(pattern, handler)}

簡單粗暴,直接就是調用DefaultServeMux對象的HandleFunc函數,其實DefaultServeMux是一個ServeMux對象:

// NewServeMux allocates and returns a new ServeMux.func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} }// DefaultServeMux is the default ServeMux used by Serve.var DefaultServeMux = NewServeMux()

DefaultServeMux對象的HandleFunc函數,也即ServeMux的成員函數:

// HandleFunc registers the handler function for the given pattern.func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {    mux.Handle(pattern, HandlerFunc(handler))}

該函數是Handle(pattern, HandlerFunc(handler))的封裝:

// Handle registers the handler for the given pattern.// If a handler already exists for pattern, Handle panics.func (mux *ServeMux) Handle(pattern string, handler Handler) {    mux.mu.Lock()    defer mux.mu.Unlock()    if pattern == "" {        panic("http: invalid pattern " + pattern)    }    if handler == nil {        panic("http: nil handler")    }    if mux.m[pattern].explicit {        panic("http: multiple registrations for " + pattern)    }    mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern}    if pattern[0] != '/' {        mux.hosts = true    }    // Helpful behavior:    // If pattern is /tree/, insert an implicit permanent redirect for /tree.    // It can be overridden by an explicit registration.    n := len(pattern)    if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {        // If pattern contains a host name, strip it and use remaining        // path for redirect.        path := pattern        if pattern[0] != '/' {            // In pattern, at least the last character is a '/', so            // strings.Index can't be -1.            path = pattern[strings.Index(pattern, "/"):]        }        url := &url.URL{Path: path}        mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(url.String(), StatusMovedPermanently), pattern: pattern}    }}

其實簡要之,就是構建一個pattern和函數Handler的map。看來原生庫中實現了路由非常簡單,就是一張map,所以實際應用中局限性比較大。實際應用中,我們往往利用其它路由實現,有必要也可能自己實現。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.