func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if !r.skipClean {
		path := req.URL.Path
		if r.useEncodedPath {
			path = req.URL.EscapedPath()
		}
		if p := cleanPath(path); p != path {
			url := *req.URL
			url.Path = p
			p = url.String()
			w.Header().Set("Location", p)
			w.WriteHeader(http.StatusMovedPermanently)
			return
		}
	}
	var match RouteMatch
	var handler http.Handler
	if r.Match(req, &match) {
		handler = match.Handler
		req = setVars(req, match.Vars)
		req = setCurrentRoute(req, match.Route)
	}
	if handler == nil && match.MatchErr == ErrMethodMismatch {
		handler = methodNotAllowedHandler()
	}
	if handler == nil {
		handler = http.NotFoundHandler()
	}
	handler.ServeHTTP(w, req)
}
ServeHTTP dispatches the handler registered in the matched route.

When there is a match, the route variables can be retrieved calling
mux.Vars(request).
package mux
import (
	"errors"
	"fmt"
	"net/http"
	"path"
	"regexp"
)
var (
	ErrMethodMismatch = errors.New("method is not allowed")
	ErrNotFound = errors.New("no matching route was found")
)
func NewRouter() *Router {
	return &Router{namedRoutes: make(map[string]*Route)}
}
type Router struct {
	NotFoundHandler http.Handler
	MethodNotAllowedHandler http.Handler
	routes []*Route
	namedRoutes map[string]*Route
	KeepContext bool
	middlewares []middleware
	routeConf
}
type routeConf struct {
	useEncodedPath bool
	strictSlash bool
	skipClean bool
	regexp routeRegexpGroup
	matchers []matcher
	buildScheme string
	buildVarsFunc BuildVarsFunc
}
func copyRouteConf(r routeConf) routeConf {
	c := r
	if r.regexp.path != nil {
		c.regexp.path = copyRouteRegexp(r.regexp.path)
	}
	if r.regexp.host != nil {
		c.regexp.host = copyRouteRegexp(r.regexp.host)
	}
	c.regexp.queries = make([]*routeRegexp, 0, len(r.regexp.queries))
	for _, q := range r.regexp.queries {
		c.regexp.queries = append(c.regexp.queries, copyRouteRegexp(q))
	}
	c.matchers = make([]matcher, 0, len(r.matchers))
	for _, m := range r.matchers {
		c.matchers = append(c.matchers, m)
	}
	return c
}
func copyRouteRegexp(r *routeRegexp) *routeRegexp {
	c := *r
	return &c
}
func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
	for _, route := range r.routes {
		if route.Match(req, match) {
			if match.MatchErr == nil {
				for i := len(r.middlewares) - 1; i >= 0; i-- {
					match.Handler = r.middlewares[i].Middleware(match.Handler)
				}
			}
			return true
		}
	}
	if match.MatchErr == ErrMethodMismatch {
		if r.MethodNotAllowedHandler != nil {
			match.Handler = r.MethodNotAllowedHandler
			return true
		}
		return false
	}
	if r.NotFoundHandler != nil {
		match.Handler = r.NotFoundHandler
		match.MatchErr = ErrNotFound
		return true
	}
	match.MatchErr = ErrNotFound
	return false
}