go语言原生http库分析 (2)

来源:互联网 发布:头皮毛囊炎 知乎 编辑:程序博客网 时间:2024/06/07 21:58

这里我们分析默认的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,所以实际应用中局限性比较大。实际应用中,我们往往利用其它路由实现,有必要也可能自己实现。

0 0
原创粉丝点击