Module versioning

Module versioning 

Source
Expand description

API-versioning grammar (DW-048): the two shared vocabularies the versioning aids need beyond serde shapes — HTTP-dates (RFC 9110 IMF-fixdate) and media types (RFC 9110 type/subtype tokens).

Both are config-contract grammar in the same sense as net.rs (the IP/CIDR vocabulary) and normalize_origin (the CORS origin vocabulary): validation (snapshot::validate) and the runtime (dataplane::versioning) must agree on ONE parsing of these strings, so it lives in config, the lowest consuming domain, and everything above imports it from here.

§Why IMF-fixdate only

RFC 9110 defines three HTTP-date formats (IMF-fixdate, RFC 850, asctime) and requires RECIPIENTS to accept all three — but generators “MUST send the IMF-fixdate form”. This module is not a recipient of arbitrary network dates; it parses OPERATOR-AUTHORED config strings that this gateway will echo verbatim into the Sunset response header. Accepting only the one form generators must produce keeps the emitted header canonical and the validation message short; the obsolete forms are rejected with an example of the expected shape.

§Why bare media types

The match.accept criterion matches a media TYPE (type/subtype), ignoring parameters and q-values on the request side — the versioned-media-type convention embeds the version in the subtype (application/vnd.acme.v2+json). Parameter-form versioning (application/vnd.acme+json;version=2) is deliberately unsupported: Accept entries mix media-type parameters with accept-extensions (RFC 9110 section 12.5.1), and separating them reliably is parser work out of proportion to an S-sized aid. Wildcards are rejected as CONFIG values because they can never match (the criterion requires the client to NAME the version explicitly — see dataplane::versioning).

Structs§

HttpDate
A parsed IMF-fixdate HTTP-date (DW-048). The original config string is what gets echoed into the Sunset header (validated verbatim); this type carries the derived Unix seconds the RFC 9745 Deprecation structured date (@<seconds>) needs.

Functions§

normalize_media_type
Normalize a configured media type (DW-048): trim, lowercase, and require a bare type/subtype — both halves non-empty RFC 9110 tokens, no parameters (;...), no whitespace, no wildcards. The lowercased form is the comparison key; None marks an authoring error validation reports.
parse_http_date
Parse an IMF-fixdate HTTP-date (DW-048): day-name "," SP 2DIGIT SP month SP 4DIGIT SP time SP "GMT", e.g. Sun, 06 Nov 1994 08:49:37 GMT. Returns None for anything else — including the obsolete RFC 850 / asctime forms (see the module docs for why) and a day-name that disagrees with the date it names (a typo’d weekday is a typo’d date; date -u output always agrees).
parse_retry_after
Parse an HTTP Retry-After header value (DW-089) into a duration from NOW. Per RFC 9110 the value is either a non-negative integer (seconds to wait) or an IMF-fixdate (the time at which to retry). Returns None for anything else (the caller treats a missing/invalid header as no backoff signal). For the HTTP-date form the duration is max(0, date - now); a date in the past yields a zero duration (the advertised window has already elapsed).