negotiate

package
v0.30.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

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

func ContentEncoding(r *http.Request, offers []string) string

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

func ContentType(r *http.Request, offers []string, defaultOffer string, opts ...Option) string

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

func WithIgnoreParameters(ignore bool) Option

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

func WithMatchSuffix(enable bool) Option

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)

Directories

Path Synopsis
Package header provides functions for parsing HTTP headers.
Package header provides functions for parsing HTTP headers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL