Skip to content

Commit

Permalink
🐛 Fix: ctx.BodyParser was not able to parse vendor specific content t…
Browse files Browse the repository at this point in the history
…ype (#1506)
  • Loading branch information
shirshendubhowmick committed Aug 22, 2021
1 parent a0b1f38 commit d892078
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
28 changes: 28 additions & 0 deletions utils/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package utils

import "strings"

const MIMEOctetStream = "application/octet-stream"

// GetMIME returns the content-type of a file extension
Expand All @@ -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
Expand Down
36 changes: 36 additions & 0 deletions utils/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit d892078

Please sign in to comment.