AcceptedEncodings returns the list of encodings that the client supports, in descending order of preference. The client preference via q-factor and the server preference via Prefer setting are taken into account. If the Sec-WebSocket-Key header is present then non-identity encodings are not consider
(r *http.Request, preferredOrder []string)
| 496 | // encodings are not considered. See |
| 497 | // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. |
| 498 | func AcceptedEncodings(r *http.Request, preferredOrder []string) []string { |
| 499 | acceptEncHeader := r.Header.Get("Accept-Encoding") |
| 500 | websocketKey := r.Header.Get("Sec-WebSocket-Key") |
| 501 | if acceptEncHeader == "" { |
| 502 | return []string{} |
| 503 | } |
| 504 | |
| 505 | prefs := []encodingPreference{} |
| 506 | |
| 507 | for accepted := range strings.SplitSeq(acceptEncHeader, ",") { |
| 508 | parts := strings.Split(accepted, ";") |
| 509 | encName := strings.ToLower(strings.TrimSpace(parts[0])) |
| 510 | |
| 511 | // determine q-factor |
| 512 | qFactor := 1.0 |
| 513 | if len(parts) > 1 { |
| 514 | qFactorStr := strings.ToLower(strings.TrimSpace(parts[1])) |
| 515 | if strings.HasPrefix(qFactorStr, "q=") { |
| 516 | if qFactorFloat, err := strconv.ParseFloat(qFactorStr[2:], 32); err == nil { |
| 517 | if qFactorFloat >= 0 && qFactorFloat <= 1 { |
| 518 | qFactor = qFactorFloat |
| 519 | } |
| 520 | } |
| 521 | } |
| 522 | } |
| 523 | |
| 524 | // encodings with q-factor of 0 are not accepted; |
| 525 | // use a small threshold to account for float precision |
| 526 | if qFactor < 0.00001 { |
| 527 | continue |
| 528 | } |
| 529 | |
| 530 | // don't encode WebSocket handshakes |
| 531 | if websocketKey != "" && encName != "identity" { |
| 532 | continue |
| 533 | } |
| 534 | |
| 535 | // set server preference |
| 536 | prefOrder := slices.Index(preferredOrder, encName) |
| 537 | if prefOrder > -1 { |
| 538 | prefOrder = len(preferredOrder) - prefOrder |
| 539 | } |
| 540 | |
| 541 | prefs = append(prefs, encodingPreference{ |
| 542 | encoding: encName, |
| 543 | q: qFactor, |
| 544 | preferOrder: prefOrder, |
| 545 | }) |
| 546 | } |
| 547 | |
| 548 | // sort preferences by descending q-factor first, then by preferOrder |
| 549 | slices.SortStableFunc(prefs, func(a, b encodingPreference) int { |
| 550 | if math.Abs(a.q-b.q) < 0.00001 { |
| 551 | return cmp.Compare(b.preferOrder, a.preferOrder) |
| 552 | } |
| 553 | return cmp.Compare(b.q, a.q) |
| 554 | }) |
| 555 |