Optimize NegotiateMediaTypeOptions

This commit is contained in:
Wojciech Tyczynski 2019-10-10 11:49:31 +02:00
parent 053721d9d5
commit 1baf4778ae
2 changed files with 32 additions and 16 deletions

View File

@ -234,13 +234,6 @@ func acceptMediaTypeOptions(params map[string]string, accepts *runtime.Serialize
return options, true
}
type candidateMediaType struct {
accepted *runtime.SerializerInfo
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 []runtime.SerializerInfo, endpoint EndpointRestrictions) (MediaTypeOptions, bool) {
@ -250,25 +243,21 @@ func NegotiateMediaTypeOptions(header string, accepted []runtime.SerializerInfo,
}, true
}
var candidates candidateMediaTypeSlice
clauses := goautoneg.ParseAccept(header)
for _, clause := range clauses {
for i := range clauses {
clause := &clauses[i]
for i := range accepted {
accepts := &accepted[i]
switch {
case clause.Type == accepts.MediaTypeType && clause.SubType == accepts.MediaTypeSubType,
clause.Type == accepts.MediaTypeType && clause.SubType == "*",
clause.Type == "*" && clause.SubType == "*":
candidates = append(candidates, candidateMediaType{accepted: accepts, clauses: clause})
if retVal, ret := acceptMediaTypeOptions(clause.Params, accepts, endpoint); ret {
return retVal, true
}
}
}
}
for _, v := range candidates {
if retVal, ret := acceptMediaTypeOptions(v.clauses.Params, v.accepted, endpoint); ret {
return retVal, true
}
}
return MediaTypeOptions{}, false
}

View File

@ -280,3 +280,30 @@ func TestNegotiate(t *testing.T) {
}
}
}
func fakeSerializerInfoSlice() []runtime.SerializerInfo {
result := make([]runtime.SerializerInfo, 2)
result[0] = runtime.SerializerInfo{
MediaType: "application/json",
MediaTypeType: "application",
MediaTypeSubType: "json",
}
result[1] = runtime.SerializerInfo{
MediaType: "application/vnd.kubernetes.protobuf",
MediaTypeType: "application",
MediaTypeSubType: "vnd.kubernetes.protobuf",
}
return result
}
func BenchmarkNegotiateMediaTypeOptions(b *testing.B) {
accepted := fakeSerializerInfoSlice()
header := "application/vnd.kubernetes.protobuf,*/*"
for i := 0; i < b.N; i++ {
options, _ := NegotiateMediaTypeOptions(header, accepted, DefaultEndpointRestrictions)
if options.Accepted != accepted[1] {
b.Errorf("Unexpected result")
}
}
}