// 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. package httputil import ( "github.com/golang/gddo/httputil/header" "net/http" "strings" ) // 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 _, offer := range offers { 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 = offer } 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 = offer } default: if spec.Value == offer && (spec.Q > bestQ || bestWild > 0) { bestQ = spec.Q bestWild = 0 bestOffer = offer } } } } return bestOffer }