Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions bind.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fiber

import (
"errors"
"reflect"
"slices"
"sync"
Expand Down Expand Up @@ -41,7 +40,7 @@ type Bind struct {
func AcquireBind() *Bind {
b, ok := bindPool.Get().(*Bind)
if !ok {
panic(errors.New("failed to type-assert to *Bind"))
panic(errBindPoolTypeAssertion)
}

return b
Expand Down
6 changes: 5 additions & 1 deletion binder/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ var (
ErrSuitableContentNotFound = errors.New("binder: suitable content not found to parse body")
ErrMapNotConvertible = errors.New("binder: map is not convertible to map[string]string or map[string][]string")
ErrMapNilDestination = errors.New("binder: map destination is nil and cannot be initialized")
ErrInvalidDestinationValue = errors.New("binder: invalid destination value")
ErrUnmatchedBrackets = errors.New("unmatched brackets")
)

var errPoolTypeAssertion = errors.New("failed to type-assert to T")

var HeaderBinderPool = sync.Pool{
New: func() any {
return &HeaderBinding{}
Expand Down Expand Up @@ -77,7 +81,7 @@ var MsgPackBinderPool = sync.Pool{
func GetFromThePool[T any](pool *sync.Pool) T {
binder, ok := pool.Get().(T)
if !ok {
panic(errors.New("failed to type-assert to T"))
panic(errPoolTypeAssertion)
}

return binder
Expand Down
7 changes: 3 additions & 4 deletions binder/mapping.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package binder

import (
"errors"
"fmt"
"maps"
"mime/multipart"
Expand Down Expand Up @@ -108,7 +107,7 @@ func parseToStruct(aliasTag string, out any, data map[string][]string, files ...
// thanks to https://github.com/gin-gonic/gin/blob/master/binding/binding.go
func parseToMap(target reflect.Value, data map[string][]string) error {
if !target.IsValid() {
return errors.New("binder: invalid destination value")
return ErrInvalidDestinationValue
}

if target.Kind() == reflect.Interface && !target.IsNil() {
Expand Down Expand Up @@ -179,7 +178,7 @@ func parseParamSquareBrackets(k string) (string, error) {
if b == ']' {
openBracketsCount--
if openBracketsCount < 0 {
return "", errors.New("unmatched brackets")
return "", ErrUnmatchedBrackets
}
continue
}
Expand All @@ -190,7 +189,7 @@ func parseParamSquareBrackets(k string) (string, error) {
}

if openBracketsCount > 0 {
return "", errors.New("unmatched brackets")
return "", ErrUnmatchedBrackets
}

return bb.String(), nil
Expand Down
10 changes: 4 additions & 6 deletions binder/mapping_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package binder

import (
"errors"
"mime/multipart"
"reflect"
"strconv"
Expand Down Expand Up @@ -91,17 +90,17 @@ func Test_ParseParamSquareBrackets(t *testing.T) {
expected: "foo.bar.baz",
},
{
err: errors.New("unmatched brackets"),
err: ErrUnmatchedBrackets,
input: "foo[bar",
expected: "",
},
{
err: errors.New("unmatched brackets"),
err: ErrUnmatchedBrackets,
input: "foo[bar][baz",
expected: "",
},
{
err: errors.New("unmatched brackets"),
err: ErrUnmatchedBrackets,
input: "foo]bar[",
expected: "",
},
Expand Down Expand Up @@ -133,8 +132,7 @@ func Test_ParseParamSquareBrackets(t *testing.T) {

result, err := parseParamSquareBrackets(tt.input)
if tt.err != nil {
require.Error(t, err)
require.EqualError(t, err, tt.err.Error())
require.ErrorIs(t, err, tt.err)
} else {
require.NoError(t, err)
require.Equal(t, tt.expected, result)
Expand Down
3 changes: 1 addition & 2 deletions client/cookiejar.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package client

import (
"bytes"
"errors"
"net"
"strings"
"sync"
Expand All @@ -23,7 +22,7 @@ var cookieJarPool = sync.Pool{
func AcquireCookieJar() *CookieJar {
jar, ok := cookieJarPool.Get().(*CookieJar)
if !ok {
panic(errors.New("failed to type-assert to *CookieJar"))
panic(errCookieJarTypeAssertion)
}

return jar
Expand Down
4 changes: 2 additions & 2 deletions client/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ var responseChanPool = &sync.Pool{
func acquireResponseChan() chan *Response {
ch, ok := responseChanPool.Get().(chan *Response)
if !ok {
panic(errors.New("failed to type-assert to *Response"))
panic(errResponseChanTypeAssertion)
}
return ch
}
Expand All @@ -258,7 +258,7 @@ var errChanPool = &sync.Pool{
func acquireErrChan() chan error {
ch, ok := errChanPool.Get().(chan error)
if !ok {
panic(errors.New("failed to type-assert to chan error"))
panic(errChanErrorTypeAssertion)
}
return ch
}
Expand Down
14 changes: 14 additions & 0 deletions client/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package client

import (
"errors"
)

var (
errResponseChanTypeAssertion = errors.New("failed to type-assert to *Response")
errChanErrorTypeAssertion = errors.New("failed to type-assert to chan error")
errRequestTypeAssertion = errors.New("failed to type-assert to *Request")
errFileTypeAssertion = errors.New("failed to type-assert to *File")
errCookieJarTypeAssertion = errors.New("failed to type-assert to *CookieJar")
errSyncPoolBuffer = errors.New("failed to retrieve buffer from a sync.Pool")
)
3 changes: 1 addition & 2 deletions client/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package client

import (
"crypto/rand"
"errors"
"fmt"
"io"
"mime/multipart"
Expand Down Expand Up @@ -265,7 +264,7 @@ func parserRequestBodyFile(req *Request) error {
// Add files.
fileBuf, ok := fileBufPool.Get().(*[]byte)
if !ok {
return errors.New("failed to retrieve buffer from a sync.Pool")
return errSyncPoolBuffer
}

defer fileBufPool.Put(fileBuf)
Expand Down
4 changes: 2 additions & 2 deletions client/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ var requestPool = &sync.Pool{
func AcquireRequest() *Request {
req, ok := requestPool.Get().(*Request)
if !ok {
panic(errors.New("failed to type-assert to *Request"))
panic(errRequestTypeAssertion)
}
return req
}
Expand Down Expand Up @@ -1034,7 +1034,7 @@ func AcquireFile(setter ...SetFileFunc) *File {
if fv != nil {
f, ok := fv.(*File)
if !ok {
panic(errors.New("failed to type-assert to *File"))
panic(errFileTypeAssertion)
}
for _, v := range setter {
v(f)
Expand Down
4 changes: 1 addition & 3 deletions ctx_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
package fiber

import (
"errors"

"github.com/valyala/fasthttp"
)

Expand Down Expand Up @@ -53,7 +51,7 @@ func (app *App) AcquireCtx(fctx *fasthttp.RequestCtx) CustomCtx {
ctx, ok := app.pool.Get().(CustomCtx)

if !ok {
panic(errors.New("failed to type-assert to CustomCtx"))
panic(errCustomCtxTypeAssertion)
}

if app.hasCustomCtx {
Expand Down
3 changes: 2 additions & 1 deletion ctx_interface_gen.go

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

14 changes: 14 additions & 0 deletions errors_internal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package fiber

import (
"errors"
)

var (
errBindPoolTypeAssertion = errors.New("failed to type-assert to *Bind")
errCustomCtxTypeAssertion = errors.New("failed to type-assert to CustomCtx")
errTLSConfigTypeAssertion = errors.New("failed to type-assert to *tls.Config")
errInvalidEscapeSequence = errors.New("invalid escape sequence")
errTCPAddrTypeAssertion = errors.New("failed to type-assert to *net.TCPAddr")
errRedirectTypeAssertion = errors.New("failed to type-assert to *Redirect")
)
6 changes: 3 additions & 3 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func getTLSConfig(ln net.Listener) *tls.Config {
// Cast value to *tls.Config
c, ok := reflect.TypeAssert[*tls.Config](elem)
if !ok {
panic(errors.New("failed to type-assert to *tls.Config"))
panic(errTLSConfigTypeAssertion)
}
return c
}
Expand Down Expand Up @@ -402,15 +402,15 @@ func unescapeHeaderValue(v []byte) ([]byte, error) {
if c == '\\' {
// invalid escape at end of string
if i == len(v)-1 {
return nil, errors.New("invalid escape sequence")
return nil, errInvalidEscapeSequence
}
escaping = true
continue
}
res = append(res, c)
}
if escaping {
return nil, errors.New("invalid escape sequence")
return nil, errInvalidEscapeSequence
}
return res, nil
}
Expand Down
4 changes: 3 additions & 1 deletion internal/tlstest/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"time"
)

var errAppendCACert = errors.New("failed to append CA certificate to certificate pool")

// GetTLSConfigs generates TLS configurations for a test server and client that
// trust each other using an in-memory certificate authority.
func GetTLSConfigs() (serverTLSConf, clientTLSConf *tls.Config, err error) { //nolint:nonamedreturns // gocritic unnamedResult prefers naming server and client TLS configurations along with the error
Expand Down Expand Up @@ -123,7 +125,7 @@ func GetTLSConfigs() (serverTLSConf, clientTLSConf *tls.Config, err error) { //n

certPool := x509.NewCertPool()
if ok := certPool.AppendCertsFromPEM(caPEM.Bytes()); !ok {
return nil, nil, errors.New("append CA cert to cert pool")
return nil, nil, errAppendCACert
}
clientTLSConf = &tls.Config{
RootCAs: certPool,
Expand Down
9 changes: 7 additions & 2 deletions middleware/adaptor/adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ var bufferPool = sync.Pool{
},
}

var (
ErrRemoteAddrEmpty = errors.New("remote address cannot be empty")
ErrRemoteAddrTooLong = errors.New("remote address too long")
)

// HTTPHandlerFunc wraps net/http handler func to fiber handler
func HTTPHandlerFunc(h http.HandlerFunc) fiber.Handler {
return HTTPHandler(h)
Expand Down Expand Up @@ -178,7 +183,7 @@ func resolveRemoteAddr(remoteAddr string, localAddr any) (net.Addr, error) {

// Validate input to prevent malformed addresses
if remoteAddr == "" {
return nil, errors.New("remote address cannot be empty")
return nil, ErrRemoteAddrEmpty
}

resolved, err := net.ResolveTCPAddr("tcp", remoteAddr)
Expand All @@ -189,7 +194,7 @@ func resolveRemoteAddr(remoteAddr string, localAddr any) (net.Addr, error) {
var addrErr *net.AddrError
if errors.As(err, &addrErr) && addrErr.Err == "missing port in address" {
if len(remoteAddr) > 253 { // Max hostname length
return nil, errors.New("remote address too long")
return nil, ErrRemoteAddrTooLong
}
remoteAddr = net.JoinHostPort(remoteAddr, "80")
resolved, err2 := net.ResolveTCPAddr("tcp", remoteAddr)
Expand Down
18 changes: 12 additions & 6 deletions middleware/adaptor/adaptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,7 @@ func Test_resolveRemoteAddr(t *testing.T) {
t.Parallel()

tests := []struct {
expectedErr error
localAddr any
name string
remoteAddr string
Expand Down Expand Up @@ -1164,13 +1165,14 @@ func Test_resolveRemoteAddr(t *testing.T) {
remoteAddr: "",
localAddr: nil,
expectError: true,
expectedErr: ErrRemoteAddrEmpty,
},
{
name: "too long address - should fail",
remoteAddr: strings.Repeat("a", 254),
localAddr: nil,
expectError: true,
errorContains: "remote address too long",
name: "too long address - should fail",
remoteAddr: strings.Repeat("a", 254),
localAddr: nil,
expectError: true,
expectedErr: ErrRemoteAddrTooLong,
},
}

Expand All @@ -1179,8 +1181,12 @@ func Test_resolveRemoteAddr(t *testing.T) {
t.Parallel()
addr, err := resolveRemoteAddr(tt.remoteAddr, tt.localAddr)

if tt.expectError {
expectError := tt.expectedErr != nil || tt.errorContains != ""
if expectError {
require.Error(t, err)
if tt.expectedErr != nil {
require.ErrorIs(t, err, tt.expectedErr)
}
if tt.errorContains != "" {
require.Contains(t, err.Error(), tt.errorContains)
}
Expand Down
4 changes: 3 additions & 1 deletion middleware/basicauth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"golang.org/x/crypto/bcrypt"
)

var ErrInvalidSHA256PasswordLength = errors.New("decode SHA256 password: invalid length")

// Config defines the config for middleware.
type Config struct {
// Next defines a function to skip this middleware when returned true.
Expand Down Expand Up @@ -188,7 +190,7 @@ func parseHashedPassword(h string) (func(string) bool, error) {
return nil, fmt.Errorf("decode SHA256 password: %w", err)
}
if len(b) != sha256.Size {
return nil, errors.New("decode SHA256 password: invalid length")
return nil, ErrInvalidSHA256PasswordLength
}
}
return func(p string) bool {
Expand Down
11 changes: 11 additions & 0 deletions middleware/encryptcookie/encryptcookie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ func Test_Middleware_InvalidBase64(t *testing.T) {
})
}

func Test_DecryptCookie_InvalidEncryptedValue(t *testing.T) {
t.Parallel()

key := GenerateKey(32)
// the decoded value is shorter than the GCM nonce size, so decryption should fail immediately
shortValue := base64.StdEncoding.EncodeToString([]byte("short"))

_, err := DecryptCookie("session", shortValue, key)
require.ErrorIs(t, err, ErrInvalidEncryptedValue)
}

func Test_Middleware_EncryptionErrorPropagates(t *testing.T) {
t.Parallel()

Expand Down
Loading
Loading