mirror of https://github.com/gofiber/fiber.git
🩹 Fix: sorting error in sortAcceptedTypes (#3331)
* 🩹 Fix: correct sorting error in sortAcceptedTypes. * ♻️ Refactor: remove redundant branch --------- Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com>pull/3335/head^2
parent
86cf80630b
commit
6afba957f1
11
helpers.go
11
helpers.go
|
@ -483,7 +483,7 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head
|
|||
|
||||
if len(acceptedTypes) > 1 {
|
||||
// Sort accepted types by quality and specificity, preserving order of equal elements
|
||||
sortAcceptedTypes(&acceptedTypes)
|
||||
sortAcceptedTypes(acceptedTypes)
|
||||
}
|
||||
|
||||
// Find the first offer that matches the accepted types
|
||||
|
@ -511,19 +511,14 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head
|
|||
// A type with parameters has higher priority than an equivalent one without parameters.
|
||||
// e.g., text/html;a=1;b=2 comes before text/html;a=1
|
||||
// See: https://www.rfc-editor.org/rfc/rfc9110#name-content-negotiation-fields
|
||||
func sortAcceptedTypes(acceptedTypes *[]acceptedType) {
|
||||
if acceptedTypes == nil || len(*acceptedTypes) < 2 {
|
||||
return
|
||||
}
|
||||
at := *acceptedTypes
|
||||
|
||||
func sortAcceptedTypes(at []acceptedType) {
|
||||
for i := 1; i < len(at); i++ {
|
||||
lo, hi := 0, i-1
|
||||
for lo <= hi {
|
||||
mid := (lo + hi) / 2
|
||||
if at[i].quality < at[mid].quality ||
|
||||
(at[i].quality == at[mid].quality && at[i].specificity < at[mid].specificity) ||
|
||||
(at[i].quality == at[mid].quality && at[i].specificity < at[mid].specificity && len(at[i].params) < len(at[mid].params)) ||
|
||||
(at[i].quality == at[mid].quality && at[i].specificity == at[mid].specificity && len(at[i].params) < len(at[mid].params)) ||
|
||||
(at[i].quality == at[mid].quality && at[i].specificity == at[mid].specificity && len(at[i].params) == len(at[mid].params) && at[i].order > at[mid].order) {
|
||||
lo = mid + 1
|
||||
} else {
|
||||
|
|
|
@ -354,7 +354,6 @@ func Test_Utils_SortAcceptedTypes(t *testing.T) {
|
|||
{spec: "text/html", quality: 1, specificity: 3, order: 0},
|
||||
{spec: "text/*", quality: 0.5, specificity: 2, order: 1},
|
||||
{spec: "*/*", quality: 0.1, specificity: 1, order: 2},
|
||||
{spec: "application/json", quality: 0.999, specificity: 3, order: 3},
|
||||
{spec: "application/xml", quality: 1, specificity: 3, order: 4},
|
||||
{spec: "application/pdf", quality: 1, specificity: 3, order: 5},
|
||||
{spec: "image/png", quality: 1, specificity: 3, order: 6},
|
||||
|
@ -363,8 +362,9 @@ func Test_Utils_SortAcceptedTypes(t *testing.T) {
|
|||
{spec: "image/gif", quality: 1, specificity: 3, order: 9},
|
||||
{spec: "text/plain", quality: 1, specificity: 3, order: 10},
|
||||
{spec: "application/json", quality: 0.999, specificity: 3, params: headerParams{"a": []byte("1")}, order: 11},
|
||||
{spec: "application/json", quality: 0.999, specificity: 3, order: 3},
|
||||
}
|
||||
sortAcceptedTypes(&acceptedTypes)
|
||||
sortAcceptedTypes(acceptedTypes)
|
||||
require.Equal(t, []acceptedType{
|
||||
{spec: "text/html", quality: 1, specificity: 3, order: 0},
|
||||
{spec: "application/xml", quality: 1, specificity: 3, order: 4},
|
||||
|
@ -390,7 +390,7 @@ func Benchmark_Utils_SortAcceptedTypes_Sorted(b *testing.B) {
|
|||
acceptedTypes[0] = acceptedType{spec: "text/html", quality: 1, specificity: 1, order: 0}
|
||||
acceptedTypes[1] = acceptedType{spec: "text/*", quality: 0.5, specificity: 1, order: 1}
|
||||
acceptedTypes[2] = acceptedType{spec: "*/*", quality: 0.1, specificity: 1, order: 2}
|
||||
sortAcceptedTypes(&acceptedTypes)
|
||||
sortAcceptedTypes(acceptedTypes)
|
||||
}
|
||||
require.Equal(b, "text/html", acceptedTypes[0].spec)
|
||||
require.Equal(b, "text/*", acceptedTypes[1].spec)
|
||||
|
@ -414,7 +414,7 @@ func Benchmark_Utils_SortAcceptedTypes_Unsorted(b *testing.B) {
|
|||
acceptedTypes[8] = acceptedType{spec: "image/*", quality: 1, specificity: 2, order: 8}
|
||||
acceptedTypes[9] = acceptedType{spec: "image/gif", quality: 1, specificity: 3, order: 9}
|
||||
acceptedTypes[10] = acceptedType{spec: "text/plain", quality: 1, specificity: 3, order: 10}
|
||||
sortAcceptedTypes(&acceptedTypes)
|
||||
sortAcceptedTypes(acceptedTypes)
|
||||
}
|
||||
require.Equal(b, []acceptedType{
|
||||
{spec: "text/html", quality: 1, specificity: 3, order: 0},
|
||||
|
|
Loading…
Reference in New Issue