mirror of https://github.com/k3s-io/k3s
Fix Content negotiation incorrect when Accept header uses type parameters
parent
2c9ffc0e88
commit
66c2ec32f2
|
@ -273,6 +273,13 @@ func acceptMediaTypeOptions(params map[string]string, accepts *AcceptedMediaType
|
|||
return options, true
|
||||
}
|
||||
|
||||
type candidateMediaType struct {
|
||||
accepted *AcceptedMediaType
|
||||
clauses goautoneg.Accept
|
||||
}
|
||||
|
||||
type candidateMediaTypeSlice []candidateMediaType
|
||||
|
||||
// NegotiateMediaTypeOptions returns the most appropriate content type given the accept header and
|
||||
// a list of alternatives along with the accepted media type parameters.
|
||||
func NegotiateMediaTypeOptions(header string, accepted []AcceptedMediaType, endpoint EndpointRestrictions) (MediaTypeOptions, bool) {
|
||||
|
@ -282,6 +289,7 @@ func NegotiateMediaTypeOptions(header string, accepted []AcceptedMediaType, endp
|
|||
}, true
|
||||
}
|
||||
|
||||
var candidates candidateMediaTypeSlice
|
||||
clauses := goautoneg.ParseAccept(header)
|
||||
for _, clause := range clauses {
|
||||
for i := range accepted {
|
||||
|
@ -290,12 +298,17 @@ func NegotiateMediaTypeOptions(header string, accepted []AcceptedMediaType, endp
|
|||
case clause.Type == accepts.Type && clause.SubType == accepts.SubType,
|
||||
clause.Type == accepts.Type && clause.SubType == "*",
|
||||
clause.Type == "*" && clause.SubType == "*":
|
||||
// TODO: should we prefer the first type with no unrecognized options? Do we need to ignore unrecognized
|
||||
// parameters.
|
||||
return acceptMediaTypeOptions(clause.Params, accepts, endpoint)
|
||||
candidates = append(candidates, candidateMediaType{accepted: accepts, clauses: clause})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range candidates {
|
||||
if retVal, ret := acceptMediaTypeOptions(v.clauses.Params, v.accepted, endpoint); ret {
|
||||
return retVal, true
|
||||
}
|
||||
}
|
||||
|
||||
return MediaTypeOptions{}, false
|
||||
}
|
||||
|
||||
|
|
|
@ -181,7 +181,26 @@ func TestNegotiate(t *testing.T) {
|
|||
serializer: fakeCodec,
|
||||
params: map[string]string{"pretty": "1"},
|
||||
},
|
||||
|
||||
{
|
||||
req: &http.Request{
|
||||
Header: http.Header{
|
||||
"Accept": []string{"application/json;as=BOGUS;v=v1alpha1;g=meta.k8s.io, application/json"},
|
||||
},
|
||||
},
|
||||
contentType: "application/json",
|
||||
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
|
||||
serializer: fakeCodec,
|
||||
},
|
||||
{
|
||||
req: &http.Request{
|
||||
Header: http.Header{
|
||||
"Accept": []string{"application/BOGUS, application/json"},
|
||||
},
|
||||
},
|
||||
contentType: "application/json",
|
||||
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
|
||||
serializer: fakeCodec,
|
||||
},
|
||||
// "application" is not a valid media type, so the server will reject the response during
|
||||
// negotiation (the server, in error, has specified an invalid media type)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue