diff --git a/router.go b/router.go index ffe6dc8..48352df 100644 --- a/router.go +++ b/router.go @@ -86,7 +86,7 @@ func (r *Router) methodIndexOf(method string) int { // Mutable allows updating the route handler // -// It's disabled by default +// # It's disabled by default // // WARNING: Use with care. It could generate unexpected behaviours func (r *Router) Mutable(v bool) { @@ -165,7 +165,8 @@ func (r *Router) ANY(path string, handler fasthttp.RequestHandler) { // "/etc/passwd" would be served. // Internally a fasthttp.FSHandler is used, therefore fasthttp.NotFound is used instead // Use: -// router.ServeFiles("/src/{filepath:*}", "./") +// +// router.ServeFiles("/src/{filepath:*}", "./") func (r *Router) ServeFiles(path string, rootPath string) { r.ServeFilesCustom(path, &fasthttp.FS{ Root: rootPath, @@ -183,7 +184,8 @@ func (r *Router) ServeFiles(path string, rootPath string) { // Internally a fasthttp.FSHandler is used, therefore http.NotFound is used instead // of the Router's NotFound handler. // Use: -// router.ServeFilesCustom("/src/{filepath:*}", *customFS) +// +// router.ServeFilesCustom("/src/{filepath:*}", *customFS) func (r *Router) ServeFilesCustom(path string, fs *fasthttp.FS) { suffix := "/{filepath:*}" @@ -353,17 +355,15 @@ func (r *Router) tryRedirect(ctx *fasthttp.RequestCtx, tree *radix.Tree, tsr boo uri.SetString(path[:len(path)-1]) } else { uri.SetString(path) - uri.WriteString("/") + uri.WriteByte('/') } - queryBuf := ctx.URI().QueryString() - if len(queryBuf) > 0 { + if queryBuf := ctx.URI().QueryString(); len(queryBuf) > 0 { uri.WriteByte(questionMark) uri.Write(queryBuf) } ctx.Redirect(uri.String(), code) - bytebufferpool.Put(uri) return true @@ -371,28 +371,28 @@ func (r *Router) tryRedirect(ctx *fasthttp.RequestCtx, tree *radix.Tree, tsr boo // Try to fix the request path if r.RedirectFixedPath { - path := strconv.B2S(ctx.Request.URI().Path()) + path2 := strconv.B2S(ctx.Request.URI().Path()) uri := bytebufferpool.Get() found := tree.FindCaseInsensitivePath( - cleanPath(path), + cleanPath(path2), r.RedirectTrailingSlash, uri, ) if found { - queryBuf := ctx.URI().QueryString() - if len(queryBuf) > 0 { + if queryBuf := ctx.URI().QueryString(); len(queryBuf) > 0 { uri.WriteByte(questionMark) uri.Write(queryBuf) } - ctx.RedirectBytes(uri.Bytes(), code) - + ctx.Redirect(uri.String(), code) bytebufferpool.Put(uri) return true } + + bytebufferpool.Put(uri) } return false diff --git a/router_test.go b/router_test.go index 99c6f79..1836bb1 100644 --- a/router_test.go +++ b/router_test.go @@ -578,12 +578,18 @@ func testRouterNotFoundByMethod(t *testing.T, method string) { router.Handle(method, "/USERS/{name}/enTRies/", handlerFunc) router.Handle(method, "/static/{filepath:*}", handlerFunc) + reqMethod := method + if method == MethodWild { + reqMethod = randomHTTPMethod() + } + // Moved Permanently, request with GET method expectedCode := fasthttp.StatusMovedPermanently - if method == fasthttp.MethodConnect { + switch { + case reqMethod == fasthttp.MethodConnect: // CONNECT method does not allow redirects, so Not Found (404) expectedCode = fasthttp.StatusNotFound - } else if method != fasthttp.MethodGet { + case reqMethod != fasthttp.MethodGet: // Permanent Redirect, request with same method expectedCode = fasthttp.StatusPermanentRedirect } @@ -616,30 +622,29 @@ func testRouterNotFoundByMethod(t *testing.T, method string) { }...) } - reqMethod := method - if method == MethodWild { - reqMethod = randomHTTPMethod() - } - for _, tr := range testRoutes { - if runtime.GOOS == "windows" && strings.HasPrefix(tr.route, "/../") { - // See: https://github.com/valyala/fasthttp/issues/1226 - t.Logf("skipping route '%s %s' on %s, unsupported yet", reqMethod, tr.route, runtime.GOOS) - - continue - } - ctx := new(fasthttp.RequestCtx) - ctx.Request.Header.SetMethod(reqMethod) ctx.Request.SetRequestURI(tr.route) ctx.Request.SetHost(host) + router.Handler(ctx) statusCode := ctx.Response.StatusCode() location := string(ctx.Response.Header.Peek("Location")) + if !(statusCode == tr.code && (statusCode == fasthttp.StatusNotFound || location == tr.location)) { - t.Errorf("NotFound handling route %s failed: ReqMethod=%s, Code=%d, Header=%v", method, tr.route, statusCode, location) + fn := t.Errorf + msg := "NotFound handling route '%s' failed: Method=%s, ReqMethod=%s, Code=%d, ExpectedCode=%d, Header=%v" + + if runtime.GOOS == "windows" && strings.HasPrefix(tr.route, "/../") { + // See: https://github.com/valyala/fasthttp/issues/1226 + // Not fail, because it is a known issue. + fn = t.Logf + msg = "ERROR: " + msg + } + + fn(msg, tr.route, method, reqMethod, statusCode, tr.code, location) } } @@ -655,9 +660,14 @@ func testRouterNotFoundByMethod(t *testing.T, method string) { ctx.Request.Header.SetMethod(reqMethod) ctx.Request.SetRequestURI("/nope") router.Handler(ctx) + if !(ctx.Response.StatusCode() == fasthttp.StatusNotFound && notFound == true) { - t.Errorf("Custom NotFound handler failed: Code=%d, Header=%v", ctx.Response.StatusCode(), ctx.Response.Header.String()) + t.Errorf( + "Custom NotFound handling failed: Method=%s, ReqMethod=%s, Code=%d, Header=%v", + method, reqMethod, ctx.Response.StatusCode(), ctx.Response.Header.String(), + ) } + ctx.Response.Reset() }