mirror of https://github.com/gofiber/fiber.git
ci: address multiple lint rules (#2869)
* ci: explicitly disable tagalign Tagalign requires awkward manual formatting and doesn't provide much value for readability. * ci: enable mirror linter mirror warns against certain cases of useless conversion between string and []byte. * ci: enable perfsprint linter This linter encourages replacing several functions from the fmt package with faster alternatives. While fixing issues, I also added a few exported error types rather than returning a naked errors.New().pull/2870/head
parent
529086aa84
commit
4c68e0242d
|
@ -164,7 +164,8 @@ issues:
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
disable:
|
disable:
|
||||||
- spancheck
|
- spancheck # opentelemetry, irrelevant
|
||||||
|
- tagalign # requires awkward manual formatting of struct tags
|
||||||
enable:
|
enable:
|
||||||
- asasalint
|
- asasalint
|
||||||
- asciicheck
|
- asciicheck
|
||||||
|
@ -199,7 +200,7 @@ linters:
|
||||||
- grouper
|
- grouper
|
||||||
- inamedparam
|
- inamedparam
|
||||||
- loggercheck
|
- loggercheck
|
||||||
# - mirror # TODO https://github.com/gofiber/fiber/issues/2816
|
- mirror
|
||||||
- misspell
|
- misspell
|
||||||
- nakedret
|
- nakedret
|
||||||
- nilerr
|
- nilerr
|
||||||
|
@ -208,7 +209,7 @@ linters:
|
||||||
- nolintlint
|
- nolintlint
|
||||||
- nonamedreturns
|
- nonamedreturns
|
||||||
- nosprintfhostport
|
- nosprintfhostport
|
||||||
# - perfsprint # TODO https://github.com/gofiber/fiber/issues/2816
|
- perfsprint
|
||||||
- predeclared
|
- predeclared
|
||||||
- promlinter
|
- promlinter
|
||||||
- reassign
|
- reassign
|
||||||
|
@ -217,7 +218,6 @@ linters:
|
||||||
- sqlclosecheck
|
- sqlclosecheck
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- stylecheck
|
- stylecheck
|
||||||
# - tagalign # TODO https://github.com/gofiber/fiber/issues/2816
|
|
||||||
- tagliatelle
|
- tagliatelle
|
||||||
- testifylint
|
- testifylint
|
||||||
# - testpackage # TODO: Enable once https://github.com/gofiber/fiber/issues/2252 is implemented
|
# - testpackage # TODO: Enable once https://github.com/gofiber/fiber/issues/2252 is implemented
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package retry
|
package retry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -44,9 +44,9 @@ func TestExponentialBackoff_Retry(t *testing.T) {
|
||||||
MaxRetryCount: 5,
|
MaxRetryCount: 5,
|
||||||
},
|
},
|
||||||
f: func() error {
|
f: func() error {
|
||||||
return fmt.Errorf("failed function")
|
return errors.New("failed function")
|
||||||
},
|
},
|
||||||
expErr: fmt.Errorf("failed function"),
|
expErr: errors.New("failed function"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
9
app.go
9
app.go
|
@ -897,7 +897,7 @@ func (app *App) ShutdownWithContext(ctx context.Context) error {
|
||||||
app.mutex.Lock()
|
app.mutex.Lock()
|
||||||
defer app.mutex.Unlock()
|
defer app.mutex.Unlock()
|
||||||
if app.server == nil {
|
if app.server == nil {
|
||||||
return fmt.Errorf("shutdown: server is not running")
|
return ErrNotRunning
|
||||||
}
|
}
|
||||||
return app.server.ShutdownWithContext(ctx)
|
return app.server.ShutdownWithContext(ctx)
|
||||||
}
|
}
|
||||||
|
@ -948,7 +948,7 @@ func (app *App) Test(req *http.Request, msTimeout ...int) (*http.Response, error
|
||||||
var returned bool
|
var returned bool
|
||||||
defer func() {
|
defer func() {
|
||||||
if !returned {
|
if !returned {
|
||||||
channel <- fmt.Errorf("runtime.Goexit() called in handler or server panic")
|
channel <- ErrHandlerExited
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -1071,10 +1071,7 @@ func (app *App) ErrorHandler(ctx Ctx, err error) error {
|
||||||
// errors before calling the application's error handler method.
|
// errors before calling the application's error handler method.
|
||||||
func (app *App) serverErrorHandler(fctx *fasthttp.RequestCtx, err error) {
|
func (app *App) serverErrorHandler(fctx *fasthttp.RequestCtx, err error) {
|
||||||
// Acquire Ctx with fasthttp request from pool
|
// Acquire Ctx with fasthttp request from pool
|
||||||
c, ok := app.AcquireCtx().(*DefaultCtx)
|
c := app.AcquireCtx()
|
||||||
if !ok {
|
|
||||||
panic(fmt.Errorf("failed to type-assert to *DefaultCtx"))
|
|
||||||
}
|
|
||||||
c.Reset(fctx)
|
c.Reset(fctx)
|
||||||
|
|
||||||
defer app.ReleaseCtx(c)
|
defer app.ReleaseCtx(c)
|
||||||
|
|
|
@ -1672,7 +1672,7 @@ func Test_App_ReadBodyStream(t *testing.T) {
|
||||||
require.NoError(t, err, "app.Test(req)")
|
require.NoError(t, err, "app.Test(req)")
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err, "io.ReadAll(resp.Body)")
|
require.NoError(t, err, "io.ReadAll(resp.Body)")
|
||||||
require.Equal(t, fmt.Sprintf("true %s", testString), string(body))
|
require.Equal(t, "true "+testString, string(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_App_DisablePreParseMultipartForm(t *testing.T) {
|
func Test_App_DisablePreParseMultipartForm(t *testing.T) {
|
||||||
|
@ -1688,7 +1688,7 @@ func Test_App_DisablePreParseMultipartForm(t *testing.T) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !req.IsBodyStream() {
|
if !req.IsBodyStream() {
|
||||||
return fmt.Errorf("not a body stream")
|
return errors.New("not a body stream")
|
||||||
}
|
}
|
||||||
file, err := mpf.File["test"][0].Open()
|
file, err := mpf.File["test"][0].Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1700,7 +1700,7 @@ func Test_App_DisablePreParseMultipartForm(t *testing.T) {
|
||||||
return fmt.Errorf("failed to read: %w", err)
|
return fmt.Errorf("failed to read: %w", err)
|
||||||
}
|
}
|
||||||
if n != len(testString) {
|
if n != len(testString) {
|
||||||
return fmt.Errorf("bad read length")
|
return errors.New("bad read length")
|
||||||
}
|
}
|
||||||
return c.Send(buffer)
|
return c.Send(buffer)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1556,7 +1556,7 @@ func (*structValidator) ValidateStruct(out any) error {
|
||||||
out = reflect.ValueOf(out).Elem().Interface()
|
out = reflect.ValueOf(out).Elem().Interface()
|
||||||
sq, ok := out.(simpleQuery)
|
sq, ok := out.(simpleQuery)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("failed to type-assert to simpleQuery")
|
return errors.New("failed to type-assert to simpleQuery")
|
||||||
}
|
}
|
||||||
|
|
||||||
if sq.Name != "john" {
|
if sq.Name != "john" {
|
||||||
|
|
11
client.go
11
client.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
|
@ -885,7 +886,7 @@ func AcquireClient() *Client {
|
||||||
}
|
}
|
||||||
c, ok := v.(*Client)
|
c, ok := v.(*Client)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to *Client"))
|
panic(errors.New("failed to type-assert to *Client"))
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -911,7 +912,7 @@ func ReleaseClient(c *Client) {
|
||||||
func AcquireAgent() *Agent {
|
func AcquireAgent() *Agent {
|
||||||
a, ok := agentPool.Get().(*Agent)
|
a, ok := agentPool.Get().(*Agent)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to *Agent"))
|
panic(errors.New("failed to type-assert to *Agent"))
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
@ -938,7 +939,7 @@ func AcquireResponse() *Response {
|
||||||
}
|
}
|
||||||
r, ok := v.(*Response)
|
r, ok := v.(*Response)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to *Response"))
|
panic(errors.New("failed to type-assert to *Response"))
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
@ -965,7 +966,7 @@ func AcquireArgs() *Args {
|
||||||
}
|
}
|
||||||
a, ok := v.(*Args)
|
a, ok := v.(*Args)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to *Args"))
|
panic(errors.New("failed to type-assert to *Args"))
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
@ -990,7 +991,7 @@ func AcquireFormFile() *FormFile {
|
||||||
}
|
}
|
||||||
ff, ok := v.(*FormFile)
|
ff, ok := v.(*FormFile)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to *FormFile"))
|
panic(errors.New("failed to type-assert to *FormFile"))
|
||||||
}
|
}
|
||||||
return ff
|
return ff
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net"
|
"net"
|
||||||
|
@ -630,7 +629,7 @@ type readErrorConn struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*readErrorConn) Read(_ []byte) (int, error) {
|
func (*readErrorConn) Read(_ []byte) (int, error) {
|
||||||
return 0, fmt.Errorf("error")
|
return 0, errors.New("error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*readErrorConn) Write(p []byte) (int, error) {
|
func (*readErrorConn) Write(p []byte) (int, error) {
|
||||||
|
|
11
ctx.go
11
ctx.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
|
@ -615,7 +616,7 @@ func (c *DefaultCtx) Hostname() string {
|
||||||
func (c *DefaultCtx) Port() string {
|
func (c *DefaultCtx) Port() string {
|
||||||
tcpaddr, ok := c.fasthttp.RemoteAddr().(*net.TCPAddr)
|
tcpaddr, ok := c.fasthttp.RemoteAddr().(*net.TCPAddr)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to *net.TCPAddr"))
|
panic(errors.New("failed to type-assert to *net.TCPAddr"))
|
||||||
}
|
}
|
||||||
return strconv.Itoa(tcpaddr.Port)
|
return strconv.Itoa(tcpaddr.Port)
|
||||||
}
|
}
|
||||||
|
@ -1108,12 +1109,8 @@ func (c *DefaultCtx) Queries() map[string]string {
|
||||||
// age := Query[int](c, "age") // Returns 8
|
// age := Query[int](c, "age") // Returns 8
|
||||||
// unknown := Query[string](c, "unknown", "default") // Returns "default" since the query parameter "unknown" is not found
|
// unknown := Query[string](c, "unknown", "default") // Returns "default" since the query parameter "unknown" is not found
|
||||||
func Query[V QueryType](c Ctx, key string, defaultValue ...V) V {
|
func Query[V QueryType](c Ctx, key string, defaultValue ...V) V {
|
||||||
ctx, ok := c.(*DefaultCtx)
|
|
||||||
if !ok {
|
|
||||||
panic(fmt.Errorf("failed to type-assert to *DefaultCtx"))
|
|
||||||
}
|
|
||||||
var v V
|
var v V
|
||||||
q := ctx.app.getString(ctx.fasthttp.QueryArgs().Peek(key))
|
q := c.App().getString(c.Context().QueryArgs().Peek(key))
|
||||||
|
|
||||||
switch any(v).(type) {
|
switch any(v).(type) {
|
||||||
case int:
|
case int:
|
||||||
|
@ -1151,7 +1148,7 @@ func Query[V QueryType](c Ctx, key string, defaultValue ...V) V {
|
||||||
if q == "" && len(defaultValue) > 0 {
|
if q == "" && len(defaultValue) > 0 {
|
||||||
return defaultValue[0]
|
return defaultValue[0]
|
||||||
}
|
}
|
||||||
return assertValueType[V, []byte](ctx.app.getBytes(q))
|
return assertValueType[V, []byte](c.App().getBytes(q))
|
||||||
default:
|
default:
|
||||||
if len(defaultValue) > 0 {
|
if len(defaultValue) > 0 {
|
||||||
return defaultValue[0]
|
return defaultValue[0]
|
||||||
|
|
|
@ -7,7 +7,7 @@ package fiber
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -446,7 +446,7 @@ func (app *App) NewCtx(fctx *fasthttp.RequestCtx) Ctx {
|
||||||
func (app *App) AcquireCtx() Ctx {
|
func (app *App) AcquireCtx() Ctx {
|
||||||
ctx, ok := app.pool.Get().(Ctx)
|
ctx, ok := app.pool.Get().(Ctx)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to Ctx"))
|
panic(errors.New("failed to type-assert to Ctx"))
|
||||||
}
|
}
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
|
@ -1271,7 +1271,7 @@ func Test_Ctx_FormValue(t *testing.T) {
|
||||||
require.NoError(t, writer.Close())
|
require.NoError(t, writer.Close())
|
||||||
|
|
||||||
req := httptest.NewRequest(MethodPost, "/test", body)
|
req := httptest.NewRequest(MethodPost, "/test", body)
|
||||||
req.Header.Set("Content-Type", fmt.Sprintf("multipart/form-data; boundary=%s", writer.Boundary()))
|
req.Header.Set("Content-Type", "multipart/form-data; boundary="+writer.Boundary())
|
||||||
req.Header.Set("Content-Length", strconv.Itoa(len(body.Bytes())))
|
req.Header.Set("Content-Length", strconv.Itoa(len(body.Bytes())))
|
||||||
|
|
||||||
resp, err := app.Test(req)
|
resp, err := app.Test(req)
|
||||||
|
@ -2155,7 +2155,7 @@ func Test_Ctx_MultipartForm(t *testing.T) {
|
||||||
require.NoError(t, writer.Close())
|
require.NoError(t, writer.Close())
|
||||||
|
|
||||||
req := httptest.NewRequest(MethodPost, "/test", body)
|
req := httptest.NewRequest(MethodPost, "/test", body)
|
||||||
req.Header.Set(HeaderContentType, fmt.Sprintf("multipart/form-data; boundary=%s", writer.Boundary()))
|
req.Header.Set(HeaderContentType, "multipart/form-data; boundary="+writer.Boundary())
|
||||||
req.Header.Set(HeaderContentLength, strconv.Itoa(len(body.Bytes())))
|
req.Header.Set(HeaderContentLength, strconv.Itoa(len(body.Bytes())))
|
||||||
|
|
||||||
resp, err := app.Test(req)
|
resp, err := app.Test(req)
|
||||||
|
@ -4181,7 +4181,7 @@ func Test_Ctx_Render_Go_Template(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
_, err = file.Write([]byte("template"))
|
_, err = file.WriteString("template")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = file.Close()
|
err = file.Close()
|
||||||
|
|
6
error.go
6
error.go
|
@ -11,9 +11,13 @@ import (
|
||||||
// Unexported because users will hopefully never need to see it.
|
// Unexported because users will hopefully never need to see it.
|
||||||
var errUnreachable = errors.New("fiber: unreachable code, please create an issue at github.com/gofiber/fiber")
|
var errUnreachable = errors.New("fiber: unreachable code, please create an issue at github.com/gofiber/fiber")
|
||||||
|
|
||||||
// Graceful shutdown errors
|
// General errors
|
||||||
var (
|
var (
|
||||||
ErrGracefulTimeout = errors.New("shutdown: graceful timeout has been reached, exiting")
|
ErrGracefulTimeout = errors.New("shutdown: graceful timeout has been reached, exiting")
|
||||||
|
// ErrNotRunning indicates that a Shutdown method was called when the server was not running.
|
||||||
|
ErrNotRunning = errors.New("shutdown: server is not running")
|
||||||
|
// ErrHandlerExited is returned by App.Test if a handler panics or calls runtime.Goexit().
|
||||||
|
ErrHandlerExited = errors.New("runtime.Goexit() called in handler or server panic")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Fiber redirection errors
|
// Fiber redirection errors
|
||||||
|
|
39
helpers.go
39
helpers.go
|
@ -7,6 +7,7 @@ package fiber
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
@ -41,25 +42,27 @@ func getTLSConfig(ln net.Listener) *tls.Config {
|
||||||
pointer := reflect.ValueOf(ln)
|
pointer := reflect.ValueOf(ln)
|
||||||
|
|
||||||
// Is it a tls.listener?
|
// Is it a tls.listener?
|
||||||
if pointer.String() == "<*tls.listener Value>" {
|
if pointer.String() != "<*tls.listener Value>" {
|
||||||
// Copy value from pointer
|
return nil
|
||||||
if val := reflect.Indirect(pointer); val.Type() != nil {
|
}
|
||||||
// Get private field from value
|
|
||||||
if field := val.FieldByName("config"); field.Type() != nil {
|
// Copy value from pointer
|
||||||
// Copy value from pointer field (unsafe)
|
if val := reflect.Indirect(pointer); val.Type() != nil {
|
||||||
newval := reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())) //nolint:gosec // Probably the only way to extract the *tls.Config from a net.Listener. TODO: Verify there really is no easier way without using unsafe.
|
// Get private field from value
|
||||||
if newval.Type() != nil {
|
if field := val.FieldByName("config"); field.Type() != nil {
|
||||||
// Get element from pointer
|
// Copy value from pointer field (unsafe)
|
||||||
if elem := newval.Elem(); elem.Type() != nil {
|
newval := reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())) //nolint:gosec // Probably the only way to extract the *tls.Config from a net.Listener. TODO: Verify there really is no easier way without using unsafe.
|
||||||
// Cast value to *tls.Config
|
if newval.Type() == nil {
|
||||||
c, ok := elem.Interface().(*tls.Config)
|
return nil
|
||||||
//nolint:revive // We need to check if the type assertion was successful
|
}
|
||||||
if !ok {
|
// Get element from pointer
|
||||||
panic(fmt.Errorf("failed to type-assert to *tls.Config"))
|
if elem := newval.Elem(); elem.Type() != nil {
|
||||||
}
|
// Cast value to *tls.Config
|
||||||
return c
|
c, ok := elem.Interface().(*tls.Config)
|
||||||
}
|
if !ok {
|
||||||
|
panic(errors.New("failed to type-assert to *tls.Config"))
|
||||||
}
|
}
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ func Test_Cache_Expired(t *testing.T) {
|
||||||
app.Use(New(Config{Expiration: 2 * time.Second}))
|
app.Use(New(Config{Expiration: 2 * time.Second}))
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
return c.SendString(fmt.Sprintf("%d", time.Now().UnixNano()))
|
return c.SendString(strconv.FormatInt(time.Now().UnixNano(), 10))
|
||||||
})
|
})
|
||||||
|
|
||||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||||
|
@ -88,7 +88,7 @@ func Test_Cache(t *testing.T) {
|
||||||
app.Use(New())
|
app.Use(New())
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
now := fmt.Sprintf("%d", time.Now().UnixNano())
|
now := strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||||
return c.SendString(now)
|
return c.SendString(now)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ func Test_Cache_Invalid_Expiration(t *testing.T) {
|
||||||
app.Use(cache)
|
app.Use(cache)
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
now := fmt.Sprintf("%d", time.Now().UnixNano())
|
now := strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||||
return c.SendString(now)
|
return c.SendString(now)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -513,8 +513,7 @@ func Test_CustomExpiration(t *testing.T) {
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
c.Response().Header.Add("Cache-Time", "1")
|
c.Response().Header.Add("Cache-Time", "1")
|
||||||
now := fmt.Sprintf("%d", time.Now().UnixNano())
|
return c.SendString(strconv.FormatInt(time.Now().UnixNano(), 10))
|
||||||
return c.SendString(now)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||||
|
@ -620,7 +619,7 @@ func Test_Cache_WithHead(t *testing.T) {
|
||||||
app.Use(New())
|
app.Use(New())
|
||||||
|
|
||||||
handler := func(c fiber.Ctx) error {
|
handler := func(c fiber.Ctx) error {
|
||||||
now := fmt.Sprintf("%d", time.Now().UnixNano())
|
now := strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||||
return c.SendString(now)
|
return c.SendString(now)
|
||||||
}
|
}
|
||||||
app.Route("/").Get(handler).Head(handler)
|
app.Route("/").Get(handler).Head(handler)
|
||||||
|
|
|
@ -70,7 +70,7 @@ func appWithConfig(t *testing.T, c *fiber.Config) *fiber.App {
|
||||||
}, "/", func(c fiber.Ctx) error {
|
}, "/", func(c fiber.Ctx) error {
|
||||||
valid, ok := c.Locals(localsKeyTestValid).(bool)
|
valid, ok := c.Locals(localsKeyTestValid).(bool)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to bool"))
|
panic(errors.New("failed to type-assert to bool"))
|
||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
return errors.New("handler called even though validation failed")
|
return errors.New("handler called even though validation failed")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package filesystem
|
package filesystem
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
@ -12,6 +13,11 @@ import (
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrDirListingNotSupported is returned from the filesystem middleware handler if
|
||||||
|
// the given fs.FS does not support directory listing. This is uncommon and may
|
||||||
|
// indicate an issue with the FS implementation.
|
||||||
|
var ErrDirListingNotSupported = errors.New("failed to type-assert to fs.ReadDirFile")
|
||||||
|
|
||||||
func getFileExtension(p string) string {
|
func getFileExtension(p string) string {
|
||||||
n := strings.LastIndexByte(p, '.')
|
n := strings.LastIndexByte(p, '.')
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
|
@ -23,7 +29,7 @@ func getFileExtension(p string) string {
|
||||||
func dirList(c fiber.Ctx, f fs.File) error {
|
func dirList(c fiber.Ctx, f fs.File) error {
|
||||||
ff, ok := f.(fs.ReadDirFile)
|
ff, ok := f.(fs.ReadDirFile)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("failed to type-assert to fs.ReadDirFile")
|
return ErrDirListingNotSupported
|
||||||
}
|
}
|
||||||
fileinfos, err := ff.ReadDir(-1)
|
fileinfos, err := ff.ReadDir(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -70,7 +70,7 @@ func New(config ...Config) fiber.Handler {
|
||||||
subdomains = "; includeSubDomains"
|
subdomains = "; includeSubDomains"
|
||||||
}
|
}
|
||||||
if cfg.HSTSPreloadEnabled {
|
if cfg.HSTSPreloadEnabled {
|
||||||
subdomains = fmt.Sprintf("%s; preload", subdomains)
|
subdomains += "; preload"
|
||||||
}
|
}
|
||||||
c.Set(fiber.HeaderStrictTransportSecurity, fmt.Sprintf("max-age=%d%s", cfg.HSTSMaxAge, subdomains))
|
c.Set(fiber.HeaderStrictTransportSecurity, fmt.Sprintf("max-age=%d%s", cfg.HSTSMaxAge, subdomains))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package keyauth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -300,7 +299,7 @@ func TestCustomSuccessAndFailureHandlers(t *testing.T) {
|
||||||
|
|
||||||
// Create a request with a valid API key in the Authorization header
|
// Create a request with a valid API key in the Authorization header
|
||||||
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
||||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", CorrectKey))
|
req.Header.Add("Authorization", "Bearer "+CorrectKey)
|
||||||
|
|
||||||
// Send the request to the app
|
// Send the request to the app
|
||||||
res, err = app.Test(req)
|
res, err = app.Test(req)
|
||||||
|
@ -363,7 +362,7 @@ func TestCustomNextFunc(t *testing.T) {
|
||||||
|
|
||||||
// Create a request with a different path and send it to the app with correct key
|
// Create a request with a different path and send it to the app with correct key
|
||||||
req = httptest.NewRequest(fiber.MethodGet, "/not-allowed", nil)
|
req = httptest.NewRequest(fiber.MethodGet, "/not-allowed", nil)
|
||||||
req.Header.Add("Authorization", fmt.Sprintf("Basic %s", CorrectKey))
|
req.Header.Add("Authorization", "Basic "+CorrectKey)
|
||||||
|
|
||||||
res, err = app.Test(req)
|
res, err = app.Test(req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -397,7 +396,7 @@ func TestAuthSchemeToken(t *testing.T) {
|
||||||
|
|
||||||
// Create a request with a valid API key in the "Token" Authorization header
|
// Create a request with a valid API key in the "Token" Authorization header
|
||||||
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
||||||
req.Header.Add("Authorization", fmt.Sprintf("Token %s", CorrectKey))
|
req.Header.Add("Authorization", "Token "+CorrectKey)
|
||||||
|
|
||||||
// Send the request to the app
|
// Send the request to the app
|
||||||
res, err := app.Test(req)
|
res, err := app.Test(req)
|
||||||
|
@ -445,7 +444,7 @@ func TestAuthSchemeBasic(t *testing.T) {
|
||||||
|
|
||||||
// Create a request with a valid API key in the "Authorization" header using the "Basic" scheme
|
// Create a request with a valid API key in the "Authorization" header using the "Basic" scheme
|
||||||
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
req := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
||||||
req.Header.Add("Authorization", fmt.Sprintf("Basic %s", CorrectKey))
|
req.Header.Add("Authorization", "Basic "+CorrectKey)
|
||||||
|
|
||||||
// Send the request to the app
|
// Send the request to the app
|
||||||
res, err = app.Test(req)
|
res, err = app.Test(req)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
package fiber
|
package fiber
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ type RedirectConfig struct {
|
||||||
func AcquireRedirect() *Redirect {
|
func AcquireRedirect() *Redirect {
|
||||||
redirect, ok := redirectPool.Get().(*Redirect)
|
redirect, ok := redirectPool.Get().(*Redirect)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to *Redirect"))
|
panic(errors.New("failed to type-assert to *Redirect"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect
|
return redirect
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package fiber
|
package fiber
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -209,12 +210,12 @@ func (app *App) requestHandler(rctx *fasthttp.RequestCtx) {
|
||||||
if app.newCtxFunc != nil {
|
if app.newCtxFunc != nil {
|
||||||
c, ok = app.AcquireCtx().(CustomCtx)
|
c, ok = app.AcquireCtx().(CustomCtx)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to CustomCtx"))
|
panic(errors.New("failed to type-assert to CustomCtx"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c, ok = app.AcquireCtx().(*DefaultCtx)
|
c, ok = app.AcquireCtx().(*DefaultCtx)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("failed to type-assert to *DefaultCtx"))
|
panic(errors.New("failed to type-assert to *DefaultCtx"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.Reset(rctx)
|
c.Reset(rctx)
|
||||||
|
|
Loading…
Reference in New Issue