Skip to content

Commit

Permalink
Merge branch 'main' into v3-params
Browse files Browse the repository at this point in the history
  • Loading branch information
dozheiny committed Mar 17, 2024
2 parents 1403ded + 5449b04 commit 2f44dc1
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 85 deletions.
274 changes: 212 additions & 62 deletions .golangci.yml

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions binder/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,24 @@ func equalFieldType(out any, kind reflect.Kind, key string) bool {
structFieldKind := structField.Kind()
// Does the field type equals input?
if structFieldKind != kind {
// Is the field an embedded struct?
if structFieldKind == reflect.Struct {
// Loop over embedded struct fields
for j := 0; j < structField.NumField(); j++ {
structFieldField := structField.Field(j)

// Can this embedded field be changed?
if !structFieldField.CanSet() {
continue
}

// Is the embedded struct field type equal to the input?
if structFieldField.Kind() == kind {
return true
}
}
}

continue
}
// Get tag from field if exist
Expand Down
19 changes: 13 additions & 6 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1359,7 +1359,12 @@ func Test_Ctx_Parsers(t *testing.T) {
// setup
app := New()

type TestEmbeddedStruct struct {
Names []string `query:"names"`
}

type TestStruct struct {
TestEmbeddedStruct
Name string
Class int
NameWithDefault string `json:"name2" xml:"Name2" form:"name2" cookie:"name2" query:"name2" params:"name2" header:"Name2"`
Expand All @@ -1378,36 +1383,37 @@ func Test_Ctx_Parsers(t *testing.T) {
require.Equal(t, 111, testStruct.Class)
require.Equal(t, "bar", testStruct.NameWithDefault)
require.Equal(t, 222, testStruct.ClassWithDefault)
require.Equal(t, []string{"foo", "bar", "test"}, testStruct.TestEmbeddedStruct.Names)
}

t.Run("BodyParser:xml", func(t *testing.T) {
t.Parallel()
withValues(t, func(c Ctx, testStruct *TestStruct) error {
c.Request().Header.SetContentType(MIMEApplicationXML)
c.Request().SetBody([]byte(`<TestStruct><Name>foo</Name><Class>111</Class><Name2>bar</Name2><Class2>222</Class2></TestStruct>`))
c.Request().SetBody([]byte(`<TestStruct><Name>foo</Name><Class>111</Class><Name2>bar</Name2><Class2>222</Class2><Names>foo</Names><Names>bar</Names><Names>test</Names></TestStruct>`))
return c.Bind().Body(testStruct)
})
})
t.Run("BodyParser:form", func(t *testing.T) {
t.Parallel()
withValues(t, func(c Ctx, testStruct *TestStruct) error {
c.Request().Header.SetContentType(MIMEApplicationForm)
c.Request().SetBody([]byte(`name=foo&class=111&name2=bar&class2=222`))
c.Request().SetBody([]byte(`name=foo&class=111&name2=bar&class2=222&names=foo,bar,test`))
return c.Bind().Body(testStruct)
})
})
t.Run("BodyParser:json", func(t *testing.T) {
t.Parallel()
withValues(t, func(c Ctx, testStruct *TestStruct) error {
c.Request().Header.SetContentType(MIMEApplicationJSON)
c.Request().SetBody([]byte(`{"name":"foo","class":111,"name2":"bar","class2":222}`))
c.Request().SetBody([]byte(`{"name":"foo","class":111,"name2":"bar","class2":222,"names":["foo","bar","test"]}`))
return c.Bind().Body(testStruct)
})
})
t.Run("BodyParser:multiform", func(t *testing.T) {
t.Parallel()
withValues(t, func(c Ctx, testStruct *TestStruct) error {
body := []byte("--b\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nfoo\r\n--b\r\nContent-Disposition: form-data; name=\"class\"\r\n\r\n111\r\n--b\r\nContent-Disposition: form-data; name=\"name2\"\r\n\r\nbar\r\n--b\r\nContent-Disposition: form-data; name=\"class2\"\r\n\r\n222\r\n--b--")
body := []byte("--b\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nfoo\r\n--b\r\nContent-Disposition: form-data; name=\"class\"\r\n\r\n111\r\n--b\r\nContent-Disposition: form-data; name=\"name2\"\r\n\r\nbar\r\n--b\r\nContent-Disposition: form-data; name=\"class2\"\r\n\r\n222\r\n--b\r\nContent-Disposition: form-data; name=\"names\"\r\n\r\nfoo\r\n--b\r\nContent-Disposition: form-data; name=\"names\"\r\n\r\nbar\r\n--b\r\nContent-Disposition: form-data; name=\"names\"\r\n\r\ntest\r\n--b--")
c.Request().SetBody(body)
c.Request().Header.SetContentType(MIMEMultipartForm + `;boundary="b"`)
c.Request().Header.SetContentLength(len(body))
Expand All @@ -1417,14 +1423,14 @@ func Test_Ctx_Parsers(t *testing.T) {
t.Run("CookieParser", func(t *testing.T) {
t.Parallel()
withValues(t, func(c Ctx, testStruct *TestStruct) error {
c.Request().Header.Set("Cookie", "name=foo;name2=bar;class=111;class2=222")
c.Request().Header.Set("Cookie", "name=foo;name2=bar;class=111;class2=222;names=foo,bar,test")
return c.Bind().Cookie(testStruct)
})
})
t.Run("QueryParser", func(t *testing.T) {
t.Parallel()
withValues(t, func(c Ctx, testStruct *TestStruct) error {
c.Request().URI().SetQueryString("name=foo&name2=bar&class=111&class2=222")
c.Request().URI().SetQueryString("name=foo&name2=bar&class=111&class2=222&names=foo,bar,test")
return c.Bind().Query(testStruct)
})
})
Expand All @@ -1444,6 +1450,7 @@ func Test_Ctx_Parsers(t *testing.T) {
c.Request().Header.Add("name2", "bar")
c.Request().Header.Add("class", "111")
c.Request().Header.Add("class2", "222")
c.Request().Header.Add("names", "foo,bar,test")
return c.Bind().Header(testStruct)
})
})
Expand Down
2 changes: 1 addition & 1 deletion listen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"errors"
"fmt"
"io"
"log"
"log" //nolint:depguard // TODO: Required to capture output, use internal log package instead
"net"
"os"
"strings"
Expand Down
5 changes: 2 additions & 3 deletions middleware/cors/cors.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,10 @@ func New(config ...Config) fiber.Handler {
trimmedOrigin := strings.TrimSpace(origin)
isValid, normalizedOrigin := normalizeOrigin(trimmedOrigin)

if isValid {
allowOrigins[i] = normalizedOrigin
} else {
if !isValid {
log.Panicf("[CORS] Invalid origin format in configuration: %s", trimmedOrigin) //nolint:revive // we want to exit the program
}
allowOrigins[i] = normalizedOrigin
}
} else {
// If AllowOrigins is set to a wildcard or not set,
Expand Down
7 changes: 2 additions & 5 deletions middleware/idempotency/idempotency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,8 @@ func Test_Idempotency(t *testing.T) {
if !isIdempotent {
return errors.New("request with unsafe HTTP method should be idempotent if X-Idempotency-Key request header is set")
}
} else {
// No request header
if isIdempotent {
return errors.New("request with unsafe HTTP method should not be idempotent if X-Idempotency-Key request header is not set")
}
} else if isIdempotent {
return errors.New("request with unsafe HTTP method should not be idempotent if X-Idempotency-Key request header is not set")
}
}

Expand Down
2 changes: 1 addition & 1 deletion middleware/session/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (s *Store) Get(c fiber.Ctx) (*Session, error) {
if raw != nil && err == nil {
mux.Lock()
defer mux.Unlock()
sess.byteBuffer.Write(raw)
_, _ = sess.byteBuffer.Write(raw) // Ignore error, this will never fail
encCache := gob.NewDecoder(sess.byteBuffer)
err := encCache.Decode(&sess.data.Data)
if err != nil {
Expand Down
7 changes: 4 additions & 3 deletions path.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,11 +591,12 @@ func findGreedyParamLen(s string, searchCount int, segment *routeSegment) int {
// check all from right to left segments
for i := segment.PartCount; i > 0 && searchCount > 0; i-- {
searchCount--
if constPosition := strings.LastIndex(s, segment.ComparePart); constPosition != -1 {
s = s[:constPosition]
} else {

constPosition := strings.LastIndex(s, segment.ComparePart)
if constPosition == -1 {
break
}
s = s[:constPosition]
}

return len(s)
Expand Down
7 changes: 3 additions & 4 deletions redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,12 @@ func (r *Redirect) setFlash() {
var commaPos int
for {
commaPos = findNextNonEscapedCharsetPosition(cookieValue, []byte(CookieDataSeparator))
if commaPos != -1 {
r.c.redirectionMessages = append(r.c.redirectionMessages, strings.Trim(cookieValue[:commaPos], " "))
cookieValue = cookieValue[commaPos+1:]
} else {
if commaPos == -1 {
r.c.redirectionMessages = append(r.c.redirectionMessages, strings.Trim(cookieValue, " "))
break
}
r.c.redirectionMessages = append(r.c.redirectionMessages, strings.Trim(cookieValue[:commaPos], " "))
cookieValue = cookieValue[commaPos+1:]
}

r.c.ClearCookie(FlashCookieName)
Expand Down

0 comments on commit 2f44dc1

Please sign in to comment.