Skip to content

Commit

Permalink
Merge pull request #436 from Fenny/master
Browse files Browse the repository at this point in the history
Hot fix Fasthttp file server bug
  • Loading branch information
Fenny authored Jun 3, 2020
2 parents 961fda2 + f44b1fd commit 6e9fae8
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 13 deletions.
24 changes: 23 additions & 1 deletion app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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")
Expand Down
84 changes: 82 additions & 2 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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")
Expand All @@ -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()

Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -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=
Expand Down
23 changes: 16 additions & 7 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 6e9fae8

Please sign in to comment.