Updated content-type parsing to respect wildcards.

This commit is contained in:
Chris Jones 2018-09-08 13:40:49 -06:00
parent 500ebd9ea8
commit c22d088aad
3 changed files with 41 additions and 7 deletions

View File

@ -893,7 +893,7 @@ func (c *Context) NegotiateFormat(offered ...string) string {
}
for _, accepted := range c.Accepted {
for _, offert := range offered {
if accepted == offert {
if contentMatches(accepted, offert) {
return offert
}
}

View File

@ -1122,13 +1122,27 @@ func TestContextNegotiationFormat(t *testing.T) {
}
func TestContextNegotiationFormatWithAccept(t *testing.T) {
typicalAccept := "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
testCases := []struct {
accept string
offer []string
expect string
}{
{"*/*", []string{MIMEJSON}, MIMEJSON},
{"", []string{MIMEJSON, MIMEXML}, MIMEJSON},
{MIMEJSON, []string{MIMEXML}, ""},
{MIMEJSON, []string{MIMEXML, MIMEJSON, MIMEHTML}, MIMEJSON},
{typicalAccept, []string{MIMEJSON, MIMEXML}, MIMEXML},
{typicalAccept, []string{MIMEXML, MIMEHTML}, MIMEHTML},
{typicalAccept, []string{MIMEJSON}, MIMEJSON},
}
for i, tc := range testCases {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
assert.Equal(t, MIMEXML, c.NegotiateFormat(MIMEJSON, MIMEXML))
assert.Equal(t, MIMEHTML, c.NegotiateFormat(MIMEXML, MIMEHTML))
assert.Empty(t, c.NegotiateFormat(MIMEJSON))
c.Request.Header.Add("Accept", tc.accept)
assert.Equal(t, tc.expect, c.NegotiateFormat(tc.offer...), fmt.Sprintf("test case %d", i))
}
}
func TestContextNegotiationFormatCustum(t *testing.T) {

View File

@ -110,6 +110,26 @@ func parseAccept(acceptHeader string) []string {
return out
}
// contentMatches returns true if content matches the pattern.
// See RFC2616, section 14.1.
func contentMatches(pattern, content string) bool {
patternParts := strings.SplitN(pattern, "/", 2)
contentParts := strings.SplitN(content, "/", 2)
if patternParts[0] == "*" {
return true
}
if patternParts[0] != contentParts[0] {
return false
}
if patternParts[1] == "*" {
return true
}
if patternParts[1] != contentParts[1] {
return false
}
return true
}
func lastChar(str string) uint8 {
if str == "" {
panic("The length of the string can't be 0")