From 64d74e840a53ff8d4a4067e58f05a735eaa211c9 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Wed, 3 Jun 2020 17:16:10 +0200 Subject: [PATCH 1/2] Hot fix fasthttp bug --- app_test.go | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++-- go.mod | 3 +- go.sum | 4 +-- router.go | 23 ++++++++++----- 4 files changed, 102 insertions(+), 12 deletions(-) diff --git a/app_test.go b/app_test.go index 24e9ab9768..79a9997d7d 100644 --- a/app_test.go +++ b/app_test.go @@ -28,6 +28,43 @@ func testStatus200(t *testing.T, app *App, url string, method string) { // } +// func Test_App_ErrorHandler(t *testing.T) { +// app := New() + +// app.Get("/", func(c *Ctx) { +// c.Next(errors.New("Hi, I'm an error!")) +// }) + +// resp, err := app.Test(httptest.NewRequest("GET", "/", nil)) +// utils.AssertEqual(t, nil, err, "app.Test(req)") +// utils.AssertEqual(t, 500, resp.StatusCode, "Status code") + +// body, err := ioutil.ReadAll(resp.Body) +// utils.AssertEqual(t, nil, err) +// utils.AssertEqual(t, "Hi, I'm an error!", string(body)) + +// } + +// func Test_App_ErrorHandler_Custom(t *testing.T) { +// app := New(&Settings{ +// ErrorHandler: func(ctx *Ctx, err error) { +// ctx.Status(200).SendString("Hi, I'm an custom error!") +// }, +// }) + +// app.Get("/", func(c *Ctx) { +// c.Next(errors.New("Hi, I'm an error!")) +// }) + +// resp, err := app.Test(httptest.NewRequest("GET", "/", nil)) +// utils.AssertEqual(t, nil, err, "app.Test(req)") +// utils.AssertEqual(t, 200, resp.StatusCode, "Status code") + +// body, err := ioutil.ReadAll(resp.Body) +// utils.AssertEqual(t, nil, err) +// utils.AssertEqual(t, "Hi, I'm an custom error!", string(body)) +// } + func Test_App_Nested_Params(t *testing.T) { app := New() @@ -204,8 +241,8 @@ func Test_App_Shutdown(t *testing.T) { _ = app.Shutdown() } -// go test -run Test_App_Static -func Test_App_Static_Index(t *testing.T) { +// go test -run Test_App_Static_Index_Default +func Test_App_Static_Index_Default(t *testing.T) { app := New() app.Static("/prefix", "./.github/workflows") @@ -222,6 +259,33 @@ func Test_App_Static_Index(t *testing.T) { utils.AssertEqual(t, true, strings.Contains(string(body), "Hello, World!")) } + +// go test -run Test_App_Static_Index +func Test_App_Static_Direct(t *testing.T) { + app := New() + + app.Static("/", "./.github") + + resp, err := app.Test(httptest.NewRequest("GET", "/index.html", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, 200, resp.StatusCode, "Status code") + utils.AssertEqual(t, false, resp.Header.Get("Content-Length") == "") + utils.AssertEqual(t, "text/html; charset=utf-8", resp.Header.Get("Content-Type")) + + body, err := ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, nil, err) + utils.AssertEqual(t, true, strings.Contains(string(body), "Hello, World!")) + + resp, err = app.Test(httptest.NewRequest("GET", "/FUNDING.yml", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, 200, resp.StatusCode, "Status code") + utils.AssertEqual(t, false, resp.Header.Get("Content-Length") == "") + utils.AssertEqual(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) + + body, err = ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, nil, err) + utils.AssertEqual(t, true, strings.Contains(string(body), "buymeacoffee")) +} func Test_App_Static_Group(t *testing.T) { app := New() @@ -264,6 +328,10 @@ func Test_App_Static_Wildcard(t *testing.T) { utils.AssertEqual(t, false, resp.Header.Get("Content-Length") == "") utils.AssertEqual(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) + body, err := ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, nil, err) + utils.AssertEqual(t, true, strings.Contains(string(body), "buymeacoffee")) + } func Test_App_Static_Prefix_Wildcard(t *testing.T) { @@ -277,6 +345,18 @@ func Test_App_Static_Prefix_Wildcard(t *testing.T) { utils.AssertEqual(t, 200, resp.StatusCode, "Status code") utils.AssertEqual(t, false, resp.Header.Get("Content-Length") == "") utils.AssertEqual(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) + + app.Static("/my/nameisjohn*", "./.github/FUNDING.yml") + + resp, err = app.Test(httptest.NewRequest("GET", "/my/nameisjohn/no/its/not", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, 200, resp.StatusCode, "Status code") + utils.AssertEqual(t, false, resp.Header.Get("Content-Length") == "") + utils.AssertEqual(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) + + body, err := ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, nil, err) + utils.AssertEqual(t, true, strings.Contains(string(body), "buymeacoffee")) } func Test_App_Static_Prefix(t *testing.T) { diff --git a/go.mod b/go.mod index 4c5337624c..39ba88593d 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,8 @@ module github.com/gofiber/fiber go 1.11 require ( - github.com/gofiber/utils v0.0.3 + github.com/gofiber/utils v0.0.4 + github.com/google/uuid v1.1.1 // indirect github.com/gorilla/schema v1.1.0 github.com/valyala/bytebufferpool v1.0.0 github.com/valyala/fasthttp v1.14.0 diff --git a/go.sum b/go.sum index 7c10cde935..288584d55f 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/gofiber/utils v0.0.3 h1:nNQKfZbZAGmOHqTOYplJwwOvX1Mg/NsTjfFO4/wTGrU= -github.com/gofiber/utils v0.0.3/go.mod h1:pacRFtghAE3UoknMOUiXh2Io/nLWSUHtQCi/3QASsOc= +github.com/gofiber/utils v0.0.4 h1:gcOb+WZDQ319bELqAp5ePDYwxostDDzWh4pY7S0KiMI= +github.com/gofiber/utils v0.0.4/go.mod h1:pacRFtghAE3UoknMOUiXh2Io/nLWSUHtQCi/3QASsOc= github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY= github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= github.com/klauspost/compress v1.10.4 h1:jFzIFaf586tquEB5EhzQG0HwGNSlgAJpG53G6Ss11wc= diff --git a/router.go b/router.go index 0337d4deae..cc1cab83ba 100644 --- a/router.go +++ b/router.go @@ -96,6 +96,19 @@ func (app *App) next(ctx *Ctx) bool { func (app *App) handler(rctx *fasthttp.RequestCtx) { // Acquire Ctx with fasthttp request from pool ctx := app.AcquireCtx(rctx) + // // Possible feature for v1.12 + // // Add recover by default + // defer func() { + // if r := recover(); r != nil { + // err, ok := r.(error) + // if !ok { + // err = fmt.Errorf("%v", r) + // } + // app.Settings.ErrorHandler(ctx, err) + // app.ReleaseCtx(ctx) + // return + // } + // }() // Prettify path ctx.prettifyPath() // Find match in stack @@ -233,7 +246,8 @@ func (app *App) registerStatic(prefix, root string, config ...Static) *Route { path = path[prefixLen:] } } - return append(path, '/') + path = append([]byte("/"), path...) + return path }, PathNotFound: func(ctx *fasthttp.RequestCtx) { ctx.Response.SetStatusCode(404) @@ -262,12 +276,7 @@ func (app *App) registerStatic(prefix, root string, config ...Static) *Route { c.Fasthttp.Response.SetStatusCode(200) c.Fasthttp.Response.SetBodyString("") // Next middleware - match := c.app.next(c) - // If no other route is executed return 404 Not Found - if !match { - c.Fasthttp.Response.SetStatusCode(404) - c.Fasthttp.Response.SetBodyString("Not Found") - } + c.Next() } route := &Route{ use: true, From f44b1fd88e06850ea42ee0330c0d8a4c4959d1de Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Wed, 3 Jun 2020 17:20:20 +0200 Subject: [PATCH 2/2] Update version --- app.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index 5325286ebc..7913b37cee 100644 --- a/app.go +++ b/app.go @@ -26,7 +26,7 @@ import ( ) // Version of current package -const Version = "1.10.4" +const Version = "1.10.5" // Map is a shortcut for map[string]interface{}, useful for JSON returns type Map map[string]interface{} @@ -49,6 +49,14 @@ type App struct { // Settings holds is a struct holding the server settings type Settings struct { + // Possible feature for v1.11.x + // // ErrorHandler is executed when you pass an error in the Next(err) method + // // This function is also executed when a panic occurs somewhere in the stack + // // Default: func(err error, ctx *fiber.Ctx) { + // // ctx.Status(500).Send(err.Error()) + // // } + // ErrorHandler func(*Ctx, error) + // Enables the "Server: value" HTTP header. // Default: "" ServerHeader string @@ -181,6 +189,10 @@ func New(settings ...*Settings) *App { Prefork: utils.GetArgument("-prefork"), BodyLimit: 4 * 1024 * 1024, Concurrency: 256 * 1024, + // Possible feature for v1.11.x + // ErrorHandler: func(ctx *Ctx, err error) { + // ctx.Status(500).SendString(err.Error()) + // }, }, } // Overwrite settings if provided @@ -200,6 +212,12 @@ func New(settings ...*Settings) *App { getBytes = getBytesImmutable getString = getStringImmutable } + // Possible feature for v1.11.x + // if app.Settings.ErrorHandler == nil { + // app.Settings.ErrorHandler = func(ctx *Ctx, err error) { + // ctx.Status(500).SendString(err.Error()) + // } + // } } // Initialize app return app.init() @@ -491,6 +509,10 @@ func (app *App) init() *App { Logger: &disableLogger{}, LogAllErrors: false, ErrorHandler: func(fctx *fasthttp.RequestCtx, err error) { + // Possible feature for v1.11.x + // ctx := app.AcquireCtx(fctx) + // app.Settings.ErrorHandler(ctx, err) + // app.ReleaseCtx(ctx) if _, ok := err.(*fasthttp.ErrSmallBuffer); ok { fctx.Response.SetStatusCode(StatusRequestHeaderFieldsTooLarge) fctx.Response.SetBodyString("Request Header Fields Too Large")