@ -48,6 +48,8 @@ type Router struct {
namedRoutes map [ string ] * Route
namedRoutes map [ string ] * Route
// See Router.StrictSlash(). This defines the flag for new routes.
// See Router.StrictSlash(). This defines the flag for new routes.
strictSlash bool
strictSlash bool
// See Router.SkipClean(). This defines the flag for new routes.
skipClean bool
// If true, do not clear the request context after handling the request
// If true, do not clear the request context after handling the request
KeepContext bool
KeepContext bool
}
}
@ -73,19 +75,21 @@ func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
// When there is a match, the route variables can be retrieved calling
// When there is a match, the route variables can be retrieved calling
// mux.Vars(request).
// mux.Vars(request).
func ( r * Router ) ServeHTTP ( w http . ResponseWriter , req * http . Request ) {
func ( r * Router ) ServeHTTP ( w http . ResponseWriter , req * http . Request ) {
// Clean path to canonical form and redirect.
if ! r . skipClean {
if p := cleanPath ( req . URL . Path ) ; p != req . URL . Path {
// Clean path to canonical form and redirect.
if p := cleanPath ( req . URL . Path ) ; p != req . URL . Path {
// Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query.
// This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue:
// Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query.
// http://code.google.com/p/go/issues/detail?id=5252
// This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue:
url := * req . URL
// http://code.google.com/p/go/issues/detail?id=5252
url . Path = p
url := * req . URL
p = url . String ( )
url . Path = p
p = url . String ( )
w . Header ( ) . Set ( "Location" , p )
w . WriteHeader ( http . StatusMovedPermanently )
w . Header ( ) . Set ( "Location" , p )
return
w . WriteHeader ( http . StatusMovedPermanently )
return
}
}
}
var match RouteMatch
var match RouteMatch
var handler http . Handler
var handler http . Handler
@ -133,6 +137,19 @@ func (r *Router) StrictSlash(value bool) *Router {
return r
return r
}
}
// SkipClean defines the path cleaning behaviour for new routes. The initial
// value is false. Users should be careful about which routes are not cleaned
//
// When true, if the route path is "/path//to", it will remain with the double
// slash. This is helpful if you have a route like: /fetch/http://xkcd.com/534/
//
// When false, the path will be cleaned, so /fetch/http://xkcd.com/534/ will
// become /fetch/http/xkcd.com/534
func ( r * Router ) SkipClean ( value bool ) * Router {
r . skipClean = value
return r
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// parentRoute
// parentRoute
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@ -170,7 +187,7 @@ func (r *Router) buildVars(m map[string]string) map[string]string {
// NewRoute registers an empty route.
// NewRoute registers an empty route.
func ( r * Router ) NewRoute ( ) * Route {
func ( r * Router ) NewRoute ( ) * Route {
route := & Route { parent : r , strictSlash : r . strictSlash }
route := & Route { parent : r , strictSlash : r . strictSlash , skipClean : r . skipClean }
r . routes = append ( r . routes , route )
r . routes = append ( r . routes , route )
return route
return route
}
}
@ -357,6 +374,7 @@ func cleanPath(p string) string {
if p [ len ( p ) - 1 ] == '/' && np != "/" {
if p [ len ( p ) - 1 ] == '/' && np != "/" {
np += "/"
np += "/"
}
}
return np
return np
}
}