Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

http.negotiate

import http

http exposes this as http.negotiate, so import http is enough and the names are called as http.negotiate.*. import http.negotiate reaches the same definitions directly.

Content negotiation: choosing what to send when the client has said what it prefers.

Accept, Accept-Encoding and Accept-Language all use the same quality-value grammar, which parse_accept() reads and best_match() scores against what the server can actually produce.

Functions

parse_accept()

http.negotiate.parse_accept(header)

Parses an Accept, Accept-Encoding, Accept-Language or Accept-Charset header into entries, most preferred first.

Ordering follows RFC 9110 §12.5.1: by quality weight descending, then by specificity, then by the order they were written. An entry with q=0 is kept rather than dropped, because q=0 is an explicit refusal (“anything but this”) and a caller needs to see it to honour it.

Parameters

  • header (?string)

Returns — list: AcceptEntry, most preferred first

quality_of()

http.negotiate.quality_of(header, candidate: string) -> number

The quality weight header assigns to candidate, honouring wildcards.

Returns -1 when the header names nothing that covers candidate at all, which is different from a weight of 0 (an explicit refusal) and lets a caller apply the different defaults the two cases call for.

Parameters

  • header (?string)
  • candidate (string)

Returns number

best_match()

http.negotiate.best_match(header, available: list) -> ?string

Picks the entry of available the client would most like, or nil when it would accept none of them.

available is in server preference order, which decides ties - the usual and correct behaviour, since the server is the one that knows which representation is cheapest or best.

negotiate.best_match(request.header('accept'), ['application/json', 'text/html'])

Parameters

  • header (?string)
  • available (list)

Returns ?string

preferred_encoding()

http.negotiate.preferred_encoding(header, available: list) -> ?string

Picks a content coding for a response, given the request’s Accept-Encoding.

identity - sending the body uncompressed - is acceptable unless the client explicitly refused it, so this falls back to 'identity' rather than to nil whenever it can, and only returns nil when the client has refused identity too and offered nothing else this server has.

Parameters

  • header (?string)
  • available (list) — the codings the server can produce, in preference order

Returns ?string

preferred_language()

http.negotiate.preferred_language(header, available: list) -> ?string

Picks a language from available using the request’s Accept-Language.

A tag matches a request for its prefix, so en-GB satisfies a request for en (RFC 4647’s basic filtering). The reverse is not true: a request for en-GB is not satisfied by plain en, though en will still be picked if nothing better is on offer.

Parameters

  • header (?string)
  • available (list)

Returns ?string

names_explicitly()

http.negotiate.names_explicitly(header, value: string) -> bool

Whether header names value outright rather than covering it with a wildcard.

This is the difference between a client that asked for JSON and one that sent Accept: followed by a bare wildcard and would take anything - a distinction that matters when deciding what to give a client that expressed no real preference.

Parameters

  • header (?string)
  • value (string)

Returns bool

Classes

AcceptEntry

class http.negotiate.AcceptEntry

One entry of an Accept-style header: the value, its quality weight, and any other parameters it carried.

Fields

FieldTypeDescription
valuestringThe value itself, lowercased - a media type, a coding, a language tag, a charset.
qualitynumberThe quality weight from the q parameter, 0.0 to 1.0.
paramsdictAny parameters other than q, e.g. the level of an old text/html;level=1.

Constructor

http.negotiate.AcceptEntry(value, quality, params)

AcceptEntry.specificity()

http.negotiate.AcceptEntry.specificity() -> number

How specific this entry is, used to break ties between entries of equal quality: an exact type outranks a subtype wildcard, which in turn outranks the bare wildcard.

Returns number

AcceptEntry.to_string()

http.negotiate.AcceptEntry.to_string()

2026, Richard Ore and Zuri contributors