Documentation
¶
Overview ¶
Package negotiate provides server-side HTTP content negotiation helpers — selecting the response Content-Type from an Accept header and the response Content-Encoding from an Accept-Encoding header.
The package is stdlib-only (modulo the typed mediatype.MediaType values it consumes).
The exported ContentType honours MIME-type parameters by default; use WithIgnoreParameters to restore the pre-v0.30 looser match.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContentEncoding ¶
ContentEncoding returns the best offered content encoding for the request's Accept-Encoding header. If two offers match with equal weight then the offer earlier in the list is preferred. If no offers are acceptable, then "" is returned.
Encoding tokens have no parameters, so this function is unaffected by the v0.30 parameter-honouring change to ContentType.
func ContentType ¶
ContentType 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 (text/* trumps */*; type/subtype trumps type/*). 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.
As of v0.30 the matching rule honours MIME-type parameters: an Accept entry of "text/plain;charset=utf-8" matches an offer of bare "text/plain" (offer carries no constraint), but it does NOT match an offer of "text/plain;charset=ascii" (charset values disagree). Pass WithIgnoreParameters(true) to restore the pre-v0.30 behaviour where parameters were stripped before matching — see WithIgnoreParameters for details and an example.
When the Accept header is absent, the first offer is returned unchanged (param-stripping is irrelevant in that case).
Types ¶
type Option ¶
type Option func(*options)
Option configures ContentType behaviour.
func WithIgnoreParameters ¶
WithIgnoreParameters returns an Option that strips MIME-type parameters from both Accept entries and offers before matching, restoring the behaviour the runtime had before v0.30.
New code should leave parameters honoured (the default). This option exists for applications that depend on the looser pre-v0.30 match — most often because their producers and Accept clients use mismatched charset or version params that they treat as informational.
Example — per-call opt-out:
chosen := negotiate.ContentType(r, offers, "",
negotiate.WithIgnoreParameters(true),
)
Example — server-wide opt-out (via [middleware.Context]):
ctx := middleware.NewContext(spec, api, nil).SetIgnoreParameters(true)
Example ¶
ExampleWithIgnoreParameters shows the per-call opt-out for legacy parameter-stripping behaviour.
package main
import (
"fmt"
"net/http"
"github.com/go-openapi/runtime/server-middleware/negotiate"
)
// Test fixtures: extracted to dedup goconst hits across the table-driven cases.
const (
textPlainASCII = "text/plain;charset=ascii"
textPlainUTF8 = "text/plain;charset=utf-8"
)
func main() {
r := &http.Request{Header: http.Header{headerAccept: {textPlainASCII}}}
offers := []string{textPlainUTF8}
// Default: parameters are honoured. The charset values disagree, so
// no offer matches and we fall back to the default.
strict := negotiate.ContentType(r, offers, "fallback/default")
// Opt-out: strip parameters before matching. The bare types agree, so
// the offer is selected.
loose := negotiate.ContentType(r, offers, "fallback/default",
negotiate.WithIgnoreParameters(true),
)
fmt.Printf("strict=%q\nloose=%q\n", strict, loose)
}
Output: strict="fallback/default" loose="text/plain;charset=utf-8"
func WithMatchSuffix ¶
WithMatchSuffix returns an Option that extends content negotiation to tolerate RFC 6839 structured-syntax suffix media types. When enabled, an Accept entry of "application/json" matches an offer of "application/vnd.api+json" and vice versa, for the suffixes recognised by the runtime (+json, +xml, +yaml).
Default: strict (false). Use only when interoperating with clients or servers that do not strictly abide by the spec — for example, servers returning application/problem+json error responses against operations that only declare application/json in produces.
Suffix matches always lose to exact and alias matches when those are on offer; see mediatype.MatchKind for the tier ordering.
Example — per-call opt-in:
chosen := negotiate.ContentType(r, offers, "",
negotiate.WithMatchSuffix(true),
)
Example — server-wide opt-in (via [middleware.Context]):
ctx := middleware.NewContext(spec, api, nil).SetMatchSuffix(true)