//只要实现了Handler的接口就可以当作自定义的路由来用,也就是带上ServerHttp的方法就可以了。 func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { // Clean path to canonical form and redirect. if p := cleanPath(req.URL.Path); p != req.URL.Path { // Added 3 lines (Philip Schlump) - It was droping the query string and #whatever from query. // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue: // http://code.google.com/p/go/issues/detail?id=5252 url := *req.URL url.Path = p p = url.String() //根据HTTP的协议重定向
//设置Http的头Location,就可以告知服务器重定向到p这个地址
w.Header().Set("Location", p) w.WriteHeader(http.StatusMovedPermanently) return } var match RouteMatch var handler http.Handler
//路由匹配对应的处理方式
//handler获得处理方式
//把req的一些值带上
//把req的路由也给带上
//调用handler的接口就可以啦 if r.Match(req, &match) { handler = match.Handler
setVars(req, match.Vars)
setCurrentRoute(req, match.Route) } if handler == nil { if r.NotFoundHandler == nil { r.NotFoundHandler = http.NotFoundHandler() } handler = r.NotFoundHandler } if !r.KeepContext { defer context.Clear(req) } handler.ServeHTTP(w, req) }
// Match matches the route against the request. func (r *Route) Match(req *http.Request, match *RouteMatch) bool { if r.buildOnly || r.err != nil {
//带了buildOnly就表示这个路由仅仅是用来制作url的,不是用来处理request的。 return false } // Match everything. //match 是匹配的路由的结果,作为参数传进来是可以对结果进行预设的 for _, m := range r.matchers { if matched := m.Match(req, match); !matched { return false } } // Yay, we have a match. Let's collect some info about it. if match.Route == nil { match.Route = r } if match.Handler == nil { match.Handler = r.handler } if match.Vars == nil { match.Vars = make(map[string]string) } // Set variables. if r.regexp != nil { r.regexp.setMatch(req, match, r) } return true }