Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.7 KiB
98 lines
2.7 KiB
// Copyright 2013 The Go Authors. All rights reserved. |
|
// |
|
// Use of this source code is governed by a BSD-style |
|
// license that can be found in the LICENSE file or at |
|
// https://developers.google.com/open-source/licenses/bsd. |
|
|
|
// this file was taken from the github.com/golang/gddo repository |
|
|
|
package middleware |
|
|
|
import ( |
|
"net/http" |
|
"strings" |
|
|
|
"github.com/go-openapi/runtime/middleware/header" |
|
) |
|
|
|
// NegotiateContentEncoding returns the best offered content encoding for the |
|
// request's Accept-Encoding header. If two offers match with equal weight and |
|
// then the offer earlier in the list is preferred. If no offers are |
|
// acceptable, then "" is returned. |
|
func NegotiateContentEncoding(r *http.Request, offers []string) string { |
|
bestOffer := "identity" |
|
bestQ := -1.0 |
|
specs := header.ParseAccept(r.Header, "Accept-Encoding") |
|
for _, offer := range offers { |
|
for _, spec := range specs { |
|
if spec.Q > bestQ && |
|
(spec.Value == "*" || spec.Value == offer) { |
|
bestQ = spec.Q |
|
bestOffer = offer |
|
} |
|
} |
|
} |
|
if bestQ == 0 { |
|
bestOffer = "" |
|
} |
|
return bestOffer |
|
} |
|
|
|
// NegotiateContentType returns the best offered content type for the request's |
|
// Accept header. If two offers match with equal weight, then the more specific |
|
// offer is preferred. For example, text/* trumps */*. If two offers match |
|
// with equal weight and specificity, then the offer earlier in the list is |
|
// preferred. If no offers match, then defaultOffer is returned. |
|
func NegotiateContentType(r *http.Request, offers []string, defaultOffer string) string { |
|
bestOffer := defaultOffer |
|
bestQ := -1.0 |
|
bestWild := 3 |
|
specs := header.ParseAccept(r.Header, "Accept") |
|
for _, rawOffer := range offers { |
|
offer := normalizeOffer(rawOffer) |
|
// No Accept header: just return the first offer. |
|
if len(specs) == 0 { |
|
return rawOffer |
|
} |
|
for _, spec := range specs { |
|
switch { |
|
case spec.Q == 0.0: |
|
// ignore |
|
case spec.Q < bestQ: |
|
// better match found |
|
case spec.Value == "*/*": |
|
if spec.Q > bestQ || bestWild > 2 { |
|
bestQ = spec.Q |
|
bestWild = 2 |
|
bestOffer = rawOffer |
|
} |
|
case strings.HasSuffix(spec.Value, "/*"): |
|
if strings.HasPrefix(offer, spec.Value[:len(spec.Value)-1]) && |
|
(spec.Q > bestQ || bestWild > 1) { |
|
bestQ = spec.Q |
|
bestWild = 1 |
|
bestOffer = rawOffer |
|
} |
|
default: |
|
if spec.Value == offer && |
|
(spec.Q > bestQ || bestWild > 0) { |
|
bestQ = spec.Q |
|
bestWild = 0 |
|
bestOffer = rawOffer |
|
} |
|
} |
|
} |
|
} |
|
return bestOffer |
|
} |
|
|
|
func normalizeOffers(orig []string) (norm []string) { |
|
for _, o := range orig { |
|
norm = append(norm, normalizeOffer(o)) |
|
} |
|
return |
|
} |
|
|
|
func normalizeOffer(orig string) string { |
|
return strings.SplitN(orig, ";", 2)[0] |
|
}
|
|
|