golang / gddo

Go Doc Dot Org
https://godoc.org
BSD 3-Clause "New" or "Revised" License
1.1k stars 265 forks source link

NegotiateContentType treats `Accept: */*` differently than no Accept header #643

Open flimzy opened 5 years ago

flimzy commented 5 years ago

I'm not 100% sure this is a bug, but intuitively, it doesn't make sense to me.

Consider this code:

package main

import (
    "fmt"
    "net/http/httptest"
    "github.com/golang/gddo/httputil"
)

func main() {
    r1 := httptest.NewRequest("GET", "/", nil)
    r2 := httptest.NewRequest("GET", "/", nil)
    r2.Header.Set("Accept", "*/*")
    ct1 := httputil.NegotiateContentType(r1, []string{"text/plain", "application/json"}, "application/json")
    ct2 := httputil.NegotiateContentType(r2, []string{"text/plain", "application/json"}, "application/json")
    fmt.Println(ct1)
    fmt.Println(ct2)
}

And it's respective output:

application/json
text/plain

Intuitively, I would expect these results to be the same.

RFC 7231 doesn't appear to weigh in explicitly on this issue, but does seem to imply that the two should be treated as equivalent (emphasis added):

The asterisk "" character is used to group media types into ranges, with "/*" indicating all media types ... A request without any Accept header field implies that the user agent will accept any media type in response.

Although maybe there are valid reasons not to consider them the same.