mirror of https://github.com/gofiber/fiber.git
🐛 Fix: ctx.BodyParser was not able to parse vendor specific content type (#1506)
parent
a0b1f38d3e
commit
d89207831d
2
ctx.go
2
ctx.go
|
@ -288,6 +288,8 @@ func (c *Ctx) BodyParser(out interface{}) error {
|
|||
// Get content-type
|
||||
ctype := utils.ToLower(utils.UnsafeString(c.fasthttp.Request.Header.ContentType()))
|
||||
|
||||
ctype = utils.ParseVendorSpecificContentType(ctype)
|
||||
|
||||
// Parse body accordingly
|
||||
if strings.HasPrefix(ctype, MIMEApplicationJSON) {
|
||||
schemaDecoder.SetAliasTag("json")
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package utils
|
||||
|
||||
import "strings"
|
||||
|
||||
const MIMEOctetStream = "application/octet-stream"
|
||||
|
||||
// GetMIME returns the content-type of a file extension
|
||||
|
@ -22,6 +24,32 @@ func GetMIME(extension string) (mime string) {
|
|||
return mime
|
||||
}
|
||||
|
||||
// ParseVendorSpecificContentType check if content type is vendor specific and
|
||||
// if it is parsable to any known types. If its not vendor specific then returns
|
||||
// the original content type.
|
||||
func ParseVendorSpecificContentType(cType string) string {
|
||||
plusIndex := strings.Index(cType, "+")
|
||||
|
||||
if plusIndex == -1 {
|
||||
return cType
|
||||
}
|
||||
|
||||
var parsableType string
|
||||
if semiColonIndex := strings.Index(cType, ";"); semiColonIndex == -1 {
|
||||
parsableType = cType[plusIndex+1:]
|
||||
} else {
|
||||
parsableType = cType[plusIndex+1 : semiColonIndex]
|
||||
}
|
||||
|
||||
slashIndex := strings.Index(cType, "/")
|
||||
|
||||
if slashIndex == -1 {
|
||||
return cType
|
||||
}
|
||||
|
||||
return cType[0:slashIndex+1] + parsableType
|
||||
}
|
||||
|
||||
// limits for HTTP statuscodes
|
||||
const (
|
||||
statusMessageMin = 100
|
||||
|
|
|
@ -53,6 +53,42 @@ func Benchmark_GetMIME(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func Test_ParseVendorSpecificContentType(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cType := ParseVendorSpecificContentType("application/json")
|
||||
AssertEqual(t, "application/json", cType)
|
||||
|
||||
cType = ParseVendorSpecificContentType("application/vnd.api+json; version=1")
|
||||
AssertEqual(t, "application/json", cType)
|
||||
|
||||
cType = ParseVendorSpecificContentType("application/vnd.api+json")
|
||||
AssertEqual(t, "application/json", cType)
|
||||
|
||||
cType = ParseVendorSpecificContentType("application/vnd.dummy+x-www-form-urlencoded")
|
||||
AssertEqual(t, "application/x-www-form-urlencoded", cType)
|
||||
|
||||
cType = ParseVendorSpecificContentType("something invalid")
|
||||
AssertEqual(t, "something invalid", cType)
|
||||
}
|
||||
|
||||
func Benchmark_ParseVendorSpecificContentType(b *testing.B) {
|
||||
var cType string
|
||||
b.Run("vendorContentType", func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
cType = ParseVendorSpecificContentType("application/vnd.api+json; version=1")
|
||||
}
|
||||
AssertEqual(b, "application/json", cType)
|
||||
})
|
||||
|
||||
b.Run("defaultContentType", func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
cType = ParseVendorSpecificContentType("application/json")
|
||||
}
|
||||
AssertEqual(b, "application/json", cType)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_StatusMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
res := StatusMessage(204)
|
||||
|
|
Loading…
Reference in New Issue