func acceptsHtml(hdr http.Header) bool { actual := header.ParseAccept(hdr, "Accept") for _, s := range actual { if s.Value == "text/html" { return (true) } } return (false) }
// negotiateLanguage negotiates the acceptable language according to the Accept-Language HTTP header. func negotiateLanguage(r *http.Request, offers []string, defaultOffer string) string { bestOffer := defaultOffer bestQ := -1.0 specs := header.ParseAccept(r.Header, "Accept-Language") 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 = defaultOffer } return bestOffer }
// 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 }