Skip to content

Commit

Permalink
Merge branch 'main' into feat/cbor
Browse files Browse the repository at this point in the history
  • Loading branch information
imsk17 authored Nov 7, 2024
2 parents ae8407c + 7126e48 commit 988fd26
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 46 deletions.
Binary file added .github/testdata/fs/img/fiberpng
Binary file not shown.
Binary file added .github/testdata/fs/img/fiberpng.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/testdata/fs/img/fiberpng.notvalidext
Binary file not shown.
2 changes: 1 addition & 1 deletion app.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ type Config struct { //nolint:govet // Aligning the struct fields is not necessa
// Default: false
StrictRouting bool `json:"strict_routing"`

// When set to true, enables case sensitive routing.
// When set to true, enables case-sensitive routing.
// E.g. "/FoO" and "/foo" are treated as different routes.
// By default this is disabled and both "/FoO" and "/foo" will execute the same handler.
//
Expand Down
4 changes: 2 additions & 2 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,9 @@ func Test_App_Use_CaseSensitive(t *testing.T) {
require.NoError(t, err, "app.Test(req)")
require.Equal(t, StatusOK, resp.StatusCode, "Status code")

// check the detected path when the case insensitive recognition is activated
// check the detected path when the case-insensitive recognition is activated
app.config.CaseSensitive = false
// check the case sensitive feature
// check the case-sensitive feature
resp, err = app.Test(httptest.NewRequest(MethodGet, "/AbC", nil))
require.NoError(t, err, "app.Test(req)")
require.Equal(t, StatusOK, resp.StatusCode, "Status code")
Expand Down
17 changes: 9 additions & 8 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,29 +83,29 @@ type SendFile struct {
// You have to set Content-Encoding header to compress the file.
// Available compression methods are gzip, br, and zstd.
//
// Optional. Default value false
// Optional. Default: false
Compress bool `json:"compress"`

// When set to true, enables byte range requests.
//
// Optional. Default value false
// Optional. Default: false
ByteRange bool `json:"byte_range"`

// When set to true, enables direct download.
//
// Optional. Default: false.
// Optional. Default: false
Download bool `json:"download"`

// Expiration duration for inactive file handlers.
// Use a negative time.Duration to disable it.
//
// Optional. Default value 10 * time.Second.
// Optional. Default: 10 * time.Second
CacheDuration time.Duration `json:"cache_duration"`

// The value for the Cache-Control HTTP-header
// that is set on the file response. MaxAge is defined in seconds.
//
// Optional. Default value 0.
// Optional. Default: 0
MaxAge int `json:"max_age"`
}

Expand Down Expand Up @@ -1514,9 +1514,10 @@ func (c *DefaultCtx) Send(body []byte) error {
return nil
}

// SendFile transfers the file from the given path.
// The file is not compressed by default, enable this by passing a 'true' argument
// Sets the Content-Type response HTTP header field based on the filenames extension.
// SendFile transfers the file from the specified path.
// By default, the file is not compressed. To enable compression, set SendFile.Compress to true.
// The Content-Type response HTTP header field is set based on the file's extension.
// If the file extension is missing or invalid, the Content-Type is detected from the file's format.
func (c *DefaultCtx) SendFile(file string, config ...SendFile) error {
// Save the filename, we will need it in the error message if the file isn't found
filename := file
Expand Down
7 changes: 4 additions & 3 deletions ctx_interface_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3123,6 +3123,49 @@ func Test_Ctx_SendFile(t *testing.T) {
app.ReleaseCtx(c)
}

// go test -race -run Test_Ctx_SendFile_ContentType
func Test_Ctx_SendFile_ContentType(t *testing.T) {
t.Parallel()
app := New()

// 1) simple case
c := app.AcquireCtx(&fasthttp.RequestCtx{})
err := c.SendFile("./.github/testdata/fs/img/fiber.png")
// check expectation
require.NoError(t, err)
require.Equal(t, StatusOK, c.Response().StatusCode())
require.Equal(t, "image/png", string(c.Response().Header.Peek(HeaderContentType)))
app.ReleaseCtx(c)

// 2) set by valid file extension, not file header
// see: https://github.com/valyala/fasthttp/blob/d795f13985f16622a949ea9fc3459cf54dc78b3e/fs.go#L1638
c = app.AcquireCtx(&fasthttp.RequestCtx{})
err = c.SendFile("./.github/testdata/fs/img/fiberpng.jpeg")
// check expectation
require.NoError(t, err)
require.Equal(t, StatusOK, c.Response().StatusCode())
require.Equal(t, "image/jpeg", string(c.Response().Header.Peek(HeaderContentType)))
app.ReleaseCtx(c)

// 3) set by file header if extension is invalid
c = app.AcquireCtx(&fasthttp.RequestCtx{})
err = c.SendFile("./.github/testdata/fs/img/fiberpng.notvalidext")
// check expectation
require.NoError(t, err)
require.Equal(t, StatusOK, c.Response().StatusCode())
require.Equal(t, "image/png", string(c.Response().Header.Peek(HeaderContentType)))
app.ReleaseCtx(c)

// 4) set by file header if extension is missing
c = app.AcquireCtx(&fasthttp.RequestCtx{})
err = c.SendFile("./.github/testdata/fs/img/fiberpng")
// check expectation
require.NoError(t, err)
require.Equal(t, StatusOK, c.Response().StatusCode())
require.Equal(t, "image/png", string(c.Response().Header.Peek(HeaderContentType)))
app.ReleaseCtx(c)
}

func Test_Ctx_SendFile_Download(t *testing.T) {
t.Parallel()
app := New()
Expand Down
22 changes: 11 additions & 11 deletions docs/api/ctx.md
Original file line number Diff line number Diff line change
Expand Up @@ -1709,7 +1709,7 @@ app.Get("/", func(c fiber.Ctx) error {

## SendFile

Transfers the file from the given path. Sets the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) response HTTP header field based on the **filenames** extension.
Transfers the file from the given path. Sets the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) response HTTP header field based on the **file** extension or format.

```go title="Config" title="Config"
// SendFile defines configuration options when to transfer file with SendFile.
Expand All @@ -1725,29 +1725,29 @@ type SendFile struct {
// You have to set Content-Encoding header to compress the file.
// Available compression methods are gzip, br, and zstd.
//
// Optional. Default value false
// Optional. Default: false
Compress bool `json:"compress"`
// When set to true, enables byte range requests.
//
// Optional. Default value false
// Optional. Default: false
ByteRange bool `json:"byte_range"`
// When set to true, enables direct download.
//
// Optional. Default: false.
// Optional. Default: false
Download bool `json:"download"`
// Expiration duration for inactive file handlers.
// Use a negative time.Duration to disable it.
//
// Optional. Default value 10 * time.Second.
// Optional. Default: 10 * time.Second
CacheDuration time.Duration `json:"cache_duration"`
// The value for the Cache-Control HTTP-header
// that is set on the file response. MaxAge is defined in seconds.
//
// Optional. Default value 0.
// Optional. Default: 0
MaxAge int `json:"max_age"`
}
```
Expand All @@ -1761,7 +1761,7 @@ app.Get("/not-found", func(c fiber.Ctx) error {
return c.SendFile("./public/404.html");
// Disable compression
return c.SendFile("./static/index.html", SendFile{
return c.SendFile("./static/index.html", fiber.SendFile{
Compress: false,
});
})
Expand All @@ -1783,7 +1783,7 @@ You can set `CacheDuration` config property to `-1` to disable caching.

```go title="Example"
app.Get("/file", func(c fiber.Ctx) error {
return c.SendFile("style.css", SendFile{
return c.SendFile("style.css", fiber.SendFile{
CacheDuration: -1,
})
})
Expand All @@ -1797,16 +1797,16 @@ You can use multiple SendFile with different configurations in single route. Fib
app.Get("/file", func(c fiber.Ctx) error {
switch c.Query("config") {
case "filesystem":
return c.SendFile("style.css", SendFile{
return c.SendFile("style.css", fiber.SendFile{
FS: os.DirFS(".")
})
case "filesystem-compress":
return c.SendFile("style.css", SendFile{
return c.SendFile("style.css", fiber.SendFile{
FS: os.DirFS("."),
Compress: true,
})
case "compress":
return c.SendFile("style.css", SendFile{
return c.SendFile("style.css", fiber.SendFile{
Compress: true,
})
default:
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ require (
github.com/mattn/go-colorable v0.1.13
github.com/mattn/go-isatty v0.0.20
github.com/stretchr/testify v1.9.0
github.com/tinylib/msgp v1.2.1
github.com/tinylib/msgp v1.2.4
github.com/valyala/bytebufferpool v1.0.0
github.com/valyala/fasthttp v1.56.0
github.com/valyala/fasthttp v1.57.0
)

require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // direct
github.com/klauspost/compress v1.17.9 // indirect
Expand Down
34 changes: 18 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
Expand All @@ -10,37 +10,39 @@ github.com/gofiber/utils/v2 v2.0.0-beta.7 h1:NnHFrRHvhrufPABdWajcKZejz9HnCWmT/as
github.com/gofiber/utils/v2 v2.0.0-beta.7/go.mod h1:J/M03s+HMdZdvhAeyh76xT72IfVqBzuz/OJkrMa7cwU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 h1:jYi87L8j62qkXzaYHAQAhEapgukhenIMZRBKTNRLHJ4=
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tinylib/msgp v1.2.1 h1:6ypy2qcCznxpP4hpORzhtXyTqrBs7cfM9MCCWY8zsmU=
github.com/tinylib/msgp v1.2.1/go.mod h1:2vIGs3lcUo8izAATNobrCHevYZC/LMsJtw4JPiYPHro=
github.com/tinylib/msgp v1.2.4 h1:yLFeUGostXXSGW5vxfT5dXG/qzkn4schv2I7at5+hVU=
github.com/tinylib/msgp v1.2.4/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.56.0 h1:bEZdJev/6LCBlpdORfrLu/WOZXXxvrUQSiyniuaoW8U=
github.com/valyala/fasthttp v1.56.0/go.mod h1:sReBt3XZVnudxuLOx4J/fMrJVorWRiWY2koQKgABiVI=
github.com/valyala/fasthttp v1.57.0 h1:Xw8SjWGEP/+wAAgyy5XTvgrWlOD1+TxbbvNADYCm1Tg=
github.com/valyala/fasthttp v1.57.0/go.mod h1:h6ZBaPRlzpZ6O3H5t2gEk1Qi33+TmLvfwgLLp0t9CpE=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
4 changes: 2 additions & 2 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type Route struct {
Name string `json:"name"` // Route's name
//nolint:revive // Having both a Path (uppercase) and a path (lowercase) is fine
Path string `json:"path"` // Original registered route path
Params []string `json:"params"` // Case sensitive param keys
Params []string `json:"params"` // Case-sensitive param keys
Handlers []Handler `json:"-"` // Ctx handlers
routeParser routeParser // Parameter parser
// Data for routing
Expand Down Expand Up @@ -316,7 +316,7 @@ func (app *App) register(methods []string, pathRaw string, group *Group, handler
if pathRaw[0] != '/' {
pathRaw = "/" + pathRaw
}
// Create a stripped path in-case sensitive / trailing slashes
// Create a stripped path in case-sensitive / trailing slashes
pathPretty := pathRaw
// Case-sensitive routing, all to lowercase
if !app.config.CaseSensitive {
Expand Down

0 comments on commit 988fd26

Please sign in to comment.