A small Rust HTTP workspace. Application code typically depends on the rttp
facade crate, which forwards to the public rttp_client and rttp-server
crates; those share the wire primitives in the internal rttp-protocol crate.
The private, unpublished rttp_test_support crate owns the reusable local HTTP
and client helpers and shared test fixtures used by the workspace test suites.
rttp— the compatibility facade. It exposesrttp::Http::serverand, with theclientfeature enabled,rttp::Http::client; it re-exports therttp_server::servermodule and forwards selectedrttp_clientresponse types. It wraps the established APIs and does not reimplement client or server behavior.rttp_client— the public HTTP client crate. Plain HTTP is available by default over directsocket2TCP connections; optionalasync,http2,tls-native, andtls-rustlsfeatures add async request APIs, bounded prior-knowledge h2c, and TLS. SOCKS proxy handshakes remain delegated to thesockscrate.rttp-server— the public blocking HTTP server crate. It serves local tests and simple embedded use from asocket2listener, parses HTTP/1.x requests, and detects the bounded h2c paths (the HTTP/2 prior-knowledge preface or a validUpgrade: h2crequest). It does not implement server TLS.rttp-protocol— the internal, transport-independent wire-primitive crate (library namerttp_protocol), intentionally unpublished. It owns protocol syntax and framing validation only, split into typed per-header modules shared by the client and server; application policy stays in its callers.rttp_test_support— the private test-support crate used only by the workspace test suites.
Across the client, server, and protocol crates, typed header and wire helpers stay metadata-only unless a section explicitly documents runtime behavior. They parse, validate, normalize, and expose bounded protocol metadata; they do not imply cache engines, browser policy, authentication decisions, retries, representation selection, or body transformation.
Typed response metadata includes Cross-Origin-Embedder-Policy and
Cross-Origin-Embedder-Policy-Report-Only. Both accept the directives
unsafe-none, require-corp, and credentialless as singleton bounded
structured-field items; well-formed parameters such as report-to are accepted
as syntax and normalized away by typed builders. RTTP exposes these values for
application use only: it does not enforce browser embedder policy, retain
reporting metadata, deliver reports, or schedule report delivery.
Typed response metadata also includes Cross-Origin-Opener-Policy and
Cross-Origin-Opener-Policy-Report-Only. Both accept the directives
unsafe-none, same-origin-allow-popups, same-origin, and
noopener-allow-popups as singleton bounded structured-field items. Enforcing
COOP accepts well-formed parameters such as report-to as syntax and discards
them. Report-only COOP retains reporting parameters, including report-to, as
metadata and does not validate those names against Reporting-Endpoints. RTTP
exposes these values for application use only: it does not enforce
browsing-context isolation, deliver reports, or schedule report delivery.
Run the same checks as GitHub CI from the repository root before opening a pull request:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --all-featuresrttp_client supports plain HTTP by default. Optional features add async
request APIs and TLS implementations:
| name | comment |
|---|---|
| async | Async request APIs |
| http2 | Bounded prior-knowledge h2c over direct socket2 TCP connections |
| tls-native | HTTPS with native-tls |
| tls-rustls | HTTPS with rustls |
[dependencies]
rttp_client = "0.2"Direct TCP client connections are opened with socket2. SOCKS proxy handshakes
are still delegated to the socks crate.
HTTP/1.x chunked responses are decoded by the client, and response trailers are
available through Response::trailers, Response::trailer, and
Response::trailer_value.
HttpClient can emit single bytes ranges with bounded helpers:
range(start, end) writes Range: bytes=start-end, range_from(start) writes
Range: bytes=start-, and range_suffix(length) writes
Range: bytes=-length. The helpers reject inverted closed ranges and a zero
suffix before opening a socket. Callers can still set a manual Range header
with the generic header API for cases outside those helpers.
client
.get()
.url("http://example.test/archive")
.range(1_024, 2_047)?
.if_range_etag(r#""revision-42""#)?
.emit()?;206 Partial Content and 416 Range Not Satisfiable are visible through
Response::is_partial_content() and Response::is_range_not_satisfiable().
Response::content_range() parses Content-Range into ContentRange, using
start and end for satisfiable ranges such as bytes 10-19/200, and no
start or end for unsatisfied ranges such as bytes */200.
If-Range is available through bounded request helpers that compose with the
range helpers: if_range_etag(etag) writes a single strong entity-tag
validator, and if_range_date(http_date) writes an HTTP-date validator. The
ETag helper rejects weak tags, *, lists, and malformed tag syntax before a
socket is opened; the date helper requires a value that parses as an HTTP-date.
Manual If-Range headers remain available through the generic header API for
cases outside the helper validation.
Response::accept_ranges() parses response Accept-Ranges fields into
AcceptRanges metadata. It returns Ok(None) when the header is absent;
present values expose units(), is_none(), and accepts_bytes(). Parsing is
bounded to 64 KiB per header field and 256 range units, rejects malformed or
empty values, rejects duplicate units case-insensitively across all parsed
fields while preserving each unit's spelling and order, and represents the
none sentinel as an empty unit list. Raw Accept-Ranges fields
remain available through the ordinary response header accessors even when the
typed parser rejects a malformed value.
On the client side, these APIs only emit request metadata and expose response
metadata. RTTP does not generate Range requests from Accept-Ranges,
evaluate If-Range, automatically retry or replay a failed or full-response
range request, store cached responses, synthesize multipart range requests,
implement a partial response engine, serve bytes, slice content, resume
downloads, follow redirects because of range metadata, choose status-policy
behavior, or apply automatic cache validation policy.
HttpClient can emit common conditional validators with
if_none_match(etag), if_match(etag), if_modified_since(http_date), and
if_unmodified_since(http_date). The ETag helpers accept one validator per
call: *, a strong tag such as "abc", or a weak tag such as W/"abc".
Comma-separated validator lists remain available through the generic header
API. The date helpers validate the supplied value as one HTTP-date through the
shared protocol IfModifiedSince and IfUnmodifiedSince types and emit the
canonical IMF-fixdate form before a socket is opened; malformed, empty,
oversized (over 64 KiB), or control-byte values are rejected.
client
.get()
.url("http://example.test/manifest")
.if_none_match(r#""revision-42""#)?
.if_modified_since("Sun, 06 Nov 1994 08:49:37 GMT")?
.emit()?;Responses expose conditional metadata with Response::is_not_modified() for
304 Not Modified, Response::is_precondition_failed() for
412 Precondition Failed, typed bounded Response::etag(),
Response::schedule_tag(), and Response::last_modified(). Malformed,
oversized, or duplicate response ETag or Schedule-Tag fields make the typed
helper return an error while raw values remain available through
Response::etag_value(), Response::schedule_tag_value(),
Response::header_value(), and Response::header_values(). 304 responses
are handled as bodyless even if
misleading body framing is present; 412 remains an ordinary response status
for the caller to handle.
These helpers do not add cache storage, automatic revalidation, or a
cache-control engine. If-Range is range-scoped and uses the dedicated
if_range_etag and if_range_date helpers above. RTTP only emits bounded
request headers and exposes response metadata; cache persistence and validation
policy remain application-owned.
Delta-Base response metadata is exposed through the shared protocol
DeltaBase/HttpDeltaBase type. Server responses can declare it with
HttpResponse::with_delta_base(...); client responses parse it with
Response::delta_base() and can inspect the raw field with
Response::delta_base_value(). The value is one strong or weak entity-tag base
validator, bounded to 64 KiB and rejected when malformed, duplicated, or a
comma-list. RTTP does not locate cached entities, compare base validators, or
apply deltas automatically.
rttp_client skips HTTP/1.1 informational response heads before the terminal
response, while preserving the skipped metadata on
Response::informational_responses(). Each InformationalResponse exposes
its code(), reason(), raw headers(), headers_of_name(),
header_value(), and header_values(), so callers can observe 100 Continue,
102 Processing, 103 Early Hints, and other skippable 1xx heads without
turning them into the final response.
The skipped head parser is bounded and validation-oriented. Each informational
head is limited to the normal response-head bound, must be an HTTP/1.1 1xx
status line, must contain well-formed header fields, and must not declare
Content-Length or Transfer-Encoding body framing. Malformed or oversized
informational heads reject the response before the final response bytes are
consumed. 101 Switching Protocols is not treated as skipped metadata: it
remains the terminal response for upgrade and tunnel handoff paths, and its
socket handoff stays separate from Response::informational_responses().
On the server side, HttpResponse::early_hints(links) and
HttpResponse::early_hints_with_headers(links, metadata) construct a bodyless
103 Early Hints response model. The helpers require at least one validated
Link value, bound each header value to 64 KiB, reject malformed field bytes,
and reject metadata fields that would affect connection or body framing such
as Connection, Content-Length, TE, Trailer, Transfer-Encoding, and
Upgrade. Manual raw headers on ordinary responses remain preserved until a
typed helper is requested or a typed constructor replaces them.
Early Hints support is metadata-only. RTTP does not automatically preload
linked resources, apply cache policy, redirect, retry, replay requests,
generate routes, expose a streaming early-write API, or add TLS/ALPN behavior
from 103 metadata.
Response::links() parses one or more final-response Link fields into
ordered LinkValues and LinkValue metadata. Each value retains its target
URI/reference and ordered parameters, including unknown parameters such as
extensions alongside rel. Parsing is on demand, so malformed or oversized
metadata returns an error without discarding raw response headers. Fields and
parameter values are limited to 64 KiB, with at most 256 link-values and 256
parameters per value.
This shares Early Hints' bounded metadata posture, but it does not preload, schedule fetches, redirect, apply cache policy, or generate routes.
HttpClient::cache_control_no_cache(), cache_control_no_store(), and
cache_control_max_age(seconds) append common request directives to one
Cache-Control field. cache_control_extension(name) and
cache_control_extension_with_value(name, value) append valueless and
token-valued extension directives. The helpers reject malformed tokens,
duplicate directives, oversized values, and more than 256 directives before a
connection is opened.
These methods only declare request metadata: they do not create a cache,
compute freshness, or automatically revalidate. Raw
header(("Cache-Control", value)) remains available for quoted-string
extension values or other syntax outside this bounded API.
Response::cache_control() parses one or more response Cache-Control header
fields into CacheControl. It exposes the common response directives
no-cache, no-store, max-age, s-maxage, private, public,
must-revalidate, proxy-revalidate, immutable,
stale-while-revalidate, and stale-if-error. Quoted field-name lists on
no-cache and private are split into field names, and unknown extension
directives are preserved as CacheControlExtension values with their token name
and optional parsed value.
The parser is bounded and validation-oriented. Each header field value is
limited to 64 KiB, the parsed header set is limited to 256 directives, directive
names and unquoted values must be valid HTTP tokens, quoted strings must be
well formed, and delta-seconds values must be unquoted non-negative decimal
integers that fit in u64. A malformed Cache-Control value makes
Response::cache_control() return an error; the original response headers and
body remain available through the ordinary response APIs.
Cache-Control parsing is intentionally separate from conditional validator
helpers. Response::etag() and Response::last_modified() expose validators,
and request helpers such as if_none_match() and if_modified_since() can
emit conditional requests when the application chooses to do so. RTTP does not
combine Cache-Control directives with validators to decide freshness, build a
cache entry, or issue a follow-up request.
The client has no cache store and does not perform automatic revalidation,
freshness calculation against wall-clock time, Vary matching, shared-cache
policy enforcement, or automatic conditional requests. Directives such as
max-age, s-maxage, no-cache, must-revalidate, and extension directives
are exposed as parsed metadata only.
Response::cache_status() parses one or more response Cache-Status header
fields into CacheStatus. It combines repeated fields in wire order as an
RFC 9211 / RFC 8941 list of cache identifiers (sf-token or sf-string) plus
parameters, including typed hit, fwd, fwd-status, ttl, stored,
collapsed, key, and detail values and well-formed extension parameters.
Each field value is limited to 64 KiB, the parsed header set is limited to
256 members, each member is limited to 256 parameters, and each parameter
value is limited to 64 KiB. A malformed Cache-Status value makes the helper
return an error while the raw response headers and body remain available
through the ordinary response APIs. An absent header returns Ok(None).
Cache-Status metadata is exposed for application-owned policy only. RTTP does
not store cache entries, compute freshness, revalidate, select endpoints,
retry, or alter response acceptance from Cache-Status.
Response::cdn_cache_control() parses one or more response
CDN-Cache-Control header fields into CdnCacheControl. It preserves
directives in wire order, including CDN-specific extension directives, and
exposes each directive token name plus its optional parsed value.
The helper uses the same bounded validation model as response
Cache-Control: each field value is limited to 64 KiB, the parsed header set
is limited to 256 directives, directive names and unquoted values must be valid
HTTP tokens, and quoted strings must be well formed. A malformed
CDN-Cache-Control value makes the helper return an error while the raw
response headers and body remain available through the ordinary response APIs.
CDN cache metadata is exposed for application-owned policy only. RTTP does not
create a CDN cache, compute freshness, revalidate automatically, implement
surrogate-key behavior, apply shared-cache policy, retry, replay, redirect, or
alter response acceptance from CDN-Cache-Control.
Response::surrogate_control() parses one or more response
Surrogate-Control header fields into SurrogateControl. Server
HttpResponse::with_surrogate_control() validates and replaces one declared
value, while HttpResponse::surrogate_control() parses attached raw response
fields through the same protocol type.
The helper accepts directive names, optional token values, and well-formed quoted extension values. It rejects malformed syntax, duplicate directive names case-insensitively across fields, more than 256 directives, values larger than 64 KiB, and aggregate parsed header sets larger than 64 KiB. A malformed value makes the typed helper return an error while raw headers and body remain available through the ordinary response APIs.
Surrogate cache metadata is exposed for application-owned policy only. RTTP
does not create a CDN cache, compute freshness, evaluate surrogate keys,
translate directives into Cache-Control, apply shared-cache policy, retry,
replay, redirect, or alter response acceptance from Surrogate-Control.
Response::date() parses the response Date header through the shared
protocol ResponseDate singleton HTTP-date primitive. The helper returns
Ok(None) when the header is absent, returns SystemTime when the value is
present and valid, and returns an error for malformed, duplicate, control-byte,
or oversize values.
Response::age() parses the response Age header through the protocol Age
type as HTTP/1.1 delta-seconds metadata. The helper returns Ok(None) when the
header is absent, returns the non-negative decimal value as u64 when it is
present and valid, and returns an error for empty, signed, fractional,
non-numeric, comma-list, overflowing, duplicate, or oversize values.
Surrounding SP and HTAB are trimmed as optional whitespace. Each field value
is bounded to 64 KiB, and the accepted numeric bound is the u64
delta-seconds range: 0 through u64::MAX.
Response::expires() parses the response Expires header through the shared
protocol ResponseExpires primitive. Response::last_modified_date() parses
Last-Modified through ResponseLastModified while
Response::last_modified() keeps exposing the raw field. These HTTP-date
helpers return Ok(None) when the header is absent, return SystemTime for
valid values, and reject malformed, duplicate, control-byte, and oversize
values. Supported HTTP-date forms are IMF-fixdate, obsolete RFC 850 dates, and
asctime dates; typed formatting emits canonical IMF-fixdate.
Malformed helper values do not reject the raw response. The original Date,
Age, Expires, and Last-Modified fields remain available through
header_value, header_values, and the other raw header accessors. These helpers expose
metadata only; RTTP does not calculate freshness, correct clock skew, validate
cache state against wall-clock time, store responses, match stored responses,
revalidate responses, apply shared-cache policy, issue automatic conditional
requests, retry, redirect, schedule work, or choose status policy.
Response::memento_datetime() parses the response Memento-Datetime header
through the protocol MementoDatetime type as one singleton IMF-fixdate.
The helper returns Ok(None) when the header is absent, returns
MementoDatetime when the value is present and valid, and returns an error
for empty, malformed, control-byte, duplicate, or oversize values. Each field
value is bounded to 64 KiB. Surrounding SP and HTAB are trimmed as optional
whitespace.
Malformed helper values do not reject the raw response. The original
Memento-Datetime field remains available through header_value and
header_values. This helper exposes metadata only; RTTP does not select an
archival representation, negotiate Accept-Datetime, implement TimeGate
behavior, retry, or change transport handling. The matching request metadata
helper is accept_datetime, which parses the same HTTP-date instants; the two
helpers still do not negotiate with each other.
HttpClient::accept_datetime(http_date) sets an Accept-Datetime request
header through the protocol AcceptDatetime type as one singleton
HTTP-date. The helper accepts IMF-fixdate, obsolete RFC 850, and asctime
forms, trims surrounding SP and HTAB, and emits the canonical IMF-fixdate
form. It returns a builder error for empty, malformed, control-byte,
oversized (over 64 KiB), and comma-joined values before a socket is opened,
and a second accept_datetime call replaces the existing field.
This helper exposes metadata only; RTTP does not select an archived
representation, implement TimeGate behavior, add Vary, alter cache policy,
or change conditional-request handling. A parsed Accept-Datetime instant
matches Response::memento_datetime() for the same HTTP-date, but the two
helpers do not negotiate with each other.
Response::retry_after() parses a single response Retry-After header through
the protocol RetryAfter type as either HTTP-date metadata or non-negative
delta-seconds. It returns Ok(None) when the header is absent. Present values
are exposed as RetryAfter, with delta_seconds() returning u64 for the
delta form and http_date() returning SystemTime for the date form.
The helper is bounded and validation-oriented. The header value is limited to
64 KiB, duplicate Retry-After header fields are rejected, delta-seconds must
be unsigned decimal digits that fit in u64, and malformed dates or other
invalid values return an error. The original response headers remain available
through Response::header_value() and Response::header_values().
RTTP does not sleep, retry, replay requests, apply backoff, integrate with a
scheduler, calculate cache freshness, or decide status-code retry policy from
Retry-After.
Response::allow() parses one or more response Allow header fields into
Allow metadata. It returns Ok(None) when the header is absent. Present
values are parsed as comma-separated HTTP method tokens across all Allow
fields in wire order, and the resulting method list is exposed by
Allow::methods() and checked with Allow::contains_method(method).
The helper is bounded and validation-oriented. Each header field value is
limited to 64 KiB, the parsed method list is limited to 256 entries, and each
method must be a valid HTTP token. Empty list members, malformed method tokens,
duplicate method names, oversized values, and too many methods make
Response::allow() return an error while leaving the original response headers
and body available through the ordinary response APIs.
The helper is metadata-only. rttp_client does not choose fallback methods,
retry or replay requests, or attach automatic behavior to 405 or OPTIONS
responses based on Allow.
Response::content_language() parses one or more response Content-Language
header fields into ContentLanguage metadata. It returns Ok(None) when the
header is absent. Present values are parsed as comma-separated language ranges
across all Content-Language fields in wire order, and the resulting list is
exposed by ContentLanguage::tags(). ContentLanguage::parse(value) is
available when callers want to validate a single raw field value directly.
The helper is bounded and validation-oriented. Each header field value is
limited to 64 KiB, the parsed tag list is limited to 256 entries, and concrete
tags must contain non-empty ASCII alphanumeric subtags separated by hyphens
with an alphabetic primary subtag. Empty members, malformed values, duplicate
tags across one or more helper-parsed header fields, oversized values, and too
many tags make Response::content_language() return an error while leaving
the original response headers and body available through the ordinary response
APIs.
The helper interoperates with the existing response metadata helpers by
preserving raw headers and parsing only when requested. RTTP does not perform
automatic language negotiation, locale fallback, variant matching, cache
policy, retry, replay, redirect, or status-policy behavior from
Content-Language.
HttpClient::accept_language(ranges) validates and emits one
Accept-Language request header from ordered language ranges through the
shared protocol-owned AcceptLanguage type. Each range may include an
optional q weight, for example fr-CA; q=0.8; * is also accepted. The
shared primitive limits each supplied value to 64 KiB and the parsed range
list to 32 entries, rejects malformed ranges or q-values and case-insensitive
duplicates, and returns a builder error before opening a connection. Raw
header(("Accept-Language", value)) remains available when callers need to
preserve unvalidated metadata.
On the server, Request::accept_language() and
HttpRequest::accept_language() parse received fields in wire order into
HttpAcceptLanguages (the server alias for the shared protocol AcceptLanguage
type), returning Ok(None) when the header is absent.
HttpAcceptLanguages::ranges() and HttpAcceptLanguages::qualities() expose
the validated ranges and optional q-values. Each received field is bounded to
64 KiB and the combined range list to 32 entries; malformed values, invalid
q-values, and duplicate ranges return HttpAcceptLanguageParseError without
changing the raw request headers.
These helpers are metadata-only. RTTP does not perform locale matching,
fallback selection, translation lookup, routing, or automatic response choice
from Accept-Language.
Response::content_location() parses a response Content-Location header into
the shared protocol-owned ContentLocation metadata type. It returns
Ok(None) when the header is absent and rejects duplicate header fields
because Content-Location is handled as a singleton response metadata field.
ContentLocation::parse(value) is available when callers want to validate one
raw field value directly; it trims outer HTTP optional whitespace and exposes
the preserved reference text with ContentLocation::as_str() and
ContentLocation::header_value().
The helper is bounded and validation-oriented. The field value is limited to
64 KiB and must be a non-empty absolute URI or relative URI reference that can
be parsed without control characters, interior whitespace, unsafe field-value
characters, malformed URI syntax, or broken percent-encoding.
Malformed values, duplicated singleton fields, and oversized values make
Response::content_location() return an error while leaving the original
response headers and body available through Response::header_value(),
Response::header_values(), and the other response metadata helpers.
The helper interoperates with adjacent response metadata helpers such as
Response::cache_control(), Response::allow(),
Response::content_language(), Response::vary(), Response::retry_after(),
Response::age(), Response::expires(), and
Response::accept_ranges() by preserving raw headers and parsing only when
requested. It is metadata-only: RTTP does not treat Content-Location as
redirect behavior, cache variant selection, representation replacement,
retry/replay behavior, route generation, or status-policy behavior.
Response::service_worker_allowed() parses a response Service-Worker-Allowed
header into the shared protocol-owned ServiceWorkerAllowed metadata type. It
returns Ok(None) when the header is absent and rejects duplicate header
fields because Service-Worker-Allowed is handled as a singleton response
metadata field. ServiceWorkerAllowed::parse(value) is available when callers
want to validate one raw field value directly; it trims outer HTTP optional
whitespace and exposes the preserved path text with
ServiceWorkerAllowed::as_str() and ServiceWorkerAllowed::header_value().
The helper is bounded and validation-oriented. The field value is limited to
64 KiB and must be a non-empty origin-relative or absolute path without
control or non-ASCII characters, interior whitespace, unsafe field-value characters, broken
percent-encoding, absolute URIs, or network-path authority forms.
Malformed values, duplicated singleton fields, and oversized values make
Response::service_worker_allowed() return an error while leaving the original
response headers and body available through Response::header_value(),
Response::header_values(), and the other response metadata helpers.
The helper interoperates with adjacent response metadata helpers by preserving raw headers and parsing only when requested. It is metadata-only: RTTP does not register service workers, evaluate service-worker scope, resolve the value against a script URL, or apply application routing policy.
Response::content_dpr() parses a response Content-DPR header into the
shared protocol-owned ContentDpr metadata type. It returns Ok(None) when
the header is absent and rejects duplicate header fields because Content-DPR
is handled as a singleton response metadata field. ContentDpr::parse(value)
is available when callers want to validate one raw field value directly; it
trims outer HTTP optional whitespace and exposes the finite positive ratio with
ContentDpr::ratio() plus the preserved decimal text with
ContentDpr::header_value().
The helper is bounded and validation-oriented. The field value is limited to
64 KiB and must match 1*DIGIT["." 1*DIGIT] as a finite ratio greater than
zero. Zero, trailing or leading decimal points, signs, exponent notation,
control bytes, malformed values, duplicated singleton fields, and oversized
values make Response::content_dpr() return an error while leaving the
original response headers and body available through Response::header_value(),
Response::header_values(), and the other response metadata helpers.
The helper is observation-only. RTTP does not rescale images, send request DPR,
apply Client Hints policy, retry, replay, redirect, or change transport from
Content-DPR.
Response::content_type() parses a singleton response Content-Type header
into ContentType metadata. It returns Ok(None) when the header is absent
and rejects duplicate Content-Type fields. Present values expose the
normalized media type through type_(), subtype(), essence(), and
is(type, subtype), plus ordered parameters through parameters() and
case-insensitive parameter(name). ContentType::parse(value) is available
when callers want to validate one raw field value directly.
Response::content_encoding() parses one or more response Content-Encoding
fields into ContentEncoding metadata. It returns Ok(None) when the header
is absent. Present values are parsed as comma-separated content codings across
all fields in wire order and exposed through ContentEncoding::codings().
Coding spelling and order are preserved, while duplicate detection is
case-insensitive.
Both helpers are bounded and validation-oriented. Each field value is limited
to 64 KiB. Client Content-Type parsing accepts at most 256 parameters, lowers
the media type and parameter names, rejects missing or malformed media types,
malformed parameter syntax, malformed quoted strings, duplicate parameters,
duplicate singleton fields, CR/LF injection, oversized values, and too many
parameters. Client Content-Encoding parsing accepts at most 256 codings and
rejects empty members, malformed tokens, duplicate codings, oversized values,
and too many codings. Parse errors do not reject the raw response: original
headers and body remain available through Response::header_value(),
Response::header_values(), and the ordinary body APIs.
let content_type = response.content_type()?.expect("Content-Type");
if content_type.is("application", "json") {
let charset = content_type.parameter("charset");
}
let content_encoding = response.content_encoding()?.expect("Content-Encoding");
assert_eq!(vec!["gzip", "br"], content_encoding.codings());These helpers are representation metadata only. rttp_client does not perform
MIME sniffing, body decoding from this metadata, charset transcoding,
compression or decompression policy, negotiation, cache policy, redirects,
retry/replay, or filesystem serving from Content-Type or
Content-Encoding.
rttp-protocol owns the shared Accept-Charset primitive. Client helpers
format through that type, and server Request / HttpRequest helpers parse
with the same rules.
HttpClient::accept_charset() appends a validated request charset range,
while accept_charset_with_q() accepts an HTTP q-value from 0 through 1
with at most three fractional digits. The helpers emit one comma-separated
Accept-Charset field and reject invalid charset tokens, q-values,
duplicates, oversized values, and more than 32 ranges before a connection is
opened.
On the server, Request::accept_charset() and
HttpRequest::accept_charset() parse all received Accept-Charset fields in
wire order into HttpRequestAcceptCharsets, an alias of the shared protocol
type. Each entry provides its charset() and q-value quality() in
thousandths (1000 is the default quality of 1). Absent metadata returns
Ok(None); malformed, duplicate, empty, oversized, or excessive entries
return a parse error without changing the request itself.
These helpers declare and parse metadata only. They do not negotiate, transcode, decode bodies, sniff MIME types, or select a response charset.
rttp-protocol owns the shared RFC 2295 Negotiate primitive. Client
helpers format through that type, and server Request / HttpRequest
helpers parse with the same rules.
HttpClient::negotiate(value) validates and emits one Negotiate field,
replacing any existing same-name field before a socket is opened. The value
must be an ordered comma-separated list of trans, vlist, guess-small,
*, major.minor remote variant selection algorithm versions, or
token[=token] extension directives. Flags are normalized to lowercase,
versions are normalized to major.minor, and duplicate directives are
rejected: at most one of each flag and *, one occurrence of each version
pair, and one extension per case-insensitive name. The helper rejects invalid
tokens, valued flags or versions, empty or trailing comma members,
duplicates, oversized values, and more than 32 members before a connection is
opened.
On the server, Request::negotiate() and HttpRequest::negotiate() parse
all received Negotiate fields in wire order into HttpNegotiate, an alias
of the shared protocol type. Each HttpNegotiateDirective is a trans,
vlist, guess-small, or * flag, a major.minor version, or a
token[=token] extension. Absent metadata returns Ok(None); malformed,
duplicate, empty, oversized, or excessive entries return a parse error
without changing the request itself.
These helpers declare and parse metadata only. They do not select a variant,
run transparent content negotiation, synthesize Alternates, TCN,
Variant-Vary, or Vary, or change cache selection.
rttp-protocol owns the shared Accept-Encoding primitive. Client helpers
format through that type, and server Request / HttpRequest helpers parse
with the same rules.
HttpClient::accept_encoding() appends a validated request coding, while
accept_encoding_with_q() accepts an HTTP q-value from 0 through 1 with
at most three fractional digits. Convenience helpers cover gzip, deflate,
br, and identity, including q-value variants. The helpers emit one
comma-separated Accept-Encoding field and reject invalid coding tokens,
q-values, duplicates, oversized values, and more than 32 codings before a
connection is opened.
On the server, Request::accept_encoding() and
HttpRequest::accept_encoding() parse all received Accept-Encoding fields
in wire order into HttpRequestAcceptEncodings, an alias of the shared
protocol type. Each entry provides its coding() and q-value quality() in
thousandths (1000 is the default quality of 1). Absent metadata returns
Ok(None); malformed, duplicate, empty, oversized, or excessive entries
return a parse error without changing the request itself.
These helpers declare and parse metadata only. They do not enable automatic compression, decompression, or content negotiation.
HttpClient::want_content_digest() and want_content_digest_with_q() append
validated algorithms to one Want-Content-Digest field. want_repr_digest()
and want_repr_digest_with_q() do the same for Want-Repr-Digest. The
_with_q variants accept RFC 9530 relative preference values from 0 through
10; the default helper value is 10.
HttpClient::new()
.get()
.url("http://example.test/asset")
.want_content_digest("sha-256")?
.want_repr_digest_with_q("sha-512", "8")?;Each helper emits a comma-separated field and rejects malformed algorithm
tokens or q-values, case-insensitive duplicate algorithms, fields over 64 KiB,
and more than 32 algorithms before opening a connection. Raw
header(("Want-Content-Digest", value)) and
header(("Want-Repr-Digest", value)) remain available for syntax outside the
bounded helper API.
On the server, Request::want_content_digest() and
HttpRequest::want_content_digest() parse received Want-Content-Digest
fields in wire order into HttpWantContentDigest. Request::want_repr_digest()
and HttpRequest::want_repr_digest() do the same for Want-Repr-Digest into
HttpWantReprDigest. Each entry exposes algorithm() and preference() (0
through 10). Absent metadata returns Ok(None); malformed, duplicate, empty,
oversized, or excessive entries return a parse error without changing the
request itself.
These helpers declare and parse preferences only. They do not select an
algorithm, compute digests, verify response body hashes, attach
Content-Digest or Repr-Digest, retry requests, or sign messages.
HttpClient::accept() appends one validated media range, while
accept_with_q() adds a q-value from 0 through 1 with at most three
fractional digits. Convenience helpers cover */*, JSON, HTML, XML, and plain
text, including q-value variants. The shared rttp-protocol Accept primitive
owns media-range parsing, quoted-string parameter validation including empty
quoted values, q-value validation, bounds, and header formatting.
The client reuses it while keeping the existing 32-helper-range limit, rejecting
malformed media types or parameters, duplicate parameters or q-values, invalid
q-values, oversized fields, and more than 32 media ranges before opening a
connection. Helper q-value arguments preserve the existing facade boundary by
accepting legacy empty fractional forms such as 0. and 1. while rejecting
surrounding whitespace. Helper appends also validate any existing raw Accept
field with the protocol primitive's strict client-builder mode, preserving the
facade's earlier rejection of valueless extension parameters before
connecting. Raw
header(("Accept", value)) by itself remains available for values outside the
bounded helper API.
On the server, Request::accept() and HttpRequest::accept() parse received
fields in wire order into the same protocol-owned representation exposed as
HttpAccept and HttpMediaRange. Absent metadata returns Ok(None);
malformed, duplicate, oversized, or excessive values return
HttpAcceptParseError without changing the raw headers.
These helpers only declare request metadata. RTTP does not perform automatic
representation selection, retries, redirects, caching, or server policy from
Accept.
HttpClient::expect_continue() formats the protocol-owned Expect singleton
as Expect: 100-continue. It is metadata only: the client does not delay
the request body or wait for an interim response. Raw
header(("Expect", value)) remains available for extension values outside
the typed helper. Response::informational_responses() continues to expose a
received 100 Continue alongside other bounded informational responses.
On the server, Request::expectations() and HttpRequest::expectations()
delegate to the shared protocol type and return bounded HttpExpectations
aliases. expects_continue() identifies the standardized expectation, while
unsupported() preserves extension names for handler policy. Absent fields
return Ok(None); malformed, duplicate, oversized, or excessive values
return HttpExpectParseError without changing the raw request. The server
does not automatically send 100 Continue or reject unsupported
expectations.
HttpClient::authorization(scheme, credentials) emits one validated
Authorization field from an HTTP-token scheme and a non-empty credential
value bounded to 64 KiB. The client uses the shared rttp-protocol
authorization primitive, including CR, LF, NUL, and other control-byte
injection checks. header(("Authorization", value)) remains available as the
raw escape hatch for application-specific schemes and syntaxes.
On the server, Request::authorization() and HttpRequest::authorization()
parse exactly one field into HttpAuthorization, exposing scheme() and
credentials(). Request::proxy_authorization() and
HttpRequest::proxy_authorization() parse Proxy-Authorization into
HttpProxyAuthorization with the same bounds. Absent metadata returns
Ok(None); invalid, oversized, control-byte-injected, or duplicate fields
return an error so handlers do not receive ambiguous credentials. Typed debug
output redacts credential values.
Credential interpretation remains application-owned. These helpers do not store credentials, validate individual schemes, refresh tokens, process challenges, retry requests, or forward credentials across redirects.
HttpClient::te() appends a validated transfer coding, te_with_q() accepts
an HTTP q-value from 0 through 1 with at most three fractional digits, and
te_trailers() declares support for trailers. The helpers validate each
member and the combined field through the shared protocol-owned rttp-protocol
Te type, which owns coding tokens, the chunked rejection, the
trailers-without-q-value rule, q-value thousandths, case-insensitive
duplicates, the 32-coding member bound, and the 64 KiB value bound. They emit
one comma-separated TE field and reject invalid tokens, q-values, duplicates,
oversized values, and more than 32 codings before a connection is opened.
trailers cannot carry a q-value.
On the server, Request::te() and HttpRequest::te() parse received fields in
wire order through the same protocol type into HttpRequestTe; each HttpTe
exposes coding(), optional thousandths quality(), and is_trailers(). This
is metadata parsing only: it does not implement transfer coding, trailer
negotiation, compression, or proxy behavior. Bounded h2c remains conservative:
it emits only an exact TE: trailers field and strips every other TE value
with HTTP/1.x connection-specific request metadata.
Response::www_authenticate() parses all received WWW-Authenticate fields
in wire order into bounded WwwAuthenticate challenge metadata. Challenges
expose their authentication scheme, optional token68 value, and ordered
auth-parameters with quoted-string unescaping. Absent metadata returns
Ok(None); malformed syntax, duplicate parameter names, invalid tokens,
oversized values, and excessive challenges or parameters return an error while
the raw response headers remain available.
On the server, HttpWwwAuthenticate::parse() validates the same syntax and
HttpResponse::with_www_authenticate() replaces raw WWW-Authenticate
fields with one validated value. HttpResponse::www_authenticate() parses raw
response fields on demand without changing them.
These helpers expose authentication challenges as metadata only. RTTP does not
store credentials, select an authentication policy, retry requests, generate
Authorization, implement Basic or Bearer authentication, or change redirect
behavior.
Response::proxy_authenticate() parses all received Proxy-Authenticate
fields in wire order into bounded ProxyAuthenticate challenge metadata.
Challenges expose their proxy authentication scheme, optional token68 value,
and ordered auth-parameters with quoted-string unescaping. Absent metadata
returns Ok(None); malformed syntax, duplicate parameter names, invalid
tokens, oversized values, and excessive challenges or parameters return an
error while the raw response headers remain available.
ProxyAuthenticate::parse() validates a single field value, and
ProxyAuthenticate::parse_values() preserves challenges across multiple field
values. These helpers expose proxy authentication challenges as metadata only.
RTTP does not store credentials, select a proxy authentication policy, retry
requests, generate Proxy-Authorization, implement Basic or Bearer
authentication, or change redirect behavior.
Response::proxy_status() parses all received RFC 9209 Proxy-Status fields
in wire order into bounded Token or String proxy identifiers with opaque
parameters. Absent metadata returns Ok(None); empty lists, inner-lists,
malformed syntax, control bytes, oversized values, and duplicate parameters
return an error while the raw response headers remain available.
On the server, HttpProxyStatus::parse() validates the same syntax and
HttpResponse::with_proxy_status() replaces raw Proxy-Status fields with
one validated value. HttpResponse::proxy_status() parses raw response fields
on demand without changing them.
These helpers expose Proxy-Status as metadata only. RTTP does not interpret
proxy health, retry requests, promote trailers, or generate origin
Proxy-Status values.
Response::server_timing() parses all received Server-Timing fields in wire
order into bounded ServerTiming metrics. Metrics expose their name, optional
dur duration, optional desc text, and ordered extension parameters;
duplicate metric names remain distinct. Malformed values, duplicate parameter
names, oversized values, and excessive metrics or parameters return an error
while the raw response headers remain available.
On the server, HttpServerTiming::parse() validates the same syntax and
HttpResponse::with_server_timing() replaces raw Server-Timing fields with
one validated value. HttpResponse::server_timing() parses raw response fields
on demand without changing them.
These helpers only parse and format timing metadata. They do not collect metrics, record measurements, export telemetry, or add a metrics backend.
Response::alt_used() and server HttpResponse::with_alt_used() /
HttpResponse::alt_used() parse or declare one bounded Alt-Used authority
through the shared protocol AltUsed type. Valid metadata preserves host
spelling, optional port, and bracketed IPv6 literal form. Malformed
authorities, duplicate fields, and values larger than 64 KiB are rejected
while raw headers remain available on parse failures; typed server declaration
replaces existing raw Alt-Used fields.
These helpers are metadata-only. RTTP does not select alternative services,
rewrite origins, migrate sockets, retry, or change connection policy from
Alt-Used.
Response::alternates() and server HttpResponse::with_alternates() /
HttpResponse::alternates() parse or declare bounded RFC 2295-style
Alternates variant metadata through the shared protocol Alternates type.
Valid metadata preserves ordered variant URI-references, source quality text,
standard attributes such as type, language, and length, quoted attribute
values, and extension attributes. Malformed entries, invalid URIs, invalid
quality values, duplicate variants or attributes, oversized values, and excess
variant or attribute counts are rejected while raw headers remain available on
parse failures; typed server declaration replaces existing raw Alternates
fields.
These helpers are metadata-only. RTTP does not select, rank, fetch, replay,
redirect to, or cache variants from Alternates.
Response::tcn() and server HttpResponse::with_tcn() /
HttpResponse::tcn() parse or declare bounded RFC 2295 TCN negotiation
result metadata through the shared protocol Tcn type. Valid metadata is a
singleton response field containing list, choice, adhoc, re-choose,
or keep tokens, normalized to lowercase in wire order. Duplicate fields,
duplicate tokens, malformed or unknown tokens, empty members, oversized
values, and control-byte injection return parse errors while raw response
headers remain available on accessor failures; typed server declaration
replaces existing raw TCN fields.
These helpers expose metadata only. RTTP does not select variants, synthesize
Alternates or Vary, or change cache behavior from TCN.
Response::variant_vary() and server HttpResponse::with_variant_vary() /
HttpResponse::variant_vary() parse or declare bounded RFC 2295
Variant-Vary response metadata through the shared protocol VariantVary
type. Valid metadata is either the exclusive * wildcard or an ordered list
of HTTP field-name tokens, normalized to lowercase in first-seen order.
Duplicate names, duplicate or mixed wildcards, malformed or empty members,
oversized values, and control-byte injection return parse errors while raw
response headers remain available on accessor failures; typed server
declaration replaces existing raw Variant-Vary fields.
These helpers expose metadata only. RTTP does not construct cache keys,
select variants, synthesize Alternates, TCN, or Vary, or change cache
behavior from Variant-Vary.
Response::origin_trials() and server HttpResponse::with_origin_trials() /
HttpResponse::origin_trials() parse or declare bounded opaque Origin-Trial
tokens through the shared protocol OriginTrials type. Valid metadata
preserves multiple tokens and duplicates in wire order. Each token is limited
to 8 KiB, the collection is limited to 64 tokens, and the combined token
bytes are limited to 64 KiB. Injected controls, obs-text, empty values, and
oversized collections are rejected while raw headers remain available on
parse failures; typed server declaration replaces existing raw Origin-Trial
fields and emits one header per token. Token material is redacted from debug
output.
These helpers are metadata-only. RTTP does not validate token signatures, expiration, origin applicability, or activate browser trials.
Response::warning() parses all received Warning fields in wire order into
bounded Warning warning-value metadata. Each item exposes its 3-digit
warn-code, opaque warn-agent, unescaped warn-text, and optional HTTP-date.
Absent metadata returns Ok(None); malformed quoting, invalid codes, empty
members, oversized values, and excessive items return an error while the raw
response headers remain available.
These helpers expose Warning as metadata only. RTTP does not use warn-codes as cache policy, calculate freshness, treat responses as stale, or change response acceptance.
Response::access_control_allow_credentials() parses a singleton
Access-Control-Allow-Credentials response field into
AccessControlAllowCredentials metadata. Absent metadata returns Ok(None).
The field value must be exactly the standards-defined true token, matched
case-sensitively per the Fetch %s"true" grammar and exposed in canonical
lowercase form; surrounding SP and HTAB are trimmed. Unknown tokens, empty
values, duplicate fields, oversized values, and control bytes return an error
while the raw response headers remain available through
Response::header_value() and Response::header_values().
On the server, HttpAccessControlAllowCredentials::parse() validates the same
syntax and HttpResponse::with_access_control_allow_credentials() replaces raw
Access-Control-Allow-Credentials fields with one validated value.
HttpResponse::access_control_allow_credentials() parses raw response fields
on demand without changing them.
These helpers expose credentials metadata only. RTTP does not evaluate CORS requests, attach credentials to requests, or grant credentials automatically.
Response::nel() parses the NEL response field as bounded W3C Network Error
Logging policy metadata. The policy exposes its required non-negative
max_age as u64, optional report_to name, include_subdomains flag, and
success_fraction/failure_fraction values as checked members; unknown JSON
members are preserved verbatim without policy semantics. Absent metadata
returns Ok(None); malformed JSON, invalid member types, duplicate singleton
members, non-finite or out-of-range fractions, and oversized input return an
error while the raw response headers remain available.
On the server, HttpNel::parse() validates the same syntax and
HttpResponse::with_nel() replaces raw NEL fields with one validated value.
HttpResponse::nel() parses raw response fields on demand without changing
them.
These helpers expose NEL as metadata only. RTTP does not send network error reports, persist policy, configure Reporting endpoint groups, or change redirect behavior.
Response::reporting_endpoints() parses retained Reporting-Endpoints
dictionary fields through the shared protocol type. Present values combine
all fields in wire order into at most 32 endpoint-name to quoted-URL
members. Each field value is bounded to 64 KiB, and the combined raw
field-value bytes are bounded to 64 KiB. Endpoint names are lowercase tokens
that may start with *; URLs must be quoted and unescape only \\ and
\". Absent metadata returns Ok(None); invalid names, unquoted URLs,
malformed quoted strings, duplicate names, oversized input, and too many
members return an error while the raw response headers remain available.
On the server, HttpReportingEndpoints::parse() and
HttpReportingEndpoints::from_endpoints() validate the same dictionary and
HttpResponse::with_reporting_endpoints() replaces raw
Reporting-Endpoints fields with one validated value.
HttpResponse::reporting_endpoints() parses raw response fields on demand
without changing them.
These helpers expose Reporting-Endpoints as metadata only. RTTP does not schedule, send, persist, retry, or route reports.
Response::cross_origin_opener_policy_report_only() parses retained
Cross-Origin-Opener-Policy-Report-Only fields through the shared protocol
type. Present values must be a singleton structured-field item using the
canonical COOP directives unsafe-none, same-origin-allow-popups,
same-origin, or noopener-allow-popups. Well-formed parameters are retained;
report-to is exposed as a reporting-endpoint name when present. Each field
value is bounded to 64 KiB. Absent metadata returns Ok(None); duplicate
fields, duplicate parameter names, unknown directives, malformed structured
fields, and oversized values return an error while the raw response headers
remain available.
On the server, HttpCrossOriginOpenerPolicyReportOnly::parse() validates the
same syntax and HttpResponse::with_cross_origin_opener_policy_report_only()
replaces raw Cross-Origin-Opener-Policy-Report-Only fields with one
validated value. HttpResponse::cross_origin_opener_policy_report_only()
parses raw response fields on demand without changing them.
These helpers expose COOP Report-Only as metadata only. RTTP does not isolate
browsing contexts, validate Reporting-Endpoints members, deliver reports, or
schedule report delivery.
Client Response::keep_alive() and server HttpResponse::keep_alive() parse
all received Keep-Alive fields in wire order into bounded RFC 2068
HttpKeepAlive metadata; HttpResponse::with_keep_alive validates and
replaces the Keep-Alive response field. The optional timeout delta-seconds
and optional max 1*DIGIT values are parsed as checked unsigned integers;
unrecognized name=token parameters are preserved as bounded extension
metadata. Duplicate recognized parameters, malformed values, overflow,
oversized values, and excessive elements return an error while the raw response
headers remain available.
These helpers expose Keep-Alive as metadata only. RTTP does not change connection lifetime, connection pooling, keep-alive timers, or HTTP/2 behavior.
Request::max_forwards() and HttpRequest::max_forwards() reuse the shared
protocol Max-Forwards type. They return Ok(None) when the field is absent
and otherwise expose one singleton 1*DIGIT hop count that fits in u32
(0 through 4294967295). Duplicate, empty, signed, non-decimal, overflowing,
oversized (over 64 KiB), or control-byte values return a parse error while
header("Max-Forwards") continues to expose the raw field. The client helper
HttpClient::max_forwards() validates and emits the same type. RTTP does not
decrement the value, route the request, select TRACE or OPTIONS, or infer
forwarding behavior.
HttpClient::depth() validates and emits one WebDAV Depth request field
through the shared protocol Depth type, replacing any existing same-name
field before a socket is opened. Request::depth() and
HttpRequest::depth() parse received fields into the same HttpDepth
representation, returning Ok(None) when absent. Recognized values are the
singleton depth values 0, 1, and infinity, bounded to 64 KiB with
optional surrounding SP or HTAB; malformed, duplicate, oversized, and
control-byte values are rejected while raw request headers remain available
when the typed parser reports an error. RTTP does not traverse resources,
select WebDAV methods, or enforce method policy.
HttpClient::destination() validates and emits one WebDAV Destination
request field through the shared protocol Destination type, replacing any
existing same-name field before a socket is opened. Request::destination()
and HttpRequest::destination() parse received fields into the same
HttpDestination representation, returning Ok(None) when absent. A
recognized value is one absolute URI, bounded to 64 KiB with optional
surrounding SP or HTAB; the trimmed URI string is preserved without
resolution or normalization. Malformed, relative, duplicate, oversized, and
control-byte values are rejected while raw request headers remain available
when the typed parser reports an error. RTTP does not resolve the
destination, authorize the target URI, select WebDAV methods, or copy, move,
or delete application resources.
HttpClient::lock_token() validates and emits one WebDAV Lock-Token
request field through the shared protocol LockToken type, replacing any
existing same-name field before a socket is opened. Request::lock_token()
and HttpRequest::lock_token() parse received request fields into the same
HttpLockToken representation, returning Ok(None) when absent.
HttpResponse::with_lock_token() validates and replaces one response field,
and HttpResponse::lock_token() plus client Response::lock_token() parse
attached or received response metadata. A recognized value is exactly one
angle-bracketed absolute URI, bounded to 64 KiB with optional surrounding SP
or HTAB; empty, unbracketed, relative, comma-list, extra-bracket, duplicate,
oversized, and control-byte values are rejected while raw headers remain
available when the typed parser reports an error. The token is redacted from
typed Debug, and parse or builder errors do not expose the full token.
These helpers declare and observe metadata only: RTTP does not create,
refresh, release, persist, compare ownership of, or enforce WebDAV locks.
HttpClient::timeout() validates and emits one WebDAV Timeout request
field through the shared protocol Timeout type, replacing any existing
same-name field before a socket is opened. Request::timeout() and
HttpRequest::timeout() parse received fields into the same HttpTimeout
representation, returning Ok(None) when absent. Recognized values are
ordered Second-n and Infinite alternatives, bounded to 64 KiB per field
and 64 KiB aggregate with at most 32 members; malformed, overflowing,
duplicate, oversized, too-many-member, and control-byte values are rejected
while raw request headers remain available when the typed parser reports an
error. RTTP does not create locks, refresh locks, or select an application
timeout.
HttpClient::if_schedule_tag_match() validates and emits one
If-Schedule-Tag-Match request field through the shared protocol
IfScheduleTagMatch type, which reuses the shared EntityTag
representation, replacing any existing same-name field before a socket is
opened. Request::if_schedule_tag_match() and
HttpRequest::if_schedule_tag_match() parse received fields into the same
representation, returning Ok(None) when absent. A recognized value is one
entity-tag-shaped schedule validator such as "sched-17" or W/"sched-17",
bounded to 64 KiB with optional surrounding SP or HTAB and weak syntax
preserved; malformed, wildcard, comma-list, duplicate, oversized, and
control-byte values are rejected while raw request headers remain available
when the typed parser reports an error. These helpers declare and observe
request metadata only: RTTP does not compare the validator to stored calendar
state, inspect calendars, select scheduling behavior, or apply 412 or
scheduling policy.
HttpClient::overwrite() validates and emits one WebDAV Overwrite request
field through the shared protocol Overwrite type, replacing any existing
same-name field before a socket is opened. Request::overwrite() and
HttpRequest::overwrite() parse received fields into the same
HttpOverwrite representation, returning Ok(None) when absent. Recognized
values are the singleton tokens T and F, bounded to 64 KiB with optional
surrounding SP or HTAB and case-sensitive matching; malformed, duplicate,
oversized, and control-byte values are rejected while raw request headers
remain available when the typed parser reports an error. RTTP does not
overwrite destination resources, apply the RFC 4918 default T when the
field is absent, or enforce WebDAV policy.
HttpClient::if_header() validates and emits one RFC 4918 section 10.4
WebDAV If request field through the shared protocol If type, replacing
any existing same-name field (without touching If-Match) before a socket
is opened. Request::if_header() and HttpRequest::if_header() parse
received fields into the same HttpIf representation, returning Ok(None)
when absent. A recognized value is either entirely untagged
((<opaquelocktoken:...>) (Not <DAV:no-lock>)) or entirely tagged
(<http://example.test/src> (<opaquelocktoken:...>) </dst> (Not <DAV:no-lock>));
mixed productions are rejected. Each field value and the aggregate input are
bounded to 64 KiB, the combined value is bounded to 32 lists and 256
conditions. Resource tags accept an RFC 3986 Simple-ref (absolute-URI or
path-absolute with optional query); state tokens are absolute coded URLs,
including <DAV:no-lock>; conditions accept the case-sensitive Not token
only when it is followed by SP or HTAB and then a state token or a bracketed
entity tag ([W/"etag"]). List
order, repeated lists, and resource tags are preserved, and header_value()
re-emits the canonical field text. Empty, unterminated, mixed, malformed,
duplicate, oversized, too-many-list, too-many-condition, and control-byte
values are rejected while raw request headers remain available when the
typed parser reports an error. State tokens are redacted from typed Debug
and raw-header debug output. These helpers declare and observe request
metadata only: RTTP does not evaluate locks, entity tags, or other resource
state, and it does not generate precondition outcomes such as 412
Precondition Failed.
Workspace HTTP/1.1 and h2c integration tests cover a metadata-only WebDAV
matrix for Depth, Destination, Overwrite, Timeout, Lock-Token,
If, DAV, If-Schedule-Tag-Match, and Schedule-Tag, including valid
roundtrips, malformed and duplicate rejection, bounds, raw-header
observability, and Lock-Token/If redaction. Those helpers still do not
store resources, create locks, or enforce WebDAV method policy.
HttpClient::idempotency_key() validates and emits one opaque Idempotency-Key
request field through the shared protocol IdempotencyKey type, replacing any
existing same-name field before a socket is opened. Request::idempotency_key()
and HttpRequest::idempotency_key() parse received fields into the same
representation, returning Ok(None) when absent. A recognized value is a
singleton key of one or more visible ASCII characters bounded to 64 KiB with
optional surrounding SP or HTAB; empty, space-containing, control-byte
(including CR/LF/NUL and obs-text), duplicate, and oversized values are
rejected. The key is redacted from typed Debug, and raw request headers
remain available when the typed parser reports an error. These helpers declare
and observe request metadata only: RTTP does not retry requests, store or
compare keys across requests, deduplicate requests, or apply application
idempotency policy.
HttpClient::sec_websocket_key() validates and emits one Sec-WebSocket-Key
request field through the shared protocol SecWebSocketKey type, replacing
any existing same-name field before a socket is opened. Request::sec_websocket_key()
and HttpRequest::sec_websocket_key() parse received fields into the same
representation, returning Ok(None) when absent. A recognized value is a
singleton RFC 4648 section 4 base64 encoding of exactly 16 nonce bytes bounded
to 64 KiB with optional surrounding SP or HTAB; empty, interior-whitespace,
non-base64, URL-safe or unpadded, wrong-decoded-length, control-byte
(including CR/LF/NUL and obs-text), duplicate, and oversized values are
rejected. Server responses can derive bounded singleton Sec-WebSocket-Accept
metadata from a validated key using the RFC 6455 GUID plus SHA-1 and base64
transform; clients can parse Response::sec_websocket_accept() and verify it
with verify_sec_websocket_accept(&key). The RFC example key
dGhlIHNhbXBsZSBub25jZQ== maps to s3pPLMBiTxaQ9kYGzzhZRbK+xOo=.
Key and accept values are redacted from typed Debug, and raw request headers
remain available when the typed parser reports an error. Workspace integration
tests cover live HTTP/1.1 and h2c metadata-only roundtrips for these handshake
headers across the client, server, and compatibility facade. These helpers
declare and observe handshake metadata only: RTTP does not perform an HTTP
upgrade, generate a random nonce, or implement WebSocket frames.
HttpClient::sec_websocket_version() validates and emits
Sec-WebSocket-Version request metadata through the shared protocol
SecWebSocketVersion type, replacing any existing same-name field before a
socket is opened. Request::sec_websocket_version() and
HttpRequest::sec_websocket_version() parse received fields into the same
representation, returning Ok(None) when absent.
HttpResponse::with_sec_websocket_version(versions) declares validated
rejection-response metadata without adding Connection or Upgrade, and
HttpResponse::sec_websocket_version() plus client
Response::sec_websocket_version() parse attached or received fields.
Recognized values are RFC 6455 version tokens (0 through 299 without
leading zeros) in numeric descending order, such as 13 or 13, 8, 7. Empty
members, non-decimal tokens, leading-zero multi-digit tokens, duplicates,
unordered lists, control-byte, over-limit, and oversized values are rejected
while raw headers remain available. These helpers declare and observe
metadata only: RTTP does not perform a WebSocket handshake, emit
Connection: Upgrade, compute Sec-WebSocket-Accept, negotiate versions, or
switch protocols.
HttpClient::sec_websocket_protocol() validates and emits
Sec-WebSocket-Protocol request metadata as offers in preference order
through the shared protocol SecWebSocketProtocol type, replacing any
existing same-name field before a socket is opened. Recognized members are
RFC 6455 section 11.3.4 token values such as chat, superchat, or
graphql-transport-ws, compared case-sensitively. Empty members, malformed
tokens, parameters, slashes, case-sensitive duplicates, control-byte,
over-limit, and oversized values are rejected while raw headers remain
available. Client Response::sec_websocket_protocol() parses received
fields as a selection singleton; a multi-token value returns a parse error.
These helpers declare and observe metadata only: RTTP does not perform a
WebSocket handshake, emit Connection: Upgrade, choose an application
subprotocol, or switch protocols. Applications own the selection decision.
HttpClient::sec_websocket_extensions() validates and emits
Sec-WebSocket-Extensions request metadata as ordered extension offers
through the shared protocol SecWebSocketExtensions type, replacing any
existing same-name field before a socket is opened. The canonical
representation validates extension tokens, ordered parameters, token and
quoted-string parameter values, duplicate extension tokens, duplicate
parameter names, member counts, and total size. Server request helpers parse
received offers, and HttpResponse::with_sec_websocket_extensions() plus
client/server response accessors parse one selected extension member. These
helpers declare and observe metadata only: RTTP does not activate compression,
negotiate extensions, emit Connection: Upgrade, or switch protocols.
HttpClient::traceparent() and HttpClient::tracestate() validate and emit
bounded W3C Trace Context request metadata through shared protocol types,
replacing existing same-name fields before a socket is opened.
Request::traceparent() / HttpRequest::traceparent() and
Request::tracestate() / HttpRequest::tracestate() parse received fields,
returning Ok(None) when absent and preserving raw headers on parse errors.
Traceparent validation checks version 00, rejects version ff and
unsupported versions, malformed or uppercase identifiers, malformed flags,
duplicates, and all-zero trace or parent identifiers. Tracestate validation
preserves member order while bounding total size, member count, key/value size,
member grammar, and duplicate keys. Typed Debug redacts propagation values.
These helpers declare and observe request metadata only: RTTP does not create
trace identifiers, decide sampling, select a tracing backend, or automatically
propagate context.
HttpClient::baggage() validates and emits bounded W3C Baggage request
metadata through the shared protocol Baggage type, replacing any existing
baggage field before a socket is opened. Request::baggage() and
HttpRequest::baggage() parse received fields, returning Ok(None) when
absent and preserving raw headers on parse errors. Validation checks HTTP
token keys, baggage-octet values, optional properties, duplicate member keys,
member order, at most 180 members, 4096-byte per-member limits, and an 8192-byte
combined size. Typed Debug and builder or parse errors redact member and
property values. These helpers declare and observe request metadata only:
RTTP does not interpret application baggage data, store request context,
select a tracing backend, or automatically propagate baggage.
HttpClient::te(), te_with_q(), and te_trailers() build a single bounded
TE field validated through the shared protocol-owned rttp-protocol Te
type. HttpClient::prefer() and prefer_with_value() build a single
bounded Prefer field. Prefer values are limited to 8 KiB and wait accepts
only unsigned decimal integers. Both client helpers reject malformed tokens,
invalid q-values, duplicates, oversized field values, and more than 32 members
before opening a connection; TE: chunked is rejected because request framing
remains owned by the existing HTTP/1 implementation.
On the server, Request::te()/HttpRequest::te() parse ordered TE codings
and their q-values, while Request::prefer()/HttpRequest::prefer() parse
ordered token-only Prefer items, including validated wait values. Absent
fields return Ok(None) and invalid, duplicate, oversized, or excessive values
return a parse error without changing the request's raw headers.
These APIs only declare or parse HTTP/1.1 metadata. They do not add transfer coding engines, trailer scheduling, proxy routing, automatic retries, automatic preference handling, cache policy, or forwarding behavior.
HttpClient::x_forwarded_for(), x_forwarded_host(), and
x_forwarded_proto() validate and emit bounded compatibility request metadata
through shared protocol-owned XForwardedFor, XForwardedHost, and
XForwardedProto types. Repeated helper calls combine existing same-name
fields in wire order before a socket is opened. Server-side Request and
HttpRequest helpers parse the same representations, return Ok(None) when
absent, and preserve raw headers on parse errors.
X-Forwarded-For accepts ordered IP node values and unknown,
X-Forwarded-Host accepts ordered host authorities, and X-Forwarded-Proto
accepts ordered URI scheme tokens. Each field family is bounded to 64 KiB per
field value, 64 KiB for the combined raw field set including ", " separator
overhead, 64 KiB for serialized output, and 256 members. Empty members,
malformed values, control-byte injection, and bound violations are rejected.
These helpers are compatibility metadata only. RTTP does not trust, rewrite, or enforce forwarded identity, select a client address, change routing, redirect, upgrade, or choose a trusted proxy set. Applications that use these fields must choose and enforce their own trusted proxies.
HttpClient::via() validates and emits bounded HTTP Via request metadata
through the shared protocol-owned Via type. Repeated helper calls combine
existing same-name fields in wire order before a socket is opened.
Server-side Request and HttpRequest helpers parse the same
representation, return Ok(None) when absent, and preserve raw headers on
parse errors. Response::via() parses received response hops.
HttpResponse::with_via() replaces raw response fields with one validated
caller-supplied chain, and HttpResponse::via() parses attached raw fields.
Via preserves optional protocol name, protocol version, received-by,
comments, duplicates, and ordering. Each field family is bounded to 64 KiB
per field value, 64 KiB for the combined raw field set including ", "
separator overhead, 64 KiB for serialized output, 256 members, and 128
comment nesting levels. Empty members, malformed hops, control-byte
injection, and bound violations are rejected.
These helpers are hop metadata only. RTTP does not append or remove hops, infer trusted proxies, rewrite identity, or change HTTP/1.1 or HTTP/2 proxy policy.
Response::connection() parses retained HTTP/1 Connection fields into
Connection header metadata. It returns Ok(None) when the header is absent.
Present values combine case-insensitive fields in wire order and preserve
token spelling, including duplicates. Connection::parse(value) is available
when callers want to validate one raw field value directly.
On the server, Request::connection(), HttpRequest::connection(), and
HttpResponse::connection() parse the same bounded token list from already
retained HTTP/1 headers. Absent fields return Ok(None).
Each field value is limited to 64 KiB. Parsing accepts at most 256 tokens and
rejects empty members, malformed tokens, parameters, oversized values, and too
many tokens. Parse errors do not reject the raw message: original headers
remain available. HTTP/2 continues to reject inbound Connection at decode
time. These helpers do not change keep-alive, hop-by-hop stripping,
upgrade/h2c, or HTTP/2 rejection.
HttpClient::upgrade_protocols() validates and replaces request Upgrade
metadata without changing request method, socket handoff, or Connection
handling. Response::upgrade() parses retained HTTP/1 Upgrade response
fields into Upgrade metadata.
On the server, Request::upgrade(), HttpRequest::upgrade(), and
HttpResponse::upgrade() parse retained HTTP/1 Upgrade fields into
HttpUpgrade metadata. HttpResponse::with_upgrade() validates and replaces
attached response Upgrade metadata. Absent fields return Ok(None), and
present values combine fields in wire order while preserving protocol
spelling.
Each field value is limited to 64 KiB. Parsing accepts at most 32 protocols.
Each protocol must be an HTTP token, optionally followed by / and a token
protocol version. Empty members, malformed protocols, control bytes,
oversized values, and too many protocols return a parser error while raw
headers remain available.
These helpers expose HTTP/1 header metadata only. They do not add
Connection: Upgrade, select h2c, perform client upgrade() handoff, change
server HttpHandoff::upgrade socket handoff, or implement the upgraded
protocol.
Response::transfer_encoding() parses retained HTTP/1 Transfer-Encoding
fields into TransferEncoding metadata. It returns Ok(None) when the header
is absent. Present values combine case-insensitive fields in wire order and
must yield a sole chunked coding, matching existing HTTP/1 framing.
TransferEncoding::parse(value) is available when callers want to validate
one raw field value directly.
On the server, Request::transfer_encoding() and
HttpRequest::transfer_encoding() parse the same sole-chunked metadata from
already-validated HTTP/1 request headers. Absent fields return Ok(None).
Each field value is limited to 64 KiB. Parsing accepts at most 256 tokens and
rejects empty members, malformed tokens, stacked or non-final chunked
codings, combined duplicate fields that are no longer sole chunked,
oversized values, and too many tokens. Parse errors do not reject the raw
message: original headers remain available. HTTP/2 continues to reject
Transfer-Encoding at decode time. These helpers do not change HTTP/1
framing decoders, TE, Content-Length, or HTTP/2 decode.
HttpClient::origin(value) emits one validated Origin field, accepting
null or an http/https tuple origin without a path, query, fragment, or
userinfo. HttpClient::access_control_request_method(value) emits one
Access-Control-Request-Method field from a single HTTP method token.
HttpClient::access_control_request_headers(field_names) emits one
Access-Control-Request-Headers field from a bounded field-name list,
normalized to lowercase with duplicates rejected.
HttpClient::access_control_request_private_network() emits
Access-Control-Request-Private-Network: true.
These helpers reject invalid input before a socket is opened: origins with a
path, query, fragment, userinfo, or non-http(s) scheme; methods that are
*, comma-separated, or not HTTP tokens; and field names that are malformed,
duplicated, or excessive. Values are bounded to 64 KiB and the field-name list
to 256 entries. Callers that need values outside the helper validation can
retain raw-header control with header(("Origin", "...")) and the other
header forms.
These helpers only declare preflight request metadata. RTTP does not decide
whether a preflight is needed, read Access-Control-Allow-* response fields,
apply CORS policy, or apply Private Network Access policy.
HttpClient::save_data() emits Save-Data: on. On the server,
Request::save_data() and HttpRequest::save_data() parse the same bounded
singleton on token, returning Ok(None) when the field is absent and a
parser error for malformed, oversized, duplicate, or control-byte values
while leaving the raw Save-Data field available.
These helpers only declare or parse request metadata. RTTP does not select a representation, compress a body, advertise Client Hints, or apply browser data-saver policy.
HttpClient::dnt(value) emits one DNT field from the user's declared
tracking preference. The value must be the W3C Tracking Preference Expression
token 0 (allow tracking) or 1 (do not track), validated through the shared
protocol Dnt type; malformed, oversized, or control-byte input is rejected
before a socket is opened. On the server, Request::dnt() and
HttpRequest::dnt() parse the same bounded singleton preference as HttpDnt,
returning Ok(None) when the field is absent and a parser error for
malformed, oversized, duplicate, or control-byte values while leaving the raw
DNT field available.
DNT is the first shared privacy-preference primitive. These helpers only
declare or parse request metadata: RTTP does not disable cookies, strip
Referer, change analytics or advertising behavior, synthesize a Tk
response field, or enforce tracking policy. Related privacy-preference headers
should reuse this same bounded singleton contract rather than inventing policy
behavior.
HttpClient::sec_gpc() emits Sec-GPC: 1. On the server,
Request::sec_gpc() and HttpRequest::sec_gpc() parse the same bounded
singleton 1 signal through the shared protocol representation, returning
Ok(None) when the field is absent and a parser error for malformed,
oversized, duplicate, or control-byte values while leaving the raw Sec-GPC
field available.
These helpers only declare or parse request metadata. RTTP does not infer or enforce consent, tracking, legal, or serving policy.
rttp-protocol owns the shared Pragma primitive. Client helpers format
through that type, and server Request / HttpRequest plus client and server
response helpers parse with the same rules.
HttpClient::pragma(value) and HttpClient::pragma_no_cache() emit bounded
RFC 9111 Pragma request metadata, combining and replacing already-attached
same-name fields. Response::pragma() parses the same representation on the
client. On the server, Request::pragma() and HttpRequest::pragma() parse
received fields into HttpPragma, and HttpResponse::with_pragma(value)
declares validated response metadata that replaces attached same-name fields.
HttpResponse::pragma() parses attached response fields. Absent fields return
Ok(None). Multiple fields are combined in wire order, directive names are
matched case-insensitively, duplicate names are rejected, each field value is
bounded to 64 KiB, combined field values are bounded to 64 KiB including
", " separator overhead, each directive value is bounded to 64 KiB, and the
combined directive count is bounded to 256. Malformed tokens or
quoted-strings, valued no-cache forms, empty members, and bound violations
return a parser error while raw headers remain available.
These helpers only declare or parse metadata. RTTP does not translate Pragma
into Cache-Control, store cache entries, or apply cache, freshness,
revalidation, intermediary, or HTTP/1.0 compatibility policy.
HttpClient::upgrade_insecure_requests() emits Upgrade-Insecure-Requests: 1.
On the server, Request::upgrade_insecure_requests() and
HttpRequest::upgrade_insecure_requests() parse the same bounded singleton
1 token, returning Ok(None) when the field is absent and a parser error for
malformed, oversized, duplicate, or control-byte values while leaving the raw
Upgrade-Insecure-Requests field available.
These helpers only declare or parse request metadata. RTTP does not rewrite
http:// URLs to https://, redirect requests, or enforce
Content-Security-Policy.
Response::vary() parses one or more response Vary header fields into
Vary metadata. A parsed value is either the wildcard form, exposed by
Vary::is_any(), or a bounded list of normalized field names exposed by
Vary::field_names() and checked with Vary::contains_field_name(name).
Field-name comparison is case-insensitive, and parsed field names are
deduplicated in lowercase form.
Vary: * is treated as a distinct wildcard result: it means the response
cannot be selected by comparing a bounded set of request header fields. The
wildcard form cannot be combined with named fields. Each Vary field value is
limited to 64 KiB, the parsed field-name list is limited to 256 entries, and
each named member must be a valid HTTP token. Empty members, malformed field
names, mixed wildcard/named values, oversized values, and too many field names
make Response::vary() return an error while leaving the original response
headers and body available through the ordinary response APIs.
The helper is metadata-only. RTTP does not store cache entries, match stored
responses, persist cache keys, replay requests, enforce shared-cache policy, or
issue automatic conditional requests based on Vary.
Response::no_vary_search() parses one or more No-Vary-Search response
fields as bounded Structured Fields dictionary metadata. The typed value
exposes recognized key-order, params, and except members and keeps
extension dictionary members as metadata. Parse errors are returned by the
typed helper while raw headers remain available.
This helper does not create cache storage, match cache keys, normalize URLs, replay requests, apply browser navigation behavior, or enforce shared-cache policy.
Response::permissions_policy() parses one or more Permissions-Policy
response fields through the shared protocol parser as bounded W3C Permissions
Policy dictionary metadata. The typed value exposes ordered feature directives
with their allowlists: the * token as the whole allowlist, the self token,
quoted serialized HTTP(S) origins, and inner lists including the empty ()
form. Parse errors are returned by the typed helper while raw headers remain
available.
The helper is metadata-only. RTTP does not grant or deny browser permissions,
compare origins, resolve self, enable or disable APIs, or enforce origin
policy, and it does not send reports.
Response::document_policy() parses one or more Document-Policy response
fields through the shared protocol parser as bounded WICG Document Policy
dictionary metadata. The typed value exposes ordered configuration-point
directives with their typed values: boolean (including a bare ?1), integer,
decimal, or token. Directive names are opaque lowercase tokens or * and are
not looked up against a browser configuration-point list. A well-formed
report-to parameter is accepted as a token or a quoted string and retained
on the directive. Parse errors are returned by the typed helper while raw
headers remain available.
The helper is metadata-only. RTTP does not execute configuration points, block
document loads, compare required policies, echo Sec-Required-Document-Policy,
enable or disable browser features, or send reports.
Response::document_policy_report_only() parses
Document-Policy-Report-Only response fields through the same shared
protocol parser, formatter, directive model, and bounds while returning the
distinct DocumentPolicyReportOnly metadata type. It preserves raw response
headers on parse errors and does not enforce policy or deliver reports.
Response::supports_loading_mode() parses one or more Supports-Loading-Mode
response fields through the shared protocol parser as bounded Structured
Fields token-list metadata, combining fields in wire order. The typed value
exposes the ordered tokens with tokens(), membership checks with
contains(token), and exact predicates for the defined fenced-frame,
credentialed-prerender, and prerender-cross-origin-frames tokens;
well-formed unknown tokens such as uncredentialed-prerender are retained.
Each field value is limited to 64 KiB, the combined raw bytes across fields
are limited to 64 KiB, and the token count is limited to 256 per header set.
Duplicate tokens are rejected with ASCII case-insensitive comparison. Parse
errors are returned by the typed helper while raw headers remain available.
The helper is metadata-only. RTTP does not prerender documents, admit fenced frames, change navigation, or alter resource loading based on this field.
Response::speculation_rules() parses one Speculation-Rules response field
through the shared protocol type as bounded opaque metadata. The field value is
limited to 64 KiB, duplicate fields fail closed, and control bytes that could
inject response fields are rejected. Typed Debug and typed parse errors do
not dump the field value. RTTP does not fetch, parse, validate, or execute
speculation rule resources.
Trailer support is explicit and bounded by protocol path. On the client,
HttpClient::trailer configures request trailer fields. Those fields are sent
for HTTP/1.1 only by emit_streaming_chunked; fixed-length HTTP/1.1 requests
and buffered emit requests do not have an HTTP/1.1 trailer section. With the
http2 feature enabled, the same configured request trailers are sent as
HTTP/2 trailing HEADERS by both emit_http2_prior_knowledge and the explicit
emit_http2_upgrade h2c path after request DATA for buffered POST, PUT, and
PATCH requests. The bounded h2c client rejects request trailers for
http2_extended_connect, and the bodyless GET, HEAD, DELETE, OPTIONS, and
TRACE paths cannot carry request DATA before trailers.
Response trailers are read through the existing Response trailer accessors.
For HTTP/1.1, RTTP exposes only trailers that arrive in a chunked response
after the terminating zero-size chunk. For bounded h2c, peer response trailers
arrive as trailing HEADERS on the active stream and are exposed through the
same accessors. In both request and response directions, trailer names must be
ordinary field names: HTTP/2 pseudo-headers and fields reserved for connection
state, routing, authentication/cookies, transfer framing, or payload framing
are rejected instead of passed to application code.
HTTP/2 trailer support does not make the generic HTTP/1.1 upgrade() or
CONNECT handoff paths parse trailers. The h2c Upgrade client path is opt-in
through emit_http2_upgrade and replaces the initial HTTP/1.1 exchange with
the bounded HTTP/2 stream model after 101 Switching Protocols; non-h2c
Upgrade handoffs remain caller-owned bytes.
With the http2 feature enabled, RTTP supports large HTTP/2 header blocks by
splitting outbound HEADERS or trailing HEADERS into an initial HEADERS frame
followed by CONTINUATION frames when the encoded HPACK block is larger than the
active peer SETTINGS_MAX_FRAME_SIZE. The same bounded decoder reassembles
inbound HEADERS plus CONTINUATION fragments before normal HPACK decoding and
header-list validation. This applies to request headers, response headers, and
trailing HEADERS on the bounded h2c paths.
Frame-size settings remain frame limits, not metadata-size limits. A legal
peer SETTINGS_MAX_FRAME_SIZE value from 16,384 through 16,777,215 bytes
controls how RTTP fragments outbound header blocks, DATA, and trailing
HEADERS. Inbound frames larger than the active local frame-size limit are
rejected even if their decoded metadata would otherwise be acceptable. Decoded
metadata is still bounded separately by SETTINGS_MAX_HEADER_LIST_SIZE and by
the HPACK dynamic table limits documented for the client and server paths.
CONTINUATION ordering is strict. Once a HEADERS frame starts a header block
without END_HEADERS, only CONTINUATION frames for that same stream may appear
until END_HEADERS closes the block. RTTP rejects orphan CONTINUATION frames,
CONTINUATION on stream 0, CONTINUATION on the wrong stream, interleaved DATA or
control frames before END_HEADERS, and EOF before a pending header block is
closed. Rejected header-block ordering failures happen before handler dispatch
or before a client response is returned.
The behavior is the same h2c stream model after both entry points:
emit_http2_prior_knowledge and explicit emit_http2_upgrade on the client,
and HTTP/2 prior-knowledge preface detection or valid Upgrade: h2c on the
server. Generic HTTP/1.1 Upgrade, CONNECT, proxy, TLS ALPN, server push,
extension callback, persistent session, and unbounded multiplexing paths do not
gain additional HTTP/2 header-block handling.
| area | tested coverage | limits |
|---|---|---|
| HTTP/1.1 response parsing | Content-Length, chunked transfer coding, chunk extensions, informational responses, Response::is_informational, is_redirection, is_error, bodyless 204/304, duplicate Set-Cookie, and framing ambiguity rejection |
Not a complete RFC conformance suite |
| HTTP/1.1 request emission | Origin-form requests, absolute-form proxy requests, CONNECT, HEAD, fixed bodies, streaming chunked uploads, and explicit Expect: 100-continue metadata through the shared protocol type |
Expect metadata does not gate body transmission; raw header(("Expect", value)) remains an escape hatch; SOCKS handshakes are delegated to the socks crate |
| Fetch Metadata | Client sec_fetch_site, sec_fetch_mode, sec_fetch_dest, sec_fetch_user, and sec_purpose emit bounded Sec-Fetch-*/Sec-Purpose fields; server Request helpers parse typed received values while preserving raw headers on errors |
No browser security policy, request blocking, origin validation, navigation policy, automatic header generation, prefetch execution, or cache behavior |
| Save-Data | Client save_data emits bounded Save-Data: on request metadata; server Request::save_data() and HttpRequest::save_data() parse typed received values while preserving raw headers on errors |
No reduced-data serving, content adaptation, compression, Client Hints advertisement, retries, or browser data-saver policy |
| DNT | Client dnt emits bounded DNT: 0/DNT: 1 request metadata through the shared protocol Dnt type and rejects invalid input before connecting |
No tracking enforcement, cookie changes, Referer stripping, analytics or advertising behavior, Tk emission, retries, or privacy-preference policy |
| Accept | Client accept and accept_with_q format bounded Accept request metadata through the shared rttp-protocol type; server Request::accept() and HttpRequest::accept() parse received fields into HttpAccept while preserving raw headers on errors |
No content negotiation, representation selection, MIME sniffing, body decoding, cache Vary synthesis, or response choice |
| Accept-Charset | Client accept_charset and accept_charset_with_q format bounded Accept-Charset request metadata through the shared rttp-protocol type; server Request::accept_charset() and HttpRequest::accept_charset() parse received fields into HttpRequestAcceptCharsets |
No content negotiation, charset transcoding, body decoding, MIME sniffing, or response selection |
| Negotiate | Client negotiate emits bounded RFC 2295 Negotiate request metadata through the shared rttp-protocol type, replacing an existing same-name field; server Request::negotiate() and HttpRequest::negotiate() parse received fields into HttpNegotiate while preserving raw headers on errors |
No variant selection, transparent content negotiation, Alternates/TCN/Vary synthesis, or automatic cache selection |
| TCN | Client Response::tcn() and server HttpResponse::with_tcn()/tcn() share bounded RFC 2295 TCN response metadata through the protocol Tcn type while preserving raw headers on accessor errors |
No variant selection, Alternates/Vary synthesis, transparent content negotiation, or cache behavior |
| Set-Cookie | Client Response::set_cookies() and server HttpResponse::with_set_cookie()/set_cookies() share bounded protocol Set-Cookie response metadata, preserve multiple field lines and raw headers, redact cookie values from typed debug and errors, and reject invalid typed metadata including duplicate attributes, valued flag attributes, non-standard SameSite, invalid Max-Age, malformed quoted values, and bounds violations; client Response::cookies()/cookie() are a legacy compatibility view that only exposes protocol-accepted fields and silently omits invalid Set-Cookie fields while raw headers remain available |
No cookie jar, persistence, domain/path matching, expiry enforcement, SameSite or partitioning policy, or automatic request Cookie emission |
| Variant-Vary | Client Response::variant_vary() and server HttpResponse::with_variant_vary()/variant_vary() share bounded RFC 2295 Variant-Vary response metadata through the protocol VariantVary type while preserving raw headers on accessor errors |
No cache-key construction, variant selection, Alternates/TCN/Vary synthesis, transparent content negotiation, or cache behavior |
| Sec-GPC | Client sec_gpc emits bounded Sec-GPC: 1 request metadata; server Request::sec_gpc() and HttpRequest::sec_gpc() parse typed received values while preserving raw headers on errors |
No consent inference, tracking-policy enforcement, legal policy, serving policy, retries, or browser state |
| Upgrade-Insecure-Requests | Client upgrade_insecure_requests emits bounded singleton Upgrade-Insecure-Requests: 1 request metadata; server Request::upgrade_insecure_requests() and HttpRequest::upgrade_insecure_requests() parse typed received values while preserving raw headers on errors |
No URL rewriting, redirecting, Content-Security-Policy enforcement, HSTS, or automatic scheme selection |
| Depth | Client depth emits bounded singleton WebDAV Depth request metadata through the shared protocol type, replacing an existing same-name field; server Request::depth() and HttpRequest::depth() parse typed received values while preserving raw headers on errors |
No resource traversal, WebDAV method selection, method-policy enforcement, retry, or forwarding policy |
| Destination | Client destination emits bounded singleton WebDAV Destination request metadata through the shared protocol type, replacing an existing same-name field; server Request::destination() and HttpRequest::destination() parse typed received values while preserving raw headers on errors |
No destination resolution, URI normalization, authorization, COPY/MOVE execution, or application resource policy |
| Lock-Token | Client lock_token emits bounded singleton WebDAV Lock-Token request metadata through the shared protocol type, replacing an existing same-name field; server Request::lock_token() and HttpRequest::lock_token() parse typed request values, server responses can declare or parse Lock-Token, and client Response::lock_token() parses typed response values while preserving raw headers on errors and redacting tokens from typed debug output |
No lock creation, refresh, release, persistence, ownership comparison, or WebDAV lock policy |
| Timeout | Client timeout emits bounded ordered WebDAV Timeout request metadata through the shared protocol type, replacing an existing same-name field; server Request::timeout() and HttpRequest::timeout() parse typed received values while preserving raw headers on errors |
No lock creation, lock refresh, application-timeout selection, retry, or forwarding policy |
| If-Schedule-Tag-Match and Schedule-Tag | Client if_schedule_tag_match emits bounded singleton If-Schedule-Tag-Match request metadata, client Response::schedule_tag() parses bounded singleton Schedule-Tag response metadata, and server Request::if_schedule_tag_match()/HttpRequest::if_schedule_tag_match() plus HttpResponse::with_schedule_tag()/schedule_tag() share protocol types backed by EntityTag |
No calendar-version generation, schedule-tag comparison, calendar inspection, scheduling policy, retry, or 412/status-policy behavior |
| Overwrite | Client overwrite emits bounded singleton WebDAV Overwrite request metadata through the shared protocol type, accepting only the tokens T and F and replacing an existing same-name field; server Request::overwrite() and HttpRequest::overwrite() parse typed received values while preserving raw headers on errors |
No destination overwrite, RFC 4918 default-T synthesis, resource policy, COPY/MOVE execution, retry, or forwarding policy |
| If | Client if_header emits bounded RFC 4918 WebDAV If request metadata through the shared protocol type, accepting untagged or tagged condition lists with Not, state tokens, and bracketed entity tags, preserving order, and replacing an existing same-name field without touching If-Match; server Request::if_header() and HttpRequest::if_header() parse typed received values into HttpIf while preserving raw headers on errors and redacting state tokens from typed debug output |
No lock, entity-tag, or resource-state evaluation; no 412 or other precondition outcome; no lock creation, refresh, or release; no COPY/MOVE/UNLOCK execution; no retry, or forwarding policy |
| WebDAV metadata matrix | Workspace integration tests cover live HTTP/1.1 and h2c client/server/facade roundtrips for Depth, Destination, Overwrite, Timeout, Lock-Token, If, DAV, If-Schedule-Tag-Match, and Schedule-Tag, including valid values, malformed/duplicate/bounds rejection, raw-header observability, and Lock-Token/If redaction |
No resource storage, locking, COPY/MOVE/LOCK/UNLOCK execution, default Overwrite: T synthesis, or WebDAV method policy |
| Transparent negotiation metadata matrix | Workspace integration tests cover live HTTP/1.1 and h2c client/server/facade roundtrips for A-IM, IM, Delta-Base, Alternates, Negotiate, TCN, and Variant-Vary, including valid values, malformed/duplicate/bounds rejection, raw-header observability, and declared-order q-value recording |
No variant selection, Alternates URI fetching, delta application, 226 IM Used synthesis, or cache policy |
| Idempotency-Key | Client idempotency_key emits bounded singleton opaque Idempotency-Key request metadata through the shared protocol type, replacing an existing same-name field; server Request::idempotency_key() and HttpRequest::idempotency_key() parse typed received values while preserving raw headers on errors, and the key is redacted from typed debug output |
No retry, replay, key storage or comparison, deduplication store, or application idempotency policy |
| WebSocket handshake metadata | Client sec_websocket_key emits bounded singleton Sec-WebSocket-Key request metadata through the shared protocol type, replacing an existing same-name field; server Request::sec_websocket_key() and HttpRequest::sec_websocket_key() parse typed received values while preserving raw headers on errors; server responses can derive Sec-WebSocket-Accept with the RFC GUID plus SHA-1/base64 transform; client responses can parse and verify it against a validated key; key and accept material is redacted from typed debug output; workspace integration tests cover live HTTP/1.1 and h2c metadata-only roundtrips, malformed/duplicate/bounds rejection, and raw-header observability |
No HTTP upgrade, random nonce generation, WebSocket frames, or handshake policy |
| Sec-WebSocket-Version | Client sec_websocket_version emits bounded Sec-WebSocket-Version request metadata through the shared protocol type; server Request/HttpRequest helpers parse received fields; HttpResponse::with_sec_websocket_version/sec_websocket_version and client Response::sec_websocket_version declare or parse rejection-response version lists while preserving raw headers on errors; workspace integration tests cover live HTTP/1.1 and h2c metadata-only roundtrips |
No WebSocket handshake, Connection: Upgrade emission, Sec-WebSocket-Accept computation, version negotiation, protocol switch, or frames |
| Sec-WebSocket-Protocol | Client sec_websocket_protocol emits bounded Sec-WebSocket-Protocol offer metadata in preference order through the shared protocol type; server Request/HttpRequest helpers parse received offers; HttpResponse::with_sec_websocket_protocol/sec_websocket_protocol and client Response::sec_websocket_protocol declare or parse selection singletons while preserving raw headers on errors; workspace integration tests cover live HTTP/1.1 and h2c metadata-only roundtrips |
No WebSocket handshake, Connection: Upgrade emission, automatic subprotocol choice, protocol switch, or frames |
| Sec-WebSocket-Extensions | Client sec_websocket_extensions emits bounded ordered Sec-WebSocket-Extensions offer metadata through the shared protocol type; server Request/HttpRequest helpers parse received offers; HttpResponse::with_sec_websocket_extensions/sec_websocket_extensions and client Response::sec_websocket_extensions declare or parse one-extension selection singletons while preserving raw headers on errors; workspace integration tests cover live HTTP/1.1 and h2c metadata-only roundtrips |
No WebSocket handshake, Connection: Upgrade emission, compression activation, extension negotiation, protocol switch, or frames |
| Pragma | Client pragma/pragma_no_cache and Response::pragma share the bounded protocol Pragma representation with server Request::pragma, HttpRequest::pragma, HttpResponse::with_pragma, and HttpResponse::pragma across client construction, server request access, server response construction, and client response access, combining fields in wire order and preserving raw headers on errors |
No translation into Cache-Control, cache storage, freshness checks, revalidation, or cache/intermediary policy |
| W3C Trace Context | Client traceparent/tracestate validate and emit bounded W3C Trace Context request metadata through shared protocol types; server Request/HttpRequest helpers parse received fields, preserve raw headers on errors, preserve tracestate ordering, and redact propagation values from typed debug output |
No trace-id creation, sampling decision, tracing backend, span model, or automatic propagation |
| W3C Baggage | Client baggage validates and emits bounded W3C Baggage request metadata through the shared protocol type; server Request/HttpRequest helpers parse received fields, preserve raw headers on errors, preserve member order, and redact member and property values from typed debug output |
No application-data interpretation, request-context storage, tracing backend, span model, or automatic propagation |
| X-Forwarded compatibility metadata | Client x_forwarded_for, x_forwarded_host, and x_forwarded_proto emit bounded compatibility request metadata through shared protocol types; server Request/HttpRequest helpers parse ordered node, authority, and scheme values while preserving raw headers on errors |
No forwarded identity trust, client address selection, routing rewrite, scheme rewrite, redirect, upgrade, enforcement, or trusted-proxy selection; applications must choose trusted proxies |
| Via | Client via emits bounded HTTP Via hop metadata through the shared protocol type; Response::via parses received hops; server Request/HttpRequest helpers and HttpResponse::with_via/via parse or declare caller-supplied chains while preserving raw headers on errors |
No automatic hop insertion or removal, trusted-proxy inference, identity rewrite, or HTTP/1.1 or HTTP/2 proxy-policy changes |
| Accept-Language | Client accept_language emits bounded Accept-Language request metadata through the protocol AcceptLanguage type; server Request::accept_language() and HttpRequest::accept_language() parse typed received values as HttpAcceptLanguages while preserving raw headers on errors |
No locale matching, fallback selection, translation lookup, routing, or automatic response choice |
| Preflight request metadata | Client origin, access_control_request_method, access_control_request_headers, and access_control_request_private_network emit bounded Origin, Access-Control-Request-Method, Access-Control-Request-Headers, and Access-Control-Request-Private-Network request metadata and reject invalid input before connecting |
No automatic preflight decision, Access-Control-Allow-* response parsing, CORS policy, or Private Network Access policy |
| Access-Control-Allow-Credentials | Client Response::access_control_allow_credentials and server HttpAccessControlAllowCredentials, HttpResponse::with_access_control_allow_credentials, and HttpResponse::access_control_allow_credentials parse or declare bounded singleton Access-Control-Allow-Credentials true-token metadata while preserving raw headers on parse failures |
No CORS request evaluation, automatic credential attachment, or automatic credentials granting |
| Digest preferences | want_content_digest, want_content_digest_with_q, want_repr_digest, and want_repr_digest_with_q emit bounded Want-Content-Digest and Want-Repr-Digest request metadata; server Request::want_content_digest(), HttpRequest::want_content_digest(), Request::want_repr_digest(), and HttpRequest::want_repr_digest() parse received preference fields |
No algorithm selection, digest computation, response body hash validation, retries, or signing |
| Accept-Encoding | Client accept_encoding, accept_encoding_with_q, and gzip/deflate/br/identity helpers format bounded Accept-Encoding request metadata through the shared rttp-protocol type; server Request::accept_encoding() and HttpRequest::accept_encoding() parse received fields into HttpRequestAcceptEncodings |
No compression, decompression, content negotiation, retries, or transport changes |
| Upgrade and tunnel handoff | CONNECT returns the tunnel socket after a successful 200; upgrade() returns the socket after 101 Switching Protocols and skips interim 1xx responses |
Upgraded protocols are handed to the caller and are not parsed by rttp_client |
| Redirects | Auto-redirect covers 301, 302, 303, 307, and 308 method/body behavior, relative and absolute Location resolution, same- and cross-authority header handling, loop detection, and redirect bounds |
Redirects are HTTP client behavior, not a browser policy implementation |
| Byte ranges | range, range_from, range_suffix, if_range_etag, and if_range_date emit bounded HTTP/1.1 range request metadata; Response::content_range, accept_ranges, is_partial_content, and is_range_not_satisfiable expose Content-Range, Accept-Ranges, 206, and 416 metadata while preserving raw headers |
No Range request generation from Accept-Ranges, client-side If-Range evaluation, partial response engine, byte serving, content slicing, download resume, automatic retry/replay, cache storage, redirect handling, status-policy behavior, multipart range generation, or automatic cache validation policy |
| Conditional requests | if_none_match, if_match, if_modified_since, and if_unmodified_since emit bounded HTTP/1.1 validators; the date helpers validate and emit through the shared protocol IfModifiedSince and IfUnmodifiedSince types; Response::is_not_modified, is_precondition_failed, typed bounded etag, delta_base, and last_modified expose 304/412 and delta-base metadata while preserving raw headers |
One ETag validator per helper call, If-Range is range-scoped, no cache storage, no cached-entity lookup, no automatic revalidation, no delta application, and no cache-control engine |
| Informational responses and Early Hints | Response::informational_responses exposes skipped bounded HTTP/1.1 1xx heads, including 103 Early Hints, with preserved raw headers; server HttpResponse::early_hints/early_hints_with_headers construct validated bodyless 103 metadata |
101 Switching Protocols remains terminal for upgrade handoff; no automatic preload execution, cache policy, redirect/retry/replay, route generation, streaming early-write API, TLS/ALPN behavior, or status-policy behavior |
| Cache-Control, CDN-Cache-Control, Cache-Status, Date, Age, Expires, Retry-After, and Allow | Response::cache_control parses bounded response directives, numeric freshness fields, quoted field-name lists, and extension directives; Response::cdn_cache_control parses bounded CDN-Cache-Control directives and CDN extension metadata while preserving raw responses on parse errors; Response::cache_status parses bounded RFC 9211 Cache-Status list members and parameters while preserving raw responses on parse errors; Response::date parses singleton HTTP-date metadata; Response::age parses bounded singleton Age metadata through the protocol Age type, rejecting duplicate fields, values larger than 64 KiB, and overflowing u64 delta-seconds; Response::expires parses bounded HTTP-date metadata; Response::retry_after parses bounded singleton delta-seconds or HTTP-date metadata through the protocol RetryAfter type while preserving raw headers on parse errors; Response::allow parses bounded ordered method metadata |
No cache storage, CDN cache, Cache-Status forwarding or freshness policy, automatic revalidation, wall-clock freshness calculation, clock-skew correction, Vary matching, shared-cache policy enforcement, surrogate-key behavior, automatic conditional requests, automatic sleep, retry, replay, redirect, backoff, scheduler integration, fallback method selection, or status-code policy engine |
| Cache-Control, CDN-Cache-Control, Surrogate-Control, Cache-Status, Date, Age, Expires, Last-Modified, Retry-After, and Allow | Response::cache_control parses bounded response directives, numeric freshness fields, quoted field-name lists, and extension directives; Response::cdn_cache_control parses bounded CDN-Cache-Control directives and CDN extension metadata while preserving raw responses on parse errors; Response::surrogate_control parses bounded Surrogate-Control directives with duplicate rejection and aggregate-size validation while preserving raw responses on parse errors; Response::cache_status parses bounded RFC 9211 Cache-Status list members and parameters while preserving raw responses on parse errors; Response::date, Response::expires, and Response::last_modified_date parse bounded singleton HTTP-date metadata through shared protocol primitives; Response::age parses bounded singleton Age metadata through the protocol Age type, rejecting duplicate fields, values larger than 64 KiB, and overflowing u64 delta-seconds; Response::retry_after parses bounded delta-seconds or HTTP-date metadata; Response::allow parses bounded ordered method metadata |
No cache storage, CDN cache, Cache-Status forwarding or freshness policy, automatic revalidation, wall-clock freshness calculation, clock-skew correction, Vary matching, shared-cache policy enforcement, surrogate-key behavior, Surrogate-Control to Cache-Control translation, automatic conditional requests, automatic sleep, retry, replay, redirect, backoff, scheduler integration, fallback method selection, or status-code policy engine |
| Memento-Datetime | Response::memento_datetime parses bounded singleton Memento-Datetime IMF-fixdate metadata through the protocol MementoDatetime type while preserving raw headers on parse errors |
No archival selection, Accept-Datetime negotiation, TimeGate behavior, retry, or transport changes |
| Accept-Datetime | accept_datetime validates and emits bounded singleton Accept-Datetime request metadata through the protocol AcceptDatetime type, accepting obsolete HTTP-date forms and replacing an existing same-name field |
No archival selection, TimeGate behavior, Vary injection, cache-policy changes, or conditional-request handling |
| Content-Security-Policy-Report-Only | Response::content_security_policy_report_only, ContentSecurityPolicyReportOnly, HttpContentSecurityPolicyReportOnly, and HttpResponse::with_content_security_policy_report_only share bounded opaque CSP field validation while keeping the report-only header identity distinct, preserving repeated fields in wire order and raw headers on parse failures |
No CSP enforcement, directive evaluation, report delivery, browser policy state, retry, redirect, cache behavior, or status-policy behavior |
| Content-Language | Response::content_language parses bounded response Content-Language fields into ordered language metadata while preserving raw headers |
No automatic language negotiation, locale fallback, variant matching, cache policy, retry, replay, redirect, or status-policy behavior |
| Content-Location | Response::content_location and ContentLocation::parse parse bounded singleton response Content-Location metadata while preserving raw headers |
No redirect behavior, cache variant selection, representation replacement, retry/replay, route generation, or status-policy behavior |
| Service-Worker-Allowed | Response::service_worker_allowed and ServiceWorkerAllowed::parse parse bounded singleton response Service-Worker-Allowed path metadata while preserving raw headers |
No service-worker registration, scope evaluation, script-URL resolution, or application routing policy |
| Content-DPR | Response::content_dpr and ContentDpr::parse parse bounded singleton response Content-DPR decimal-ratio metadata while preserving raw headers |
No image rescaling, request DPR emission, Client Hints policy, retry, or transport changes |
| Content-Type and Content-Encoding | Response::content_type/ContentType::parse parse bounded singleton Content-Type metadata, and Response::content_encoding/ContentEncoding::parse parse bounded ordered Content-Encoding codings while preserving raw headers on parse failures |
No MIME sniffing, body decoding, charset transcoding, compression/decompression policy, negotiation, cache policy, redirects, retry/replay, or filesystem serving |
| Connection | Response::connection/Connection::parse parse bounded HTTP/1 Connection tokens, combining duplicate fields in wire order while preserving raw headers on parse failures |
No change to keep-alive, auto_add_connection, hop-by-hop stripping, or HTTP/2 rejection |
| Transfer-Encoding | Response::transfer_encoding/TransferEncoding::parse parse bounded HTTP/1 Transfer-Encoding fields that must be sole chunked, combining duplicate fields in wire order while preserving raw headers on parse failures |
No change to HTTP/1 framing decoders, TE, Content-Length, chunked body decoding policy, or HTTP/2 decode rejection |
| Content-Disposition | Client Response::content_disposition and protocol-backed server HttpContentDisposition, HttpResponse::with_content_disposition, with_attachment_filename, and content_disposition parse or declare bounded singleton response Content-Disposition metadata, preserve raw headers on parse failures, and preserve parsed filename plus filename* parameter values as metadata |
No automatic download, filesystem path handling, MIME sniffing, cache behavior, redirect behavior, retry/replay, negotiation, or status-policy behavior |
| WWW-Authenticate | Client Response::www_authenticate and server HttpWwwAuthenticate, HttpResponse::with_www_authenticate, and HttpResponse::www_authenticate parse or declare bounded response authentication challenges while preserving raw headers on parse failures |
No credential storage, authentication policy, retry, automatic Authorization generation, Basic/Bearer implementation, redirect behavior, or status-policy behavior |
| Authorization and Proxy-Authorization | Protocol Authorization/ProxyAuthorization, client HttpClient::authorization, and server Request::authorization/proxy_authorization validate bounded request authorization metadata, reject duplicate parsed inbound fields, and redact credentials from typed debug output |
No credential storage, authentication policy, challenge processing, retry, Basic/Bearer implementation, redirect policy changes, or automatic credential forwarding |
| Proxy-Authenticate | Client Response::proxy_authenticate and protocol ProxyAuthenticate::parse/parse_values parse bounded proxy authentication challenges across one or more response fields while preserving raw headers on parse failures |
No credential storage, proxy authentication policy, retry, automatic Proxy-Authorization generation, Basic/Bearer implementation, redirect behavior, or status-policy behavior |
| Proxy-Status | Client Response::proxy_status and server HttpProxyStatus, HttpResponse::with_proxy_status, and HttpResponse::proxy_status parse or declare bounded RFC 9209 Token/String proxy identifiers with opaque parameters while preserving raw headers on parse failures |
No proxy health checks, retries, trailer promotion, or origin-generation policy |
| Server-Timing | Client Response::server_timing and server HttpServerTiming, HttpResponse::with_server_timing, and HttpResponse::server_timing parse or declare bounded response timing metadata while preserving raw headers on parse failures |
No metric collection, measurement, telemetry export, metrics backend integration, retry, redirect behavior, or status-policy behavior |
| Alt-Used | Client Response::alt_used and server HttpAltUsed, HttpResponse::with_alt_used, and HttpResponse::alt_used parse or declare bounded singleton response authority metadata while preserving raw headers on parse failures and replacing raw response duplicates on typed declaration |
No alternative service selection, origin rewriting, socket migration, retry, or connection-policy behavior |
| Alternates | Client Response::alternates and server HttpAlternates, HttpResponse::with_alternates, and HttpResponse::alternates parse or declare bounded RFC 2295-style response variant metadata while preserving raw headers on parse failures and replacing raw response duplicates on typed declaration |
No variant selection, ranking, fetching, request replay, redirect, cache storage, or transparent negotiation behavior |
| Origin-Trial | Client Response::origin_trials and server HttpOriginTrials, HttpResponse::with_origin_trials, and HttpResponse::origin_trials parse or declare bounded opaque Origin-Trial tokens in wire order, preserve duplicates, redact token material from debug output, and replace raw response fields on typed declaration |
No token signature validation, expiration checks, origin applicability, feature activation, or browser trial policy |
| Speculation-Rules | Client Response::speculation_rules and server HttpSpeculationRules, HttpResponse::with_speculation_rules, and HttpResponse::speculation_rules preserve one bounded opaque Speculation-Rules response field, reject duplicates and response-field injection bytes, redact debug output, and replace raw response fields on typed declaration |
No speculation rule fetching, parsing, validation, prefetching, prerendering, execution, navigation changes, cache behavior, retry, or redirect behavior |
| Warning | Client Response::warning parses bounded RFC 7234 Warning warning-value lists while preserving raw headers on parse failures |
No cache storage, freshness calculation, stale-response handling, warn-code policy, retry, redirect behavior, or response-acceptance changes |
| NEL | Client Response::nel and server HttpNel, HttpResponse::with_nel, and HttpResponse::nel parse or declare bounded W3C Network Error Logging policy JSON while preserving raw headers on parse failures |
No network error report sending, policy persistence, Reporting endpoint group configuration, retry, redirect behavior, or status-policy behavior |
| Reporting-Endpoints | Client Response::reporting_endpoints and server HttpReportingEndpoints, HttpResponse::with_reporting_endpoints, and HttpResponse::reporting_endpoints parse or declare bounded endpoint-name to quoted-URL dictionaries through the shared protocol type while preserving raw headers on parse failures |
No report scheduling, sending, persistence, retry, routing, or endpoint policy behavior |
| Cross-Origin-Opener-Policy-Report-Only | Client Response::cross_origin_opener_policy_report_only and server HttpCrossOriginOpenerPolicyReportOnly, HttpResponse::with_cross_origin_opener_policy_report_only, and HttpResponse::cross_origin_opener_policy_report_only parse or declare bounded singleton COOP Report-Only metadata, reuse the canonical COOP directives, retain reporting parameters including report-to, and preserve raw headers on parse failures |
No browsing-context isolation, report scheduling, sending, persistence, retry, routing, or Reporting-Endpoints validation |
| Keep-Alive | Client Response::keep_alive and server HttpKeepAlive, HttpResponse::with_keep_alive, and HttpResponse::keep_alive parse or declare bounded RFC 2068 Keep-Alive timeout and max parameters as checked unsigned integers while preserving raw headers on parse failures |
No connection lifetime management, connection pooling, keep-alive timers, or HTTP/2 behavior changes |
| Vary | Response::vary parses bounded response Vary fields into wildcard or normalized case-insensitive field-name metadata |
No cache storage, stored-response matching engine, cache key persistence, automatic request replay, shared-cache policy enforcement, or automatic conditional requests |
| No-Vary-Search | Response::no_vary_search parses bounded Structured Fields response metadata for query-parameter variance declarations |
No cache storage, cache-key matching, URL normalization, navigation behavior, request replay, or shared-cache policy enforcement |
| Permissions-Policy | Response::permissions_policy parses bounded W3C Permissions Policy dictionary metadata through the shared protocol type, combining fields in wire order and preserving raw headers on parse failures |
No browser permission grants or denials, origin comparison, self resolution, API enablement, origin-policy enforcement, or report sending |
| Document-Policy | Response::document_policy parses bounded WICG Document Policy dictionary metadata through the shared protocol type, combining fields in wire order, retaining * and report-to, and preserving raw headers on parse failures |
No configuration-point execution, document-load blocking, required-policy comparison, Sec-Required-Document-Policy echoing, feature enablement, or report sending |
| Document-Policy-Report-Only | Response::document_policy_report_only parses bounded WICG Document Policy Report-Only dictionary metadata through the same shared protocol parser and formatter, retaining report-only type identity, *, and report-to, and preserving raw headers on parse failures |
No policy enforcement, document-load blocking, required-policy comparison, Sec-Required-Document-Policy echoing, feature enablement, report delivery, scheduling, retry, or endpoint validation |
| Supports-Loading-Mode | Response::supports_loading_mode parses bounded Structured Fields token-list response metadata through the shared protocol type, combining fields in wire order, retaining unknown tokens, and preserving raw headers on parse failures |
No prerendering, fenced-frame admission, navigation changes, redirects, retries, or resource-loading behavior |
| Trailers | Chunked response trailers are exposed for blocking and async APIs; streaming chunked uploads can send declared request trailers | Application metadata trailers such as X-Trace are allowed; pseudo-header, connection-specific, routing, authentication/cookie, and framing trailer fields are rejected |
| Bounded h2c client | With http2, direct socket2 h2c sends GET, HEAD, bodyless DELETE, OPTIONS, or TRACE, buffered POST, PUT, or PATCH requests, and opt-in RFC 8441 extended CONNECT request HEADERS via http2_extended_connect, opens at most one request stream, supports prior-knowledge with emit_http2_prior_knowledge, supports explicit HTTP/1.1 Upgrade: h2c negotiation with emit_http2_upgrade, advertises SETTINGS_ENABLE_PUSH = 0, advertises SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 only for the explicit extended CONNECT path, validates received SETTINGS_ENABLE_PUSH values as only 0 or 1, honors initial peer SETTINGS_MAX_CONCURRENT_STREAMS by failing before request HEADERS when the peer allows zero streams, honors peer-advertised SETTINGS_MAX_HEADER_LIST_SIZE request metadata limits, accepts only legal SETTINGS_MAX_FRAME_SIZE values from 16,384 through 16,777,215 bytes, splits outbound HEADERS, DATA, and trailers to the active peer frame-size limit, rejects oversized inbound frames when a configured local frame-size limit is exceeded, bounds HPACK dynamic table use with SETTINGS_HEADER_TABLE_SIZE, strips HTTP/1.x connection-specific request fields before emission, rejects connection-specific peer response fields, suppresses HEAD response bodies, treats RST_STREAM on the active stream as a bounded reset/cancellation signal, acknowledges inbound PING without ACK on stream 0 and exactly 8 octets with matching opaque data, ignores inbound PING ACK, rejects malformed PING frames, DATA bodies, trailers, HPACK static Huffman strings, bounded large header blocks, padded incoming frames, GOAWAY shutdown boundaries, PRIORITY metadata validation without scheduling, HTTP/2-allowed unknown/extension frame ignoring inside this bounded path, reserved stream-id high-bit normalization, and conservative DATA flow control |
Ordinary CONNECT, header-configured :protocol metadata, non-h2c HTTP/1.1 Upgrade handoff requests, and proxies are rejected deterministically, and PUSH_PROMISE/server push is rejected instead of managed; bounded direct h2c only, with no keepalive timers, no automatic client/server initiated PING policy, no public cancellation callback API, no dynamic policy API, no extension callback API, no full extension negotiation, TLS ALPN, external h2 integration, proxy tunneling to h2, proxy h2, tunnel handoff, connection pooling, persistent HTTP/2 session management, automatic retry/replay, server push, full session manager, full stream state machine, full multiplex scheduler, unbounded multiplex scheduling, general multiplexing, priority scheduling, request bodies or trailers for extended CONNECT, or request bodies for GET, HEAD, DELETE, OPTIONS, or TRACE |
With the http2 feature enabled, emit_http2_prior_knowledge sends a bounded
prior-knowledge h2c request over a direct socket2 TCP connection. It opens at
most one request stream and honors the peer's initial
SETTINGS_MAX_CONCURRENT_STREAMS: a value of zero rejects the request before
HEADERS are sent. It also honors the peer's advertised
SETTINGS_MAX_HEADER_LIST_SIZE for request metadata: encoded request HEADERS
and trailing HEADERS must stay within that peer boundary before emission, while
peers that do not advertise the setting keep the bounded direct-client default.
It supports GET, HEAD, bodyless DELETE, OPTIONS, or TRACE,
buffered POST, PUT, or PATCH requests, and the explicit
HttpClient::http2_extended_connect(protocol) mode for bounded RFC 8441
extended CONNECT request HEADERS. Non-empty buffered request bodies are sent as
DATA frames for the write methods. GET, HEAD, DELETE, OPTIONS, TRACE, and
extended CONNECT requests with bodies are rejected; HEAD, bodyless DELETE,
OPTIONS, TRACE, and extended CONNECT requests do not send request DATA frames,
and any HEAD response DATA frames are consumed without being exposed as a
response body. The client advertises SETTINGS_ENABLE_PUSH = 0 in its initial
SETTINGS frame so peers see server push disabled, and it advertises
SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 only when
http2_extended_connect(protocol) is used. It validates received
SETTINGS_ENABLE_PUSH values as only 0 or 1; any other value rejects the
bounded h2c handshake.
emit_http2_upgrade is the explicit HTTP/1.1 h2c Upgrade variant of the same
bounded single-request client path. It is opt-in and separate from
emit_http2_prior_knowledge: the client first sends an HTTP/1.1 request with
Connection: Upgrade, HTTP2-Settings, Upgrade: h2c, and the local SETTINGS
payload in HTTP2-Settings, requires a 101 Switching Protocols response
that negotiates h2c, then sends the HTTP/2 connection preface and uses the
same bounded single-stream h2c request/response flow on the upgraded socket.
The Upgrade variant supports the same request methods and body limits as the
prior-knowledge h2c path, rejects proxies before opening a socket, rewrites
any preconfigured HTTP/1.x upgrade/framing fields into the required h2c
upgrade fields, and fails deterministically for invalid h2c upgrade responses.
Ordinary upgrade() continues to return the socket to the caller for
WebSocket-style protocols, and non-h2c HTTP/1.1 Upgrade handoff remains
outside the bounded h2c client path.
The client validates SETTINGS_MAX_FRAME_SIZE boundaries on both sides of the
bounded h2c handshake. A configured local
http2_max_frame_size is advertised only when set, must be in the legal
HTTP/2 range of 16,384 through 16,777,215 bytes, and is used to reject inbound
frame payloads larger than that active local limit. Peer-advertised
SETTINGS_MAX_FRAME_SIZE values outside that same legal range reject the
handshake. Legal peer values become the outbound frame boundary, so request
HEADERS, DATA, and trailing HEADERS are split into frames no larger than the
active peer limit while the client remains a single-stream prior-knowledge
path. Before encoding request HEADERS, this bounded h2c client path
strips HTTP/1.x connection-specific fields: Connection, Keep-Alive,
Proxy-Connection, Transfer-Encoding, Upgrade, TE, Trailer, Host,
and any field named by a Connection token. Peer response HEADERS are rejected
when they contain Connection, Keep-Alive, Proxy-Connection, TE,
Transfer-Encoding, or Upgrade. Application request trailers such as
X-Trace, X-Upload-Status, or X-Upload-Checksum are valid in this bounded
h2c path and are encoded as trailing HEADERS after request DATA. Configured
request trailers are rejected before emission when their field name is invalid
or reserved for connection/framing/routing behavior: Connection,
Keep-Alive, Proxy-Connection, TE, Trailer, Transfer-Encoding,
Upgrade, Content-Length, Host, Proxy-Authenticate, or
Proxy-Authorization. Peer response trailers use the existing
forbidden-trailer validation for invalid pseudo-header-like names,
connection-specific, routing, authentication/cookie, and framing fields such
as Authorization, Connection, Content-Length, Cookie, Host,
Keep-Alive, Proxy-Authenticate, Proxy-Authorization,
Proxy-Connection, Set-Cookie, TE, Trailer, Transfer-Encoding,
Upgrade, and WWW-Authenticate. The client
supports HPACK static Huffman
strings and bounded large header blocks via CONTINUATION frames. It uses HPACK
dynamic entries for repeated request header and trailer fields within the
peer's advertised SETTINGS_HEADER_TABLE_SIZE. The default peer limit is
4,096 bytes when the peer does not advertise the setting; a peer-advertised
zero disables request dynamic indexing, so request HEADERS and trailers remain
literal encoded. Peer values above 4,096 bytes are valid, but RTTP caps request
dynamic indexing at its 4,096-byte bounded encoder size. Response decoding is
bounded by the local advertised
SETTINGS_HEADER_TABLE_SIZE: the client uses the default 4,096-byte decoder
limit unless ConfigBuilder::http2_header_table_size configures and advertises
another u32-sized value. Incoming HPACK dynamic table size updates from
response HEADERS or trailers may shrink that decoder table, including to zero;
updates above the local advertised limit are rejected. Dynamic table size
updates are HPACK compression state only and do not change
SETTINGS_MAX_HEADER_LIST_SIZE, trailer validation, body framing, or the
single-stream h2c policy. Valid response PRIORITY frames and HEADERS
priority fields are validated and ignored as metadata; malformed priority
metadata is rejected, and no priority scheduling is performed. Inbound PING
without ACK is acknowledged only when it arrives on stream 0 with exactly
8 octets of opaque data; the PING ACK carries that same opaque data. Inbound
PING ACK is ignored for this bounded path. PING with a non-zero stream id or
payload length other than 8 is malformed and rejected. RTTP does not add
keepalive timers, automatic client- or server-initiated PING policy, replay
behavior, a full session manager, or a full multiplex scheduler around this
acknowledgement path. Unknown frame types, including extension frames, are
ignored only after
the prior-knowledge h2c handshake in this bounded direct-client path where
HTTP/2 permits that behavior; RTTP does not expose extension callbacks or
perform full extension negotiation. Reserved stream identifier high bits are
masked when frames are parsed or written, which normalizes wire framing but
does not add broader multiplex scheduling or persistent session management.
Server push is outside this bounded client path even when a peer advertises
SETTINGS_ENABLE_PUSH = 1: incoming PUSH_PROMISE frames are rejected
deterministically instead of creating or tracking push state. HTTP/1.1
CONNECT tunnel handoff remains a separate
client path;
prior-knowledge h2c GOAWAY is treated as a bounded shutdown signal: a
response already completed before GOAWAY remains usable, an active stream
continues only when the peer's last-stream-id includes it, and a lower
boundary rejects the response deterministically. A GOAWAY received before
stream 1 is opened is treated as request refusal and no request HEADERS are
sent. RTTP returns that refusal to the caller instead of retrying on a new
connection; callers that know a request is safe or idempotent must choose any
retry policy themselves. This protocol shutdown boundary is distinct from a
transport-level disconnect, read timeout, write timeout, or TCP reset, which
is reported through the normal socket/error path without an HTTP/2
last-stream-id boundary. RST_STREAM is likewise bounded to this
prior-knowledge h2c client path: a reset for the active stream is reported as
response cancellation, while malformed reset frames are rejected
deterministically. RTTP does not expose a public cancellation callback API or
retry the request automatically. Ordinary CONNECT, header-configured RFC
8441 :protocol metadata, HTTP/1.1 Upgrade handoff requests, and proxy
tunneling are rejected before a client socket is opened. The explicit
http2_extended_connect(protocol) mode emits :method CONNECT with
:protocol, :scheme, :authority, and :path, then returns the peer's
HTTP/2 response through the normal Response API; it does not hand an upgraded
socket to the caller and does not send request bodies or request trailers.
HTTP/1.1 CONNECT tunnel handoff and Upgrade remain separate client handoff
paths; this h2c path does not provide full WebSocket-over-h2, proxy h2, TLS
ALPN, tunnel handoff, persistent multiplex sessions, general tunnel
scheduling, or full RFC 8441 support. Extension callback APIs, full extension
negotiation, external h2 integration, connection pooling, automatic retry,
server push, full stream state machines, and full HTTP/2 features such as
unbounded multiplex scheduling, general multiplexing, and priority scheduling
are not part of that bounded prior-knowledge client path; RTTP also does not
provide a dynamic policy API for changing h2c frame-size or metadata limits at
runtime.
# #[cfg(feature = "http2")]
# fn example() -> Result<(), Box<dyn std::error::Error>> {
use rttp_client::HttpClient;
let response = HttpClient::new()
.get()
.url("http://127.0.0.1:8080/chat")
.http2_extended_connect("websocket")
.emit_http2_prior_knowledge()?;
# Ok(())
# }use rttp_client::HttpClient;
let response = HttpClient::new()
.get()
.url("http://127.0.0.1:8080/health")
.emit()?;
# Ok::<(), Box<dyn std::error::Error>>(())The rttp crate exposes rttp::Http::server, which creates a blocking
HttpServer listener.
[dependencies]
rttp = "0.2"use std::time::Duration;
use rttp::server::HttpResponse;
fn main() -> std::io::Result<()> {
let server = rttp::Http::server("127.0.0.1:0")?
.with_read_timeout(Some(Duration::from_secs(5)))
.with_write_timeout(Some(Duration::from_secs(5)));
println!("listening on {}", server.local_addr()?);
server.accept_one(|request| {
println!("{} {}", request.method(), request.target());
HttpResponse::ok("hello")
.header("Transfer-Encoding", "chunked")
.header("Trailer", "X-Trace")
.trailer("X-Trace", "abc")
})
}Use HttpServer::bind directly when you already want the server type,
HttpServer::local_addr to read the bound address, accept_one for one
connection, and serve_requests for a fixed number of sequential connections.
Use with_read_timeout and with_write_timeout to apply socket-level
timeouts to each accepted connection; pass None to leave the corresponding
socket timeout unset. Add Transfer-Encoding: chunked to an HttpResponse to
write the complete response body with HTTP/1.x chunked transfer framing instead
of an automatic Content-Length; response trailers added with
HttpResponse::trailer are written after the terminating zero-size chunk. Add a
Trailer response header when advertising which trailer fields will follow.
The listener path uses socket2.
The server provides range parsing and response constructors for applications
that choose to support partial content. It does not automatically serve files
or decide static-file policy. Application code should inspect Range, choose
the representation and entity length, and pass the header to
HttpByteRange::parse(range_header, entity_length).
Supported request forms are a single bytes=start-end, bytes=start-, or
bytes=-suffix range. Open-ended ranges are clipped to the representation
length, suffix ranges require a nonzero suffix, unsupported units return
UnsupportedUnit, comma-separated ranges return MultipleRanges, malformed
or inverted ranges return InvalidRange, and ranges beyond the entity return
UnsatisfiedRange.
For a satisfiable range, HttpResponse::partial_content(body, range) returns
206 Partial Content, adds Content-Range: bytes start-end/length, and sends
only the selected body bytes. For an unsatisfied range,
HttpResponse::range_not_satisfiable(entity_length) returns
416 Range Not Satisfiable with Content-Range: bytes */length and an empty
body.
For conditional range requests, Request::evaluate_if_range(&metadata, entity_length) composes caller-provided HttpConditionalMetadata with the
existing single-range parser. Matching strong ETags or exact HTTP-date
Last-Modified validators return PartialContent(HttpByteRange);
non-matching, weak, invalid, or metadata-missing validators return
FullResponse; guarded unsatisfied ranges return RangeNotSatisfiable.
Application code still chooses the final 200, 206, or 416 response.
Multipart ranges are intentionally not generated: RTTP does not serialize
multipart/byteranges or pick a multipart response for multiple requested
ranges. Filesystem path normalization, MIME detection, ETag or Last-Modified
generation, authorization, directory indexes, dotfile visibility, cache
storage, automatic cache validation, and any automatic retry policy remain
caller-owned policy before choosing 200, 206, or 416.
HttpResponse::with_accept_ranges(units) declares supported range units with
one bounded comma-separated Accept-Ranges response header, while
HttpResponse::with_accept_ranges_none() declares the exclusive
Accept-Ranges: none sentinel. HttpResponse::accept_ranges() parses attached
fields into HttpAcceptRanges, the shared protocol parser used by both the
client and server facades, bounded to 64 KiB per field and 256 range units.
Malformed or empty values, duplicate units across parsed fields, combining
none with any unit, and passing none through the unit declaration helper
are rejected. Manual raw Accept-Ranges headers remain preserved until a
typed declaration helper replaces them or the typed parser is requested.
The server Accept-Ranges helpers are response metadata helpers that compose
with HttpResponse::cache_control(), HttpResponse::vary(),
HttpResponse::allow(), HttpResponse::content_language(), and the other raw
header APIs. They do not parse request Range fields, generate Range
requests, create a partial response engine, serve bytes, slice content, resume
downloads, choose redirect or status-policy behavior, implement cache policy,
retry or replay requests, or automatically select 200, 206, or 416.
The server exposes conditional request primitives for applications that already
know the selected representation. Use HttpConditionalMetadata with
HttpEntityTag::strong("tag") or HttpEntityTag::weak("tag") and optional
last_modified(SystemTime), then call
Request::evaluate_conditional(&metadata) or
evaluate_conditional_request(&request, &metadata).
The evaluator returns Proceed, NotModified, or PreconditionFailed.
If-Match uses strong ETag comparison and takes precedence over
If-Unmodified-Since; If-None-Match uses weak ETag comparison and takes
precedence over If-Modified-Since. Matching If-None-Match validators return
304 Not Modified behavior for GET and HEAD, and 412 Precondition Failed
behavior for other methods. HTTP-date validators are used only when they parse
as HTTP-date values, and Last-Modified comparisons are made at second
precision.
Handlers can also observe the raw validators without evaluation:
Request::if_modified_since(), HttpRequest::if_modified_since(), and the
matching if_unmodified_since() accessors parse one HTTP-date instant through
the shared protocol HttpIfModifiedSince and HttpIfUnmodifiedSince types.
Absent fields return Ok(None); malformed, oversized, duplicate, or
control-byte values return a parse error while the raw field stays available
through header(). These accessors only parse metadata and do not change
evaluator precedence or comparison behavior.
Use HttpResponse::not_modified(&metadata) to serialize a bodyless 304 with
available ETag and Last-Modified validators. Use
HttpResponse::with_etag(HttpEntityTag::strong("tag")) or
HttpResponse::with_etag(HttpEntityTag::weak("tag")) to declare one bounded
response ETag; HttpResponse::etag() parses attached singleton ETag
metadata using the same protocol entity-tag authority and leaves raw headers
intact when typed parsing fails. Use
HttpResponse::precondition_failed() for 412; application code can still add
its own headers or body when desired. A Proceed outcome means the handler
should send its normal representation response.
HttpResponse::with_schedule_tag(HttpScheduleTag::parse("\"sched-17\"")?)
declares one bounded Schedule-Tag response field, and
HttpResponse::schedule_tag() parses attached singleton Schedule-Tag
metadata through the shared protocol HttpScheduleTag type backed by
EntityTag. The client facade re-exports the matching ScheduleTag type and
Response::schedule_tag() accessor. These helpers only declare and expose
response metadata; RTTP does not generate calendar versions, compare schedule
validators, inspect calendars, or apply scheduling policy.
The helper scope is intentionally bounded. RTTP does not choose ETags, read or serve files, implement static-file serving policy, store cached responses, automatically revalidate stale entries, or provide a full cache-control engine. Those remain application policy around the validator helpers.
HttpResponse::early_hints(links) constructs a bodyless 103 Early Hints
response with one Link header per supplied value.
HttpResponse::early_hints_with_headers(links, metadata) adds validated
metadata headers alongside those links for applications that want to send
adjacent response metadata before a final response. Serialize the returned
model with the same response-writing path used for other HttpResponse
values, then write the final response separately.
The constructors are bounded and validation-oriented. They require at least
one non-empty Link value, bound each Early Hints field value to 64 KiB,
reject invalid field-value bytes, reject invalid metadata field names, and
keep Link values in the dedicated links argument. Metadata fields that would
affect connection state or body framing are rejected, including Connection,
Content-Length, Keep-Alive, Proxy-Connection, TE, Trailer,
Transfer-Encoding, and Upgrade. A body assigned to the 103 model is not
serialized, and Content-Length is not generated for it.
103 Early Hints is separate from 101 Switching Protocols. 101 responses
remain bodyless terminal handoff responses for HttpHandoff::upgrade and
other caller-owned protocol transitions; they are not serialized as skipped
informational metadata. Raw headers attached through ordinary
HttpResponse::header calls remain preserved until a typed helper validates,
parses, or replaces the relevant field.
Early Hints support is metadata-only. The server does not execute preloads,
choose cache policy, redirect, retry, replay requests, generate routes, expose
a streaming early-write API, alter TLS/ALPN behavior, or decide final response
status from 103 metadata.
HttpResponse::links() parses final-response Link fields into ordered
HttpLinkValues and HttpLinkValue metadata. URI/reference targets and both
standard and unknown parameters are retained in order. The parser applies 64
KiB per-field and parameter-value limits, plus limits of 256 link-values and
256 parameters per value; parsing errors leave raw response headers intact.
Link metadata uses the same bounded model as Early Hints, but does not execute preloads or enable fetch scheduling, redirects, cache policy, or route generation.
Server Cache-Control helpers parse directive metadata for application policy;
they do not enforce cache behavior. Request::cache_control() and
HttpRequest::cache_control() parse request directives into
HttpRequestCacheControl, including no-cache, no-store, max-age,
max-stale with or without a value, min-fresh, no-transform,
only-if-cached, and extension directives. HttpResponse::cache_control()
parses response headers already attached to an HttpResponse into
HttpResponseCacheControl, including no-cache, no-store, max-age,
s-maxage, private, public, must-revalidate, proxy-revalidate,
immutable, stale-while-revalidate, stale-if-error, quoted field-name
lists, and extension directives.
Unknown extension directives are preserved rather than discarded. Each
HttpCacheControlExtension exposes the directive token name and optional
parsed value, with quoted-string escaping removed when a quoted value is used.
The helpers do not interpret extension semantics or negotiate extension
behavior.
Parsing is bounded and validation-oriented. Each Cache-Control field value is
limited to 64 KiB, the parsed set is limited to 256 directives across all
values passed to the helper, directive names and unquoted values must be valid
HTTP tokens, quoted strings must be well formed, and delta-seconds values must
be unquoted non-negative decimal integers that fit in u64. Invalid
Cache-Control syntax returns HttpCacheControlParseError from the helper;
it does not by itself reject the request before handler code or remove the
original header from the response model.
These helpers are separate from conditional validator evaluation.
Request::evaluate_conditional() and Request::evaluate_if_range() use only
caller-supplied HttpConditionalMetadata and the conditional request headers.
They do not consult Cache-Control directives to decide whether a response is
fresh, whether it must be revalidated, or whether validators should be emitted
on a later request.
RTTP does not provide cache storage, automatic revalidation, freshness
calculation against wall-clock time, Vary matching, shared-cache policy
enforcement, or automatic conditional requests. Directives such as max-age,
s-maxage, no-cache, only-if-cached, must-revalidate, and extension
directives are exposed as parsed metadata for application-owned policy.
HttpResponse::cache_status() parses attached Cache-Status response fields
into HttpCacheStatus as a bounded RFC 9211 / RFC 8941 list of cache
identifiers and parameters. Repeated fields are combined in wire order. Each
field is limited to 64 KiB, the member count is limited to 256, each member is
limited to 256 parameters, and each parameter value is limited to 64 KiB.
Parse errors return HttpCacheStatusParseError and do not remove the original
raw response headers from the response model. An absent header returns
Ok(None). The helper does not store cache entries, compute freshness,
revalidate, select endpoints, retry, or choose status behavior.
HttpResponse::cdn_cache_control() parses attached CDN-Cache-Control
response fields into HttpCdnCacheControl with the same bounded directive
model as response Cache-Control: 64 KiB per field, at most 256 directives,
valid HTTP tokens for directive names and unquoted values, and well-formed
quoted strings. CDN-specific extension directives are preserved in order with
their optional parsed values. Parse errors return
HttpCdnCacheControlParseError and do not remove the original raw response
headers from the response model.
CDN cache metadata remains metadata-only. The server does not create or manage
a CDN cache, compute freshness, evaluate surrogate keys, revalidate
automatically, enforce shared-cache policy, retry, replay, redirect, or choose
status behavior from CDN-Cache-Control.
Server Date, Age, Expires, and Last-Modified helpers expose adjacent
response metadata without adding cache policy.
HttpResponse::with_age(delta_seconds) adds an Age header from a
non-negative u64 delta-seconds value, and
HttpResponse::age() parses an attached single Age header back into u64.
The accepted bound is exactly the u64 delta-seconds range: 0 through
u64::MAX. Empty, signed, fractional, non-numeric, comma-list, duplicated, and
overflowing values return HttpAgeParseError.
HttpResponse::with_date(time), with_expires(time), and
with_last_modified(time) serialize canonical IMF-fixdate Date, Expires,
and Last-Modified headers from SystemTime. HttpResponse::date(),
expires(), and last_modified_date() parse attached singleton HTTP-date
fields through the shared protocol primitives. IMF-fixdate, obsolete RFC 850
dates, and asctime dates are supported; malformed, duplicated, control-byte,
unsupported-time-zone, oversized, or non-date values return typed parse errors.
HttpResponse::with_retry_after_delta(delta_seconds) serializes a
delta-seconds Retry-After header from a non-negative u64 through the shared
protocol RetryAfter formatter, while HttpResponse::with_retry_after_date(time)
serializes an HTTP-date Retry-After header from SystemTime through the same
primitive. HttpResponse::retry_after() parses an attached single
Retry-After header into the protocol-backed HttpRetryAfter::DeltaSeconds or
HttpRetryAfter::HttpDate. Empty, signed, fractional, non-numeric non-date,
comma-list, duplicated, overflowing, oversized, or malformed HTTP-date values
return HttpRetryAfterParseError.
Malformed typed helper reads return validation errors, while raw
HttpResponse::header("Date", ...), HttpResponse::header("Age", ...),
HttpResponse::header("Expires", ...), HttpResponse::header("Last-Modified", ...),
and HttpResponse::header("Retry-After", ...) values remain preserved exactly
as response headers. These helpers do not calculate freshness, correct clock
skew, validate cache state against wall-clock time, store responses, match
stored responses, revalidate responses, enforce shared-cache policy, attach
behavior to status codes, sleep, retry, replay requests, apply backoff,
integrate with a scheduler,
or issue automatic conditional requests.
Server Memento-Datetime helpers expose archival datetime metadata without
adding time negotiation. HttpResponse::with_memento_datetime(time) replaces
one Memento-Datetime header from SystemTime, and
HttpResponse::memento_datetime() parses an attached singleton field into
HttpMementoDatetime. Empty, malformed, control-byte, duplicate, and oversize
values return HttpMementoDatetimeParseError. Raw
HttpResponse::header("Memento-Datetime", ...) values remain preserved.
These helpers do not select an archival representation, negotiate
Accept-Datetime, implement TimeGate behavior, retry, or change transport
handling.
Server Accept-Datetime helpers expose the matching request metadata without
adding time negotiation. Request::accept_datetime() and
HttpRequest::accept_datetime() parse a singleton Accept-Datetime field
into HttpAcceptDatetime; absent fields return Ok(None), and malformed,
control-byte, duplicate, and oversize values return
HttpAcceptDatetimeParseError while raw request headers remain preserved.
These helpers do not select an archived representation, implement TimeGate
behavior, add Vary, alter cache policy, or feed conditional evaluation. A
parsed Accept-Datetime instant matches HttpMementoDatetime for the same
HTTP-date, but the two helpers do not negotiate with each other.
Server-side Allow helpers expose response declaration and method-list parsing
metadata without implementing method negotiation or automatic status handling.
HttpResponse::with_allow(methods) validates an explicit method list and adds
one comma-separated Allow header, while HttpResponse::allow() parses any
Allow headers already attached to a response into HttpAllowedMethods.
HttpAllowedMethods::parse(value) accepts a comma-separated list of HTTP
method tokens and preserves the declared token spelling and order.
Parsing is bounded and validation-oriented. Each Allow field value is
limited to 64 KiB, the parsed method list is limited to 32 entries, and each
member must be a valid HTTP token. Empty members, malformed method tokens,
duplicates across one or more helper-parsed header fields, oversized values,
and too many methods return HttpAllowParseError from the helper. Raw
HttpResponse::header("Allow", ...) values remain preserved exactly as
ordinary response headers; helper parse errors do not remove existing headers.
These helpers are metadata-only. RTTP does not choose fallback methods, retry
or replay requests, implement OPTIONS policy, generate 405 responses,
dispatch routes, or provide a status-code policy engine from Allow.
Server-side Content-Language helpers expose request and response metadata
without implementing language negotiation, locale fallback, or variant
matching.
Request::content_language() and HttpRequest::content_language() parse
received Content-Language fields in wire order into HttpContentLanguages
and return Ok(None) when the header is absent. HTTP/1.1 and HTTP/2 share
the same Request helpers.
HttpResponse::with_content_language(languages) validates an explicit language
tag list and adds one comma-separated Content-Language header, while
HttpResponse::content_language() parses any Content-Language headers
already attached to a response into HttpContentLanguages.
HttpContentLanguages::parse(value) accepts comma-separated language tags and
preserves the declared spelling and order; the parsed tags are exposed by both
HttpContentLanguages::languages() and HttpContentLanguages::tags().
Parsing is bounded and validation-oriented. Each Content-Language field value
is limited to 64 KiB, the parsed language list is limited to 256 entries, and
each tag must match the BCP 47-shaped grammar enforced by the shared protocol
primitive: language, optional extlang, script, region, variant, extension, and
private-use subtags, plus registered grandfathered tags. Empty members,
malformed tags, duplicates across one or more helper-parsed header fields,
oversized values, and too many tags return HttpContentLanguageParseError from
the helper. Raw
Request::header("Content-Language", ...) and
HttpResponse::header("Content-Language", ...) values remain preserved exactly
as ordinary headers; helper parse errors do not remove existing headers.
These helpers parse request metadata only and interoperate with adjacent
helpers such as Request::accept_language(), HttpResponse::cache_control(),
HttpResponse::allow(), and HttpResponse::vary() by preserving raw headers
and parsing only when requested. They do not sniff, decode, negotiate, cache,
redirect, retry, or select representations from Content-Language.
Server-side Accept-Charset helpers expose request metadata through the
shared rttp-protocol primitive. Request::accept_charset() and
HttpRequest::accept_charset() parse all received Accept-Charset fields
in wire order into HttpRequestAcceptCharsets and return Ok(None) when
the header is absent. HTTP/1.1 and HTTP/2 share the same Request helpers.
Each entry provides its charset() and q-value quality() in thousandths
(1000 is the default quality of 1). The shared protocol type is the
authority for charset-range, wildcard, q-value, duplicate, member-count, and
size validation.
Parsing is bounded and validation-oriented. Each Accept-Charset field value
is limited to 64 KiB, the combined list is limited to 32 members, and each
range must be an RFC 9110 token, including *. Empty members, malformed
tokens or q-values, duplicates across one or more helper-parsed header
fields, oversized values, and too many members return
HttpAcceptCharsetParseError from the helper. Raw
Request::header("Accept-Charset", ...) values remain preserved exactly as
ordinary headers; helper parse errors do not remove existing headers.
These helpers parse request metadata only. They do not negotiate, transcode, decode bodies, sniff MIME types, or select a response charset.
Server-side Pragma helpers expose request and response metadata through the
shared rttp-protocol primitive. Request::pragma() and HttpRequest::pragma()
parse received Pragma fields in wire order into HttpPragma, and
HttpResponse::with_pragma(value) declares validated response metadata that
replaces attached same-name fields. HttpResponse::pragma() parses attached
response fields. Absent fields return Ok(None). HTTP/1.1 and HTTP/2 share
the same Request helpers. The shared protocol type is the authority for
directive-token, optional-value, duplicate, member-count, and size validation.
Parsing is bounded and validation-oriented. Each Pragma field value is
limited to 64 KiB, combined field values are limited to 64 KiB including
", " separator overhead, each directive value is limited to 64 KiB, and the
combined directive count is limited to 256. Empty members, malformed tokens or
quoted-strings, valued no-cache forms, duplicate names, and bound violations
return HttpPragmaParseError from the helper. Raw Request::header("Pragma", ...) values remain preserved exactly as ordinary headers; helper parse errors
do not remove existing headers.
These helpers declare and parse metadata only. They do not translate Pragma
into Cache-Control, store cache entries, or apply cache, freshness,
revalidation, intermediary, or HTTP/1.0 compatibility policy.
Server-side Accept-Encoding helpers expose request metadata through the
shared rttp-protocol primitive. Request::accept_encoding() and
HttpRequest::accept_encoding() parse all received Accept-Encoding fields
in wire order into HttpRequestAcceptEncodings and return Ok(None) when
the header is absent. HTTP/1.1 and HTTP/2 share the same Request helpers.
Each entry provides its coding() and q-value quality() in thousandths
(1000 is the default quality of 1). The shared protocol type is the
authority for coding-token, wildcard, q-value, duplicate, member-count, and
size validation.
Parsing is bounded and validation-oriented. Each Accept-Encoding field value
is limited to 64 KiB, the combined list is limited to 32 members, and each
coding must be an RFC 9110 token, including identity and *. Empty members,
malformed tokens or q-values, duplicates across one or more helper-parsed
header fields, oversized values, and too many members return
HttpAcceptEncodingParseError from the helper. Raw
Request::header("Accept-Encoding", ...) values remain preserved exactly as
ordinary headers; helper parse errors do not remove existing headers.
These helpers parse request metadata only. They do not enable automatic compression, decompression, or content negotiation.
Server-side Content-Location helpers expose response metadata declaration and
parsing through the shared protocol-owned HttpContentLocation type without
implementing redirect handling, cache selection, or route policy.
HttpResponse::with_content_location(value) validates one Content-Location
URI-reference field value, trims outer whitespace, removes any existing raw
Content-Location fields, and adds a single validated Content-Location
header. HttpResponse::content_location() parses any attached
Content-Location header into HttpContentLocation and returns Ok(None)
when the header is absent.
Parsing is bounded and validation-oriented. The field value is limited to
64 KiB and must be a non-empty absolute URI or relative URI reference without
control characters, interior whitespace, unsafe field-value characters,
malformed URI syntax, or broken percent-encoding. Duplicate
Content-Location fields are rejected because the helper treats the header as
singleton response metadata. Malformed values, duplicated singleton fields, and
oversized values return HttpContentLocationParseError from the helper. Raw
HttpResponse::header("Content-Location", ...) values remain preserved exactly
as ordinary response headers until a typed declaration helper replaces them or
the typed parser is requested.
These helpers interoperate with adjacent response metadata helpers such as
HttpResponse::cache_control(), HttpResponse::allow(),
HttpResponse::content_language(), HttpResponse::vary(),
HttpResponse::retry_after(), HttpResponse::age(),
HttpResponse::expires(), and HttpResponse::accept_ranges() by preserving
raw headers and parsing only when requested. They are metadata-only: RTTP does
not treat Content-Location as redirect behavior, cache variant selection,
representation replacement, retry/replay behavior, route generation, or
status-policy behavior.
Server-side Service-Worker-Allowed helpers expose response metadata
declaration and parsing through the shared protocol-owned
HttpServiceWorkerAllowed type without registering service workers or
resolving application routing policy.
HttpResponse::with_service_worker_allowed(value) validates one
Service-Worker-Allowed origin-relative or absolute path field value, trims
outer whitespace, removes any existing raw Service-Worker-Allowed fields,
and adds a single validated Service-Worker-Allowed header.
HttpResponse::service_worker_allowed() parses any attached
Service-Worker-Allowed header into HttpServiceWorkerAllowed and returns
Ok(None) when the header is absent.
Parsing is bounded and validation-oriented. The field value is limited to
64 KiB and must be a non-empty origin-relative or absolute path without
control or non-ASCII characters, interior whitespace, unsafe field-value characters, broken
percent-encoding, absolute URIs, or network-path authority forms. Duplicate
Service-Worker-Allowed fields are rejected because the helper treats the
header as singleton response metadata. Malformed values, duplicated singleton
fields, and oversized values return HttpServiceWorkerAllowedParseError from
the helper. Raw HttpResponse::header("Service-Worker-Allowed", ...) values
remain preserved exactly as ordinary response headers until a typed
declaration helper replaces them or the typed parser is requested.
These helpers interoperate with adjacent response metadata helpers by
preserving raw headers and parsing only when requested. They are
metadata-only: RTTP does not register service workers, evaluate
service-worker scope, resolve the value against a script URL, or apply
application routing policy from Service-Worker-Allowed.
Server-side Content-DPR helpers expose response metadata declaration and
parsing through the shared protocol-owned HttpContentDpr type without
rescaling images or applying Client Hints policy.
HttpResponse::with_content_dpr(value) validates one Content-DPR field
value, trims outer whitespace, removes any existing raw Content-DPR fields,
and adds a single validated Content-DPR header. HttpResponse::content_dpr()
parses any attached Content-DPR header into HttpContentDpr and returns
Ok(None) when the header is absent.
Parsing is bounded and validation-oriented. The field value is limited to
64 KiB and must match 1*DIGIT["." 1*DIGIT] as a finite ratio greater than
zero. Duplicate Content-DPR fields are rejected because the helper treats the
header as singleton response metadata. Malformed values, duplicated singleton
fields, and oversized values return HttpContentDprParseError from the helper.
Raw HttpResponse::header("Content-DPR", ...) values remain preserved exactly
as ordinary response headers until a typed declaration helper replaces them or
the typed parser is requested.
These helpers are observation-only. RTTP does not rescale images, send request
DPR, apply Client Hints policy, retry, replay, redirect, or change transport
from Content-DPR.
Server-side Content-Disposition helpers expose response metadata declaration
and parsing without implementing download policy, filesystem handling, MIME
sniffing, cache behavior, redirect handling, retry, or negotiation.
HttpContentDisposition is backed by the shared protocol primitive.
HttpContentDisposition::parse(value) validates one field value, including a
token disposition type and bounded parameters. HttpContentDisposition::inline()
and HttpContentDisposition::attachment() construct common dispositions, and
with_parameter(name, value) adds safely serialized parameters.
HttpResponse::with_content_disposition(value) validates the provided model or
field value, removes any existing raw Content-Disposition fields, and adds one
validated Content-Disposition header. HttpResponse::with_attachment_filename
is a convenience helper for attachment; filename=....
HttpResponse::content_disposition() parses an attached singleton header and
returns Ok(None) when the header is absent.
Parsing is bounded and validation-oriented. The field value is limited to
64 KiB, parameter count is limited to 256, each parameter value is limited to
64 KiB, token positions must be valid HTTP tokens, quoted-string input must be
well formed, filename* must be an unquoted RFC 5987 ext-value, and CR/LF or
other control characters other than HTAB are rejected. Duplicate parameters
and duplicate Content-Disposition fields are rejected by the typed parser.
Raw HttpResponse::header("Content-Disposition", ...) values remain preserved
exactly as ordinary response headers until a typed declaration helper replaces
them or the typed parser is requested.
filename and filename* are preserved as separate parameters. The helper
serializes the parameter values it is given, parses those values back as
metadata, and does not decode RFC 5987 extended values or choose between
filename and filename*. Applications remain responsible for any filename
precedence, display, storage, or download policy. These helpers are
metadata-only: RTTP does not start automatic downloads, derive filesystem
paths, sniff MIME types, negotiate response variants, redirect, retry/replay,
cache, or attach status-code policy from Content-Disposition.
Server-side representation metadata helpers expose request parsing and
response declaration without changing payload bytes.
Request::content_type() and HttpRequest::content_type() parse a singleton
received Content-Type field into HttpContentType and return Ok(None)
when absent. Duplicate Content-Type fields are a helper error.
Request::content_encoding() and HttpRequest::content_encoding() parse
received Content-Encoding fields in wire order into
HttpResponseContentEncodings. HTTP/1.1 and HTTP/2 share the same Request
helpers. HttpContentType::parse(value)
validates a Content-Type field, normalizes the media type and parameter
names to lowercase, preserves parameter values, and exposes
media_type(), type_(), subtype(), parameter(name), parameters(),
and header_value().
HttpContentType::new(type_name, subtype) constructs a normalized media type,
and with_parameter(name, value) appends safely serialized parameters with
normalized names and preserved values.
HttpResponse::with_content_type(value) accepts any IntoHttpContentType,
removes existing raw Content-Type fields, and adds one validated
Content-Type header. HttpResponse::content_type() parses an attached
singleton header and returns Ok(None) when the header is absent.
HttpResponseContentEncodings::parse(value) validates comma-separated
Content-Encoding codings, while
HttpResponseContentEncodings::from_codings(codings) validates an explicit
coding list for declarations. HttpResponse::with_content_encoding(codings)
removes existing raw Content-Encoding fields and adds one validated
comma-separated header. HttpResponse::content_encoding() parses all attached
Content-Encoding fields in wire order and returns Ok(None) when absent.
Coding spelling and order are preserved, including repeated codings across
one or more header fields.
Parsing and declaration are bounded. Each Content-Type and
Content-Encoding field value is limited to 64 KiB. Server Content-Type
helpers accept at most 256 parameters and reject malformed media types,
malformed parameter syntax, malformed quoted strings, duplicate parameters,
duplicate singleton fields, CR/LF or other control bytes, oversized values,
and too many parameters. Server Content-Encoding helpers accept at most 256
codings and reject empty members, malformed tokens, oversized values, and too
many codings. Raw Request::header(...) and
HttpResponse::header(...) values remain preserved exactly as ordinary
headers until a typed declaration helper replaces them or the typed parser is
requested; parser errors do not remove existing headers or change the request
body.
let content_type = request.content_type()?.expect("Content-Type");
if content_type.media_type() == "application/json" {
let charset = content_type.parameter("charset");
}
let encodings = request.content_encoding()?.expect("Content-Encoding");
assert_eq!(vec!["gzip"], encodings.codings());
let declared = HttpContentType::new("application", "json")?
.with_parameter("charset", "utf-8")?;
let response = HttpResponse::ok("{}")
.with_content_type(declared)?
.with_content_encoding(["gzip", "br"])?;
let codings = response.content_encoding()?.expect("Content-Encoding");
assert_eq!(vec!["gzip", "br"], codings.codings());These helpers parse request metadata only; they do not sniff, decode,
negotiate, cache, redirect, retry, or select representations from
Content-Type or Content-Encoding.
Server-side Vary helpers expose response declaration and request-selection
metadata without implementing a cache. HttpResponse::with_vary(value) parses
and normalizes a response Vary value before adding the header, while
HttpResponse::vary() parses any Vary headers already attached to a
response. HttpVary::parse(value) accepts either * or a comma-separated
list of field names. Named fields are normalized to lowercase, deduplicated,
and exposed through HttpVary::field_names().
Request::vary_selection(&vary) and HttpRequest::vary_selection(&vary)
collect the current request header values named by a parsed HttpVary, using
case-insensitive header-name matching. Wildcard Vary produces a wildcard
HttpVarySelection and does not read specific request headers. Named
selection values are metadata for application-owned policy; RTTP does not
compare them against stored cache keys.
Parsing is bounded and validation-oriented. Each Vary field value is limited
to 64 KiB, the parsed field-name list is limited to 256 entries, and each
named member must be a valid HTTP token. Empty members, malformed field names,
mixed wildcard/named values, oversized values, and too many field names return
HttpVaryParseError from the helper. A parse error does not by itself reject a
request before handler code or remove existing response headers.
These helpers do not add cache storage, a stored-response matching engine, cache key persistence, automatic request replay, shared-cache policy enforcement, or automatic conditional requests. Applications that build a cache must persist any selected request metadata and enforce their own cache policy around these helpers.
Server-side No-Vary-Search helpers expose response declaration metadata
without implementing a cache. HttpResponse::with_no_vary_search(value)
parses and normalizes a declaration before replacing any existing
No-Vary-Search response fields, while HttpResponse::no_vary_search()
parses attached raw fields into HttpNoVarySearch metadata.
The helpers expose recognized key-order, params, and except members and
keep extension dictionary members as metadata. They do not create cache
storage, match cache keys, normalize URLs, replay requests, apply browser
navigation behavior, or enforce shared-cache policy.
Server-side Permissions-Policy helpers expose response declaration metadata
without enforcing browser permissions or origin policy.
HttpResponse::with_permissions_policy(value) parses a W3C Permissions Policy
Structured Fields dictionary through the shared protocol parser and replaces
any existing Permissions-Policy response fields with one canonical value,
while HttpResponse::permissions_policy() parses attached raw fields into
HttpPermissionsPolicy metadata. The typed value exposes ordered feature
directives with their allowlists: the * token as the whole allowlist, the
self token, quoted serialized HTTP(S) origins, and inner lists including the
empty () form.
The helpers are bounded and metadata-only. Field values are limited to 64 KiB,
directives to 256 per header set, and allowlist members to 256 per directive.
They do not grant or deny browser permissions, compare origins, resolve
self, enable or disable APIs, enforce origin policy, or send reports.
Server-side Document-Policy helpers expose response declaration metadata
without enforcing document policy in the HTTP layer.
HttpResponse::with_document_policy(value) parses a WICG Document Policy
Structured Fields dictionary through the shared protocol parser and replaces
any existing Document-Policy response fields with one canonical value, while
HttpResponse::document_policy() parses attached raw fields into
HttpDocumentPolicy metadata. The typed value exposes ordered
configuration-point directives with their typed values: boolean (including a
bare ?1), integer, decimal, or token. Directive names are opaque lowercase
tokens or * and are not looked up against a browser configuration-point
list. A well-formed report-to parameter is accepted as a token or a quoted
string and retained on the directive.
The helpers are bounded and metadata-only. Field values are limited to 64 KiB,
the cumulative raw bytes across all supplied fields to 64 KiB, and directives
to 256 per header set. They do not execute configuration points, block
document loads, compare required policies, echo
Sec-Required-Document-Policy, enable or disable browser features, or send
reports.
HttpResponse::with_document_policy_report_only(value) and
HttpResponse::document_policy_report_only() expose
Document-Policy-Report-Only metadata through the same shared protocol
parser, formatter, directive model, and bounds while returning distinct
HttpDocumentPolicyReportOnly metadata. Declaration replaces raw duplicate
report-only fields with one canonical value. These helpers do not enforce
policy or deliver reports.
Server-side Supports-Loading-Mode helpers expose response declaration
metadata without applying prerender or fenced-frame loading policy.
HttpResponse::with_supports_loading_mode(tokens) validates a declared token
list through the shared protocol parser and replaces any existing
Supports-Loading-Mode response fields with one canonical comma-separated
value, while HttpResponse::supports_loading_mode() parses attached raw
fields into HttpSupportsLoadingMode metadata. The typed value exposes the
ordered tokens with tokens(), membership checks with contains(token), and
exact predicates for the defined fenced-frame,
credentialed-prerender, and prerender-cross-origin-frames tokens;
well-formed unknown tokens such as uncredentialed-prerender are retained.
The helpers are bounded and metadata-only. Field values are limited to 64 KiB, the combined raw bytes across fields to 64 KiB, and tokens to 256 per header set. They do not prerender documents, admit fenced frames, change navigation, or alter resource loading.
Server-side Sec-WebSocket-Version helpers expose request access and
response declaration metadata without negotiating versions or switching
protocols. Request::sec_websocket_version() and
HttpRequest::sec_websocket_version() parse received fields into
HttpSecWebSocketVersion. HttpResponse::with_sec_websocket_version(versions)
validates a declared version list through the shared protocol parser and
replaces any existing Sec-WebSocket-Version response fields with one
canonical comma-separated value, while HttpResponse::sec_websocket_version()
parses attached raw fields. Recognized values are RFC 6455 version tokens
(0 through 299 without leading zeros) in numeric descending order, such as
13 or 13, 8, 7.
The helpers are bounded and metadata-only. Field values are limited to 64 KiB,
the combined raw or canonical serialized field set to 64 KiB, and members to
32 per header set. They do not perform a WebSocket handshake, emit
Connection: Upgrade or Upgrade: websocket, compute Sec-WebSocket-Accept,
negotiate versions, or switch protocols.
Server-side Sec-WebSocket-Protocol helpers expose request offers and
response selection metadata without choosing an application subprotocol or
switching protocols. Request::sec_websocket_protocol() and
HttpRequest::sec_websocket_protocol() parse received fields into
HttpSecWebSocketProtocol as offers in preference order.
HttpResponse::with_sec_websocket_protocol(token) validates one selected
token through the shared protocol parser and replaces any existing
Sec-WebSocket-Protocol response fields with one canonical value, while
HttpResponse::sec_websocket_protocol() parses attached raw fields as a
selection singleton.
The helpers are bounded and metadata-only. Field values are limited to 64 KiB,
the combined raw or canonical serialized field set to 64 KiB, and members to
32 per header set. They do not perform a WebSocket handshake, emit
Connection: Upgrade or Upgrade: websocket, choose an application
subprotocol, or switch protocols; applications own the selection decision.
Server-side Sec-WebSocket-Extensions helpers expose request offers and
response selection metadata without activating compression, negotiating
extensions, or switching protocols. Request::sec_websocket_extensions() and
HttpRequest::sec_websocket_extensions() parse received fields into
HttpSecWebSocketExtensions as ordered offers. The representation validates
extension tokens, ordered parameters, token and quoted-string parameter
values, duplicate extension tokens, duplicate parameter names, member count,
and total size. HttpResponse::with_sec_websocket_extensions(value) validates
one selected extension member and replaces any existing
Sec-WebSocket-Extensions response fields with one canonical value, while
HttpResponse::sec_websocket_extensions() parses attached raw fields as a
selection singleton.
The helpers are bounded and metadata-only. Field values are limited to 64 KiB,
the combined raw or canonical serialized field set to 64 KiB, and extension
members to 32 per header set. They do not perform a WebSocket handshake, emit
Connection: Upgrade or Upgrade: websocket, activate compression, negotiate
extensions, or switch protocols; applications own all extension behavior.
HttpResponse::with_speculation_rules(value) validates and replaces any raw
Speculation-Rules response fields with one bounded opaque value, while
HttpResponse::speculation_rules() parses attached raw fields into
HttpSpeculationRules. Values are limited to 64 KiB, duplicate fields fail
closed, and response-field injection bytes are rejected. The helpers do not
fetch, parse, validate, or execute speculation rule resources.
The server is intentionally small: it handles blocking HTTP/1.x request parsing
for local tests and simple embedded use. It accepts fixed Content-Length and
chunked request bodies, exposes chunked request trailers, applies bounded
request head/body validation, handles HEAD without writing a response body,
honors Connection close/keep-alive semantics across a bounded
serve_requests loop, writes response body framing and response trailers
consistently, and exposes Expect: 100-continue metadata without automatically
sending an interim response or rejecting extensions. On the same socket2 listener,
the accept path detects either the HTTP/2 client preface or an HTTP/1.1
Upgrade: h2c request and dispatches the resulting h2c connection to the same
minimal bounded handler, including bodyless DELETE, OPTIONS, and TRACE
requests. HTTP/1.1 h2c Upgrade is opt-in on both sides: the request must be
HTTP/1.1, include Connection: Upgrade, HTTP2-Settings, Upgrade: h2c,
exactly one HTTP2-Settings field with a valid unpadded base64url SETTINGS
payload, and no request body; malformed h2c upgrade attempts receive
400 Bad Request before handler dispatch. When the upgrade is valid, the
server writes 101 Switching Protocols, consumes the client's HTTP/2 preface
on the same socket, applies the advertised SETTINGS as the initial peer
SETTINGS, and uses the HTTP/2 stream id sequence reserved for an HTTP/1.1
upgrade. The server advertises SETTINGS_MAX_CONCURRENT_STREAMS from the
active request allowance for that bounded accept path and rejects new h2c
streams once the open-stream count plus completed requests reaches that
allowance. It also advertises and enforces a conservative
SETTINGS_MAX_HEADER_LIST_SIZE for inbound request metadata; request HEADERS
and trailing HEADERS can span CONTINUATION frames, but the decoded metadata
remains bounded before handler dispatch. The server validates peer
SETTINGS_ENABLE_PUSH values as only 0 or 1; any other value rejects the
bounded h2c handshake. It also validates SETTINGS_ENABLE_CONNECT_PROTOCOL
values as only 0 or 1; a received value of 1, whether in the initial peer
SETTINGS or a later SETTINGS update, enables bounded RFC 8441 extended CONNECT
request dispatch for subsequent HEADERS on that connection. Without that
negotiated setting, any :protocol pseudo-header is rejected before handler
dispatch. The server advertises the default 16,384-byte
SETTINGS_MAX_FRAME_SIZE, rejects peer SETTINGS values outside the legal
HTTP/2 range of 16,384 through 16,777,215 bytes, rejects inbound frames larger
than the active local limit, and splits outbound response HEADERS, DATA, and
trailing HEADERS to the active peer frame-size limit. It preserves the same
HEAD body suppression for prior-knowledge h2c responses.
Incoming padded HEADERS, DATA, and trailer frames are accepted without exposing
padding bytes to handlers, and application trailers such as X-Trace,
X-Upload-Status, and X-Upload-Checksum are preserved on Request.
Trailing HEADERS that contain HTTP/2 pseudo-headers are rejected before handler
dispatch. Trailer field names that affect connection state, routing,
authentication/cookies, framing, or payload processing are also rejected,
including Connection, Keep-Alive, Proxy-Connection, TE, Trailer,
Transfer-Encoding, Upgrade, Host, Content-Length, Cache-Control,
Content-Encoding, Content-Range, Content-Type, Max-Forwards,
Authorization, Proxy-Authenticate, Proxy-Authorization, Cookie,
Set-Cookie, and WWW-Authenticate. HPACK static Huffman strings, request
dynamic table entries, and bounded large header blocks are carried with
CONTINUATION frames. The server accepts peer SETTINGS_HEADER_TABLE_SIZE
values as the outbound response compression allowance and applies later peer
updates before encoding response trailers. If the peer advertises zero, the
server evicts response dynamic entries and writes response HEADERS and trailers
without dynamic indexing. Inbound request and request-trailer decoding stays
bounded to the server's fixed 4,096-byte HPACK dynamic table limit; incoming
dynamic table size updates may shrink that decoder table, including to zero,
but updates above 4,096 bytes are rejected. These table-size boundaries affect
only HPACK compression state, not decoded metadata limits, trailer validation,
handler dispatch, DATA flow control, or multiplex scheduling.
Prior-knowledge h2c request headers reject HTTP/1.x connection-specific fields
before handler dispatch: Connection, Keep-Alive, Proxy-Connection,
Transfer-Encoding, and Upgrade; TE is accepted only as te: trailers
and other TE values are rejected. When serializing h2c responses, the server
strips HTTP/1.x connection-specific response fields and generated HTTP/2
framing fields from HEADERS: Connection, Keep-Alive, Proxy-Connection,
TE, Trailer, Transfer-Encoding, Upgrade, and Content-Length. H2c
response trailers skip the existing forbidden trailer set, including invalid
pseudo-header-like names, connection-specific, transfer/framing, routing,
authentication, and cookie fields.
Valid standalone PRIORITY frames and HEADERS priority fields are validated and
ignored as metadata; malformed priority metadata is rejected, and request or
response ordering does not use priority scheduling. Inbound PING without ACK
is acknowledged only when it arrives on stream 0 with exactly 8 octets of
opaque data; the PING ACK carries that same opaque data. Inbound PING ACK is
ignored for this bounded path. PING with a non-zero stream id or payload length
other than 8 is malformed and rejected. RTTP does not add keepalive timers,
automatic client- or server-initiated PING policy, replay behavior, a full
session manager, or a full multiplex scheduler around this acknowledgement
path.
Unknown frame types, including extension frames, are ignored only after the
HTTP/2 preface is accepted in this bounded h2c server path where HTTP/2
permits that behavior; RTTP does not expose an extension callback API or
negotiate extensions. Reserved stream identifier high bits are masked when
frames are parsed or written, which normalizes frame identifiers without
adding unbounded multiplexing, session management, or external h2-stack
support.
Server push is outside this bounded server path: inbound PUSH_PROMISE frames
are rejected deterministically before handler dispatch instead of attempting
push state management, and RTTP does not implement server-side push state even
when a peer sends SETTINGS_ENABLE_PUSH = 1.
When the bounded prior-knowledge h2c server loop finishes, it sends GOAWAY
with the last completed stream id so clients have a deterministic shutdown
boundary for already processed streams. If the bounded request allowance is
exhausted while additional streams are already open, the server first sends a
graceful GOAWAY boundary and lets streams within that boundary finish; new
streams outside the boundary are refused with REFUSED_STREAM and are not
dispatched to the handler. If the peer closes the TCP connection, a read/write
timeout fires, or the socket is reset before GOAWAY can be written, that is
transport termination rather than an HTTP/2 graceful shutdown signal and no
additional stream boundary is implied.
Within that same prior-knowledge h2c server path, inbound RST_STREAM is a
bounded reset/cancellation signal for the affected stream: reset request
streams are not dispatched to handlers, and reset response streams stop within
the bounded write path. RTTP does not expose a public cancellation callback API,
retry work automatically, keep persistent HTTP/2 sessions, or model a full
HTTP/2 stream state machine around those resets.
The h2c handler does not share the HTTP/1.1 CONNECT or non-h2c Upgrade
handoff paths. Ordinary h2c CONNECT without :protocol remains unsupported
proxy tunneling and is rejected before handler dispatch. Negotiated extended
CONNECT is exposed to handlers as a normal Request with method CONNECT,
version HTTP/2, origin-form target from :path, host derived from
:authority, and Request::extended_connect_protocol() returning the
:protocol value. The handler returns a normal HttpResponse; RTTP does not
switch the stream to caller-owned tunnel bytes. HTTP/1.1 CONNECT
authority-form requests and HttpHandoff::upgrade for non-h2c protocols
remain separate handoff paths for caller-owned protocols, and the h2c Upgrade
detection preserves those existing handoffs when Upgrade is not h2c. TLS
ALPN, extension callback APIs, full
extension negotiation, external h2 integration, full WebSocket-over-h2, proxy
h2, tunnel handoff, connection pooling, persistent multiplex sessions,
persistent HTTP/2 session management, full RFC 8441 support, and full HTTP/2
features such as unbounded multiplexing, unbounded multiplex scheduling,
general multiplexing, general tunnel scheduling, server push, and priority
scheduling remain outside this bounded prior-knowledge server path. RTTP does
not expose a dynamic policy API for changing the h2c frame-size or metadata
limit at runtime.
use rttp::server::HttpResponse;
fn main() -> std::io::Result<()> {
let server = rttp::Http::server("127.0.0.1:8080")?;
server.accept_one(|request| {
if request.method() == "CONNECT"
&& request.version() == "HTTP/2"
&& request.extended_connect_protocol() == Some("websocket")
{
return HttpResponse::ok("accepted extended CONNECT metadata");
}
HttpResponse::new(400, "Bad Request")
})
}It is not a full RFC-covering web server and still does not implement server TLS or async accept loops.
| area | tested coverage | limits |
|---|---|---|
| HTTP/1.1 request parsing | Required Host validation, origin-form, absolute-form, asterisk-form OPTIONS, authority-form CONNECT, fixed and chunked bodies, chunk extensions, protocol-owned Expect metadata including 100-continue, and obsolete line folding rejection |
Expect metadata does not send 100 Continue or reject unsupported extensions; intended for local tests and simple embedded use, not full RFC coverage |
| HTTP/1.1 connection handling | Bounded sequential serve_requests, keep-alive and close behavior for HTTP/1.1 and HTTP/1.0, pipelined request boundaries, malformed request rejection before handler dispatch |
Blocking listener only; no async accept loop |
| HTTP/1.1 response framing | Automatic Content-Length, explicit chunked responses, bodyless HEAD, 101, 204, and 304, response trailers after the terminating chunk |
No server TLS |
| Byte ranges | HttpByteRange parses one bytes range, Request::evaluate_if_range gates it with caller-provided strong ETag or exact HTTP-date metadata, HttpResponse::partial_content/range_not_satisfiable serialize 206/416 with Content-Range, and HttpAcceptRanges plus HttpResponse::with_accept_ranges/with_accept_ranges_none/accept_ranges declare and parse bounded Accept-Ranges metadata while preserving raw headers |
No Range request generation, multipart range serialization, partial response engine, automatic retry/replay, redirect behavior, cache storage or policy, filesystem serving, MIME detection, automatic cache validation, automatic static-file policy, automatic byte serving, content slicing, download resume, or status-policy behavior |
| Conditional requests | Request::evaluate_conditional, evaluate_conditional_request, HttpConditionalMetadata, and HttpEntityTag evaluate bounded HTTP/1.1 validators; Request::if_modified_since/if_unmodified_since and the HttpRequest equivalents parse HTTP-date validators through the shared protocol types; HttpResponse::not_modified, precondition_failed, with_etag, and typed bounded etag serialize or expose 304/412 metadata while preserving raw headers; with_delta_base/delta_base declare and parse bounded singleton Delta-Base metadata through the shared entity-tag primitive; with_schedule_tag and schedule_tag declare and parse bounded Schedule-Tag response metadata through the shared protocol type |
No cache storage, static-file serving policy, automatic revalidation, cached-entity lookup, delta application, calendar-version generation, schedule-tag comparison, calendar inspection, scheduling policy, or cache-control engine |
| Informational responses and Early Hints | HttpResponse::early_hints and early_hints_with_headers construct validated bodyless 103 Early Hints response metadata with bounded Link and safe metadata headers |
101 Switching Protocols remains a separate terminal handoff response; no automatic preload execution, cache policy, redirect/retry/replay, route generation, streaming early-write API, TLS/ALPN behavior, or status-policy behavior |
| Cache-Control, CDN-Cache-Control, and Cache-Status | Request::cache_control, HttpRequest::cache_control, and HttpResponse::cache_control parse bounded request/response directives, numeric freshness fields, quoted field-name lists, and extension directives; HttpResponse::cdn_cache_control parses bounded response CDN-Cache-Control directives and CDN extension metadata while preserving raw response headers on parse errors; HttpResponse::cache_status parses bounded RFC 9211 Cache-Status list members and parameters while preserving raw response headers on parse errors; HttpResponse::with_age/age, with_expires/expires, and protocol-backed with_retry_after_delta/with_retry_after_date/retry_after declare and parse response Age, Expires, and Retry-After metadata |
No cache storage, CDN cache, Cache-Status forwarding or freshness policy, automatic revalidation, wall-clock freshness calculation, Vary matching, shared-cache policy enforcement, surrogate-key behavior, automatic conditional requests, directive-based validator evaluation, automatic sleep, retry, replay, backoff, scheduler integration, or status-code policy engine |
| Cache-Control, CDN-Cache-Control, Surrogate-Control, and Cache-Status | Request::cache_control, HttpRequest::cache_control, and HttpResponse::cache_control parse bounded request/response directives, numeric freshness fields, quoted field-name lists, and extension directives; HttpResponse::cdn_cache_control parses bounded response CDN-Cache-Control directives and CDN extension metadata while preserving raw response headers on parse errors; HttpResponse::with_surrogate_control/surrogate_control and client Response::surrogate_control parse or declare bounded Surrogate-Control directives through the shared protocol type, rejecting duplicates and oversized aggregate values while preserving raw headers on parse errors; HttpResponse::cache_status parses bounded RFC 9211 Cache-Status list members and parameters while preserving raw response headers on parse errors; HttpResponse::with_date/date, with_age/age, with_expires/expires, with_last_modified/last_modified_date, and with_retry_after_delta/with_retry_after_date/retry_after declare and parse response Date, Age, Expires, Last-Modified, and Retry-After metadata |
No cache storage, CDN cache, Cache-Status forwarding or freshness policy, automatic revalidation, wall-clock freshness calculation, Vary matching, shared-cache policy enforcement, surrogate-key behavior, Surrogate-Control to Cache-Control translation, automatic conditional requests, directive-based validator evaluation, automatic sleep, retry, replay, backoff, scheduler integration, or status-code policy engine |
| Memento-Datetime | HttpResponse::with_memento_datetime/memento_datetime declare and parse bounded singleton Memento-Datetime IMF-fixdate metadata while preserving raw headers on parse errors |
No archival selection, Accept-Datetime negotiation, TimeGate behavior, retry, or transport changes |
| Accept-Datetime | Request::accept_datetime/HttpRequest::accept_datetime parse bounded singleton Accept-Datetime request metadata into HttpAcceptDatetime, accepting obsolete HTTP-date forms and preserving raw headers on parse errors |
No archival selection, TimeGate behavior, Vary injection, cache-policy changes, or conditional evaluation |
| Fetch Metadata | Request::sec_fetch_site, sec_fetch_mode, sec_fetch_dest, sec_fetch_user, and sec_purpose parse bounded typed Sec-Fetch-*/Sec-Purpose request fields and preserve raw values on errors |
No browser security policy, request blocking, origin validation, navigation policy, automatic header generation, prefetch execution, or cache behavior |
| Save-Data | Request::save_data and HttpRequest::save_data parse bounded singleton Save-Data on-token metadata and preserve raw values on errors |
No reduced-data serving, content adaptation, compression, Client Hints advertisement, retries, or browser data-saver policy |
| DNT | Request::dnt and HttpRequest::dnt parse bounded singleton DNT 0/1 preference metadata through HttpDnt and preserve raw values on errors |
No tracking enforcement, cookie changes, Referer stripping, analytics or advertising behavior, Tk synthesis, retries, or privacy-preference policy |
| Accept | HttpAccept, Request::accept, and HttpRequest::accept parse bounded Accept request metadata through the shared rttp-protocol type, preserving raw values on errors |
No content negotiation, representation selection, MIME sniffing, body decoding, cache Vary synthesis, or response choice |
| Accept-Charset | HttpRequestAcceptCharsets, Request::accept_charset, and HttpRequest::accept_charset parse bounded Accept-Charset request metadata through the shared rttp-protocol type |
No content negotiation, charset transcoding, body decoding, MIME sniffing, or response selection |
| Negotiate | Request::negotiate and HttpRequest::negotiate parse bounded RFC 2295 Negotiate request metadata into HttpNegotiate through the shared rttp-protocol type and preserve raw values on errors |
No variant selection, transparent content negotiation, Alternates/TCN/Vary synthesis, or automatic cache selection |
| TCN | HttpResponse::with_tcn and HttpResponse::tcn declare or parse bounded RFC 2295 TCN response metadata through HttpTcn and preserve raw headers on accessor errors |
No variant selection, Alternates/Vary synthesis, transparent content negotiation, or cache behavior |
| Set-Cookie | HttpResponse::with_set_cookie and HttpResponse::set_cookies declare or parse bounded protocol Set-Cookie response metadata, preserve multiple field lines and raw headers, redact cookie values from typed debug and errors, and reject invalid typed metadata including duplicate attributes, valued flag attributes, non-standard SameSite, invalid Max-Age, malformed quoted values, and bounds violations |
No cookie jar, persistence, domain/path matching, expiry enforcement, SameSite or partitioning policy, or automatic request Cookie emission |
| Variant-Vary | HttpVariantVary, HttpResponse::with_variant_vary, and HttpResponse::variant_vary declare or parse bounded RFC 2295 Variant-Vary response metadata through the shared protocol type, replacing raw duplicates on declaration and preserving raw headers on accessor errors |
No cache-key construction, variant selection, Alternates/TCN/Vary synthesis, transparent content negotiation, or cache behavior |
| Sec-GPC | Request::sec_gpc and HttpRequest::sec_gpc parse bounded singleton Sec-GPC 1-signal metadata and preserve raw values on errors |
No consent inference, tracking-policy enforcement, legal policy, serving policy, retries, or browser state |
| Upgrade-Insecure-Requests | Request::upgrade_insecure_requests and HttpRequest::upgrade_insecure_requests parse bounded singleton Upgrade-Insecure-Requests 1-token metadata and preserve raw values on errors |
No URL rewriting, redirecting, Content-Security-Policy enforcement, HSTS, or automatic scheme selection |
| Depth | Request::depth and HttpRequest::depth parse bounded singleton WebDAV Depth request metadata through the shared protocol type and preserve raw values on errors |
No resource traversal, WebDAV method selection, method-policy enforcement, retry, or forwarding policy |
| Destination | Request::destination and HttpRequest::destination parse bounded singleton WebDAV Destination request metadata through the shared protocol type and preserve raw values on errors |
No destination resolution, URI normalization, authorization, COPY/MOVE execution, or application resource policy |
| Lock-Token | HttpLockToken, Request::lock_token, HttpRequest::lock_token, HttpResponse::with_lock_token, and HttpResponse::lock_token parse or declare bounded singleton WebDAV Lock-Token metadata through the shared protocol type while preserving raw headers on errors and redacting tokens from typed debug output |
No lock creation, refresh, release, persistence, ownership comparison, or WebDAV lock policy |
| Timeout | Request::timeout and HttpRequest::timeout parse bounded ordered WebDAV Timeout request metadata through the shared protocol type and preserve raw values on errors |
No lock creation, lock refresh, application-timeout selection, retry, or forwarding policy |
| Overwrite | Request::overwrite and HttpRequest::overwrite parse bounded singleton WebDAV Overwrite request metadata through the shared protocol type and preserve raw values on errors |
No destination overwrite, RFC 4918 default-T synthesis, resource policy, COPY/MOVE execution, retry, or forwarding policy |
| If | HttpIf, Request::if_header, and HttpRequest::if_header parse bounded RFC 4918 WebDAV If request metadata through the shared protocol type, accepting untagged or tagged condition lists with Not, state tokens, and bracketed entity tags, preserving order, redacting state tokens from typed debug output, and preserving raw values on errors without evaluating resource state |
No lock, entity-tag, or resource-state evaluation; no 412 or other precondition outcome; no lock creation, refresh, or release; no COPY/MOVE/UNLOCK execution; no retry, or forwarding policy |
| DAV | Dav, HttpDav, HttpResponse::with_dav/dav, and client Response::dav parse or declare bounded ordered WebDAV DAV response metadata through the shared protocol type, accepting 1, 2, 3, extension tokens, and <absolute-URI> Coded-URLs while preserving raw headers on parse failures |
No WebDAV feature inference, feature negotiation, method support enforcement, route dispatch, lock behavior, or application resource policy |
| WebDAV metadata matrix | Workspace integration tests cover live HTTP/1.1 and h2c client/server/facade roundtrips for Depth, Destination, Overwrite, Timeout, Lock-Token, If, DAV, If-Schedule-Tag-Match, and Schedule-Tag, including valid values, malformed/duplicate/bounds rejection, raw-header observability, and Lock-Token/If redaction |
No resource storage, locking, COPY/MOVE/LOCK/UNLOCK execution, default Overwrite: T synthesis, or WebDAV method policy |
| Transparent negotiation metadata matrix | Workspace integration tests cover live HTTP/1.1 and h2c client/server/facade roundtrips for A-IM, IM, Delta-Base, Alternates, Negotiate, TCN, and Variant-Vary, including valid values, malformed/duplicate/bounds rejection, raw-header observability, and declared-order q-value recording |
No variant selection, Alternates URI fetching, delta application, 226 IM Used synthesis, or cache policy |
| Idempotency-Key | Request::idempotency_key and HttpRequest::idempotency_key parse bounded singleton opaque Idempotency-Key request metadata through the shared protocol type, preserve raw values on errors, and redact the key from typed debug output |
No retry, replay, key storage or comparison, deduplication store, or application idempotency policy |
| WebSocket handshake metadata | Request::sec_websocket_key and HttpRequest::sec_websocket_key parse bounded singleton Sec-WebSocket-Key request metadata through the shared protocol type and preserve raw values on errors; HttpResponse can derive and parse bounded singleton Sec-WebSocket-Accept metadata from a validated key using the RFC GUID plus SHA-1/base64 transform; typed debug output redacts key and accept material |
No HTTP upgrade, random nonce generation, WebSocket frames, or handshake policy |
| Sec-WebSocket-Version | HttpSecWebSocketVersion, Request::sec_websocket_version, HttpRequest::sec_websocket_version, HttpResponse::with_sec_websocket_version, and HttpResponse::sec_websocket_version parse and declare bounded version-list metadata through the shared protocol type, requiring canonical descending order, replacing raw duplicates on declaration, and preserving raw headers on parse failures |
No WebSocket handshake, Connection: Upgrade emission, Sec-WebSocket-Accept computation, version negotiation, protocol switch, or frames |
| Sec-WebSocket-Protocol | HttpSecWebSocketProtocol, Request::sec_websocket_protocol, HttpRequest::sec_websocket_protocol, HttpResponse::with_sec_websocket_protocol, and HttpResponse::sec_websocket_protocol parse and declare bounded protocol-token metadata through the shared protocol type: request offers preserve preference order while response values are selection singletons, with case-sensitive duplicates rejected and raw headers preserved on parse failures |
No WebSocket handshake, Connection: Upgrade emission, automatic subprotocol choice, protocol switch, or frames |
| Sec-WebSocket-Extensions | HttpSecWebSocketExtensions, Request::sec_websocket_extensions, HttpRequest::sec_websocket_extensions, HttpResponse::with_sec_websocket_extensions, and HttpResponse::sec_websocket_extensions parse and declare bounded extension-list metadata through the shared protocol type: request offers preserve extension and parameter order while response values are one-extension selection singletons, with duplicates rejected and raw headers preserved on parse failures |
No WebSocket handshake, Connection: Upgrade emission, compression activation, extension negotiation, protocol switch, or frames |
| Pragma | HttpPragma, Request::pragma, HttpRequest::pragma, HttpResponse::with_pragma, and HttpResponse::pragma share the bounded protocol Pragma representation for server request access and server response construction, combining fields in wire order and preserving raw headers on errors |
No translation into Cache-Control, cache storage, freshness checks, revalidation, or cache/intermediary policy |
| W3C Trace Context | Request::traceparent/tracestate and HttpRequest helpers parse bounded W3C Trace Context request metadata, preserve raw values on errors, preserve tracestate ordering, and redact propagation values from typed debug output |
No trace-id creation, sampling decision, tracing backend, span model, or automatic propagation |
| W3C Baggage | Request::baggage and HttpRequest::baggage parse bounded W3C Baggage request metadata, preserve raw values on errors, preserve member order, and redact member and property values from typed debug output |
No application-data interpretation, request-context storage, tracing backend, span model, or automatic propagation |
| X-Forwarded compatibility metadata | Request::x_forwarded_for, x_forwarded_host, and x_forwarded_proto plus HttpRequest helpers parse bounded ordered node, authority, and scheme metadata while preserving raw headers on errors |
No forwarded identity trust, client address selection, routing rewrite, scheme rewrite, redirect, upgrade, enforcement, or trusted-proxy selection; applications must choose trusted proxies |
| Via | Request::via and HttpRequest::via parse bounded HTTP Via hop metadata; HttpResponse::with_via and HttpResponse::via declare or parse caller-supplied chains while preserving raw headers on errors |
No automatic hop insertion or removal, trusted-proxy inference, identity rewrite, or HTTP/1.1 or HTTP/2 proxy-policy changes |
| Accept-Language | HttpAcceptLanguages, Request::accept_language, and HttpRequest::accept_language parse bounded ordered Accept-Language ranges and q-values through the protocol AcceptLanguage type and preserve raw values on errors |
No locale matching, fallback selection, translation lookup, routing, or automatic response choice |
| Vary | HttpVary, HttpResponse::with_vary, HttpResponse::vary, Request::vary_selection, and HttpRequest::vary_selection parse, declare, and select bounded Vary metadata with case-insensitive field-name handling |
No cache storage, stored-response matching engine, cache key persistence, automatic request replay, shared-cache policy enforcement, or automatic conditional requests |
| No-Vary-Search | HttpNoVarySearch, HttpResponse::with_no_vary_search, and HttpResponse::no_vary_search parse and declare bounded Structured Fields response metadata for query-parameter variance declarations |
No cache storage, cache-key matching, URL normalization, navigation behavior, request replay, or shared-cache policy enforcement |
| Permissions-Policy | HttpPermissionsPolicy, HttpResponse::with_permissions_policy, and HttpResponse::permissions_policy parse and declare bounded W3C Permissions Policy dictionary response metadata through the shared protocol type, replacing raw duplicates on declaration and preserving raw headers on parse failures |
No browser permission grants or denials, origin comparison, self resolution, API enablement, origin-policy enforcement, or report sending |
| Document-Policy | HttpDocumentPolicy, HttpResponse::with_document_policy, and HttpResponse::document_policy parse and declare bounded WICG Document Policy dictionary response metadata through the shared protocol type, replacing raw duplicates on declaration, retaining * and report-to, and preserving raw headers on parse failures |
No configuration-point execution, document-load blocking, required-policy comparison, Sec-Required-Document-Policy echoing, feature enablement, or report sending |
| Document-Policy-Report-Only | HttpDocumentPolicyReportOnly, HttpResponse::with_document_policy_report_only, and HttpResponse::document_policy_report_only parse and declare bounded WICG Document Policy Report-Only dictionary metadata through the same shared protocol parser and formatter, replacing raw duplicates on declaration, retaining report-only type identity, *, and report-to, and preserving raw headers on parse failures |
No policy enforcement, document-load blocking, required-policy comparison, Sec-Required-Document-Policy echoing, feature enablement, report delivery, scheduling, retry, or endpoint validation |
| Supports-Loading-Mode | HttpSupportsLoadingMode, HttpResponse::with_supports_loading_mode, and HttpResponse::supports_loading_mode parse and declare bounded Structured Fields token-list response metadata through the shared protocol type, replacing raw duplicates on declaration, retaining unknown tokens, and preserving raw headers on parse failures |
No prerendering, fenced-frame admission, navigation changes, redirects, retries, or resource-loading behavior |
| Allow | HttpAllowedMethods, HttpResponse::with_allow, and HttpResponse::allow declare and parse bounded Allow method-list metadata |
No route dispatch, automatic 405 generation, OPTIONS policy, fallback method selection, retry/replay, or status-code policy engine |
| Content-Security-Policy-Report-Only | HttpContentSecurityPolicyReportOnly, HttpResponse::with_content_security_policy_report_only, content_security_policy_report_only, and client Response::content_security_policy_report_only parse or declare bounded opaque Content-Security-Policy-Report-Only response metadata while preserving repeated fields in wire order and raw headers on parse failures |
No CSP enforcement, directive evaluation, report delivery, browser policy state, retry, redirect, cache behavior, or status-policy behavior |
| Content-Language | HttpContentLanguages, Request::content_language, HttpRequest::content_language, HttpResponse::with_content_language, and HttpResponse::content_language parse or declare bounded Content-Language metadata |
No automatic language negotiation, route selection, locale fallback, variant matching, cache policy, retry, replay, redirect, or status-policy behavior |
| Accept-Encoding | HttpRequestAcceptEncodings, Request::accept_encoding, and HttpRequest::accept_encoding parse bounded Accept-Encoding request metadata through the shared rttp-protocol type |
No compression, decompression, content negotiation, retries, or transport changes |
| Content-Location | HttpResponse::with_content_location declares one bounded singleton Content-Location header, and HttpResponse::content_location parses attached singleton response metadata while preserving raw headers |
No redirect behavior, cache variant selection, representation replacement, retry/replay, route generation, or status-policy behavior |
| Service-Worker-Allowed | HttpResponse::with_service_worker_allowed declares one bounded singleton Service-Worker-Allowed header, and HttpResponse::service_worker_allowed parses attached singleton path metadata while preserving raw headers |
No service-worker registration, scope evaluation, script-URL resolution, or application routing policy |
| Content-DPR | HttpResponse::with_content_dpr declares one bounded singleton Content-DPR header, and HttpResponse::content_dpr plus client Response::content_dpr parse attached singleton decimal-ratio metadata while preserving raw headers |
No image rescaling, request DPR emission, Client Hints policy, retry, or transport changes |
| Content-Type and Content-Encoding | HttpContentType, Request::content_type, HttpRequest::content_type, HttpResponse::with_content_type, content_type, HttpResponseContentEncodings, Request::content_encoding, HttpRequest::content_encoding, HttpResponse::with_content_encoding, and content_encoding parse or declare bounded representation metadata while preserving raw headers on parse failures and replacing raw response duplicates on typed declaration |
No MIME sniffing, body decoding, charset transcoding, compression/decompression, negotiation, cache policy, redirects, retry/replay, or filesystem serving |
| Connection | HttpConnection, Request::connection, HttpRequest::connection, and HttpResponse::connection parse bounded HTTP/1 Connection tokens, combining duplicate fields in wire order while preserving raw headers on parse failures |
No change to hop-by-hop stripping, keep-alive/close, upgrade/h2c, or HTTP/2 rejection |
| Transfer-Encoding | HttpTransferEncoding, Request::transfer_encoding, and HttpRequest::transfer_encoding parse bounded HTTP/1 Transfer-Encoding fields that must be sole chunked, combining duplicate fields in wire order while preserving raw headers on parse failures |
No change to request_body_kind, TE, Content-Length, or HTTP/2 decode rejection |
| Upgrade metadata | Upgrade, HttpUpgrade, HttpClient::upgrade_protocols, Response::upgrade, Request::upgrade, HttpRequest::upgrade, HttpResponse::with_upgrade, and HttpResponse::upgrade validate, declare, or parse bounded HTTP/1 Upgrade protocol metadata while preserving raw headers on parse failures |
No automatic Connection: Upgrade, h2c selection, client/server socket handoff, ALPN negotiation, or upgraded protocol implementation |
| Content-Disposition | Protocol-backed HttpContentDisposition, HttpResponse::with_content_disposition, with_attachment_filename, and content_disposition declare and parse bounded singleton Content-Disposition response metadata, preserve parsed filename and filename* parameter values, preserve raw headers on parse failures, and replace raw duplicates on typed declaration |
No automatic download, filesystem path handling, MIME sniffing, cache behavior, redirect behavior, retry/replay, negotiation, or status-policy behavior |
| WWW-Authenticate | HttpWwwAuthenticate, HttpResponse::with_www_authenticate, and HttpResponse::www_authenticate declare or parse bounded response authentication challenge metadata while preserving raw headers on parse failures |
No credential storage, authentication policy, retry, automatic Authorization generation, Basic/Bearer implementation, redirect behavior, or status-policy behavior |
| Authorization and Proxy-Authorization | HttpAuthorization, HttpProxyAuthorization, Request::authorization, and Request::proxy_authorization expose shared bounded request authorization metadata, reject duplicate parsed inbound fields, and redact credentials from typed debug output |
No credential storage, authentication policy, challenge processing, retry, Basic/Bearer implementation, redirect policy changes, or automatic credential forwarding |
| Proxy-Status | HttpProxyStatus, HttpResponse::with_proxy_status, and HttpResponse::proxy_status declare or parse bounded RFC 9209 Token/String proxy identifiers with opaque parameters while preserving raw headers on parse failures |
No proxy health checks, retries, trailer promotion, or origin-generation policy |
| Cross-Origin-Opener-Policy-Report-Only | HttpCrossOriginOpenerPolicyReportOnly, HttpResponse::with_cross_origin_opener_policy_report_only, and HttpResponse::cross_origin_opener_policy_report_only declare or parse bounded singleton COOP Report-Only metadata, reuse the canonical COOP directives, retain reporting parameters including report-to, and preserve raw headers on parse failures |
No browsing-context isolation, report scheduling, sending, persistence, retry, routing, or Reporting-Endpoints validation |
| Server-Timing | HttpServerTiming, HttpResponse::with_server_timing, and HttpResponse::server_timing declare or parse bounded response timing metadata while preserving raw headers on parse failures |
No metric collection, measurement, telemetry export, metrics backend integration, retry, redirect behavior, or status-policy behavior |
| Alt-Used | HttpAltUsed, HttpResponse::with_alt_used, and HttpResponse::alt_used declare or parse bounded singleton response authority metadata while preserving raw headers on parse failures and replacing raw response duplicates on typed declaration |
No alternative service selection, origin rewriting, socket migration, retry, or connection-policy behavior |
| Alternates | HttpAlternates, HttpResponse::with_alternates, and HttpResponse::alternates declare or parse bounded RFC 2295-style response variant metadata while preserving raw headers on parse failures and replacing raw response duplicates on typed declaration |
No variant selection, ranking, fetching, request replay, redirect, cache storage, or transparent negotiation behavior |
| Origin-Trial | HttpOriginTrials, HttpResponse::with_origin_trials, and HttpResponse::origin_trials declare or parse bounded opaque Origin-Trial tokens in wire order, preserve duplicates, redact token material from debug output, and replace raw response fields on typed declaration |
No token signature validation, expiration checks, origin applicability, feature activation, or browser trial policy |
| Speculation-Rules | HttpSpeculationRules, HttpResponse::with_speculation_rules, and HttpResponse::speculation_rules preserve one bounded opaque Speculation-Rules response field, reject duplicates and response-field injection bytes, redact debug output, and replace raw response fields on typed declaration |
No speculation rule fetching, parsing, validation, prefetching, prerendering, execution, navigation changes, cache behavior, retry, or redirect behavior |
| Upgrade and tunnel targets | CONNECT authority-form requests are accepted as HTTP requests; HttpHandoff::upgrade can hand an upgraded socket to caller code after a matching request |
The server does not implement the upgraded protocol after handoff |
| Trailers | Chunked request trailers are preserved on Request; malformed, oversized, forbidden, and pseudo-header trailers are rejected; response trailers can be serialized for chunked responses |
Application metadata trailers are allowed; trailer names that affect connection state, routing, authentication/cookies, framing, or payload processing are rejected |
| Bounded h2c server | The same socket2 listener detects the HTTP/2 prior-knowledge preface or a valid HTTP/1.1 Upgrade: h2c request with HTTP2-Settings, validates SETTINGS including legal SETTINGS_ENABLE_PUSH and SETTINGS_ENABLE_CONNECT_PROTOCOL values of only 0 or 1 and legal SETTINGS_MAX_FRAME_SIZE values from 16,384 through 16,777,215 bytes, dispatches RFC 8441 extended CONNECT only after SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 has been negotiated, exposes negotiated extended CONNECT as a normal Request with method CONNECT, version HTTP/2, target from :path, host from :authority, and Request::extended_connect_protocol() from :protocol, advertises the default 16,384-byte SETTINGS_MAX_FRAME_SIZE, rejects inbound frames above the active local limit, splits outbound HEADERS, DATA, and trailers to the active peer frame-size limit, advertises SETTINGS_MAX_CONCURRENT_STREAMS from the bounded active stream allowance, enforces that allowance before dispatching new streams, advertises and enforces a conservative SETTINGS_MAX_HEADER_LIST_SIZE for inbound request metadata, bounds HPACK dynamic table use with SETTINGS_HEADER_TABLE_SIZE, serves bounded streams including bodyless DELETE, OPTIONS, TRACE, and negotiated extended CONNECT, handles HEAD without response DATA, rejects connection-specific request fields before handler dispatch, strips connection-specific response fields during h2c serialization, treats RST_STREAM as a bounded reset/cancellation signal for the affected stream, acknowledges inbound PING without ACK on stream 0 and exactly 8 octets with matching opaque data, ignores inbound PING ACK, rejects malformed PING frames, accepts padded HEADERS/DATA/trailers without exposing padding, handles HPACK Huffman fields and bounded CONTINUATION header blocks, emits GOAWAY with the last completed stream id at bounded shutdown, validates and ignores valid PRIORITY metadata, ignores HTTP/2-allowed unknown/extension frames inside this bounded path, normalizes reserved stream-id high bits, and applies conservative DATA flow control |
Ordinary CONNECT, missing-negotiation :protocol, non-CONNECT :protocol, malformed h2c Upgrade, request bodies on h2c Upgrade, and PUSH_PROMISE are rejected deterministically before handler dispatch; HTTP/1.1 CONNECT and non-h2c Upgrade remain separate handoff paths; bounded h2c only, with no keepalive timers, no automatic client/server initiated PING policy, no public cancellation callback API, no dynamic policy API, no extension callback API, no full extension negotiation, TLS ALPN, external h2 integration, full WebSocket-over-h2, proxy h2, tunnel handoff, connection pooling, persistent multiplex sessions, persistent HTTP/2 session management, automatic retry/replay, server push, full RFC 8441 support, full session manager, full stream state machine, full multiplex scheduler, unbounded multiplexing, unbounded multiplex scheduling, general multiplexing, general tunnel scheduling, priority scheduling, or full HTTP/2 server feature set |
This repository participates in automated end-to-end acceptance runs driven by the CodeOn flow (review, revision, landing preflight, merge).
The full CodeOn acceptance flow expects the following environment variables when running against this repository:
| Name | Purpose | Example |
|---|---|---|
CODEON_DATABASE_URL |
Postgres URL of the CodeOn database | postgres://codeon:codeon@localhost/codeon |
CODEON_MCP_BEARER_TOKEN |
Bearer token for the CodeOn MCP HTTP API | secret-token |
GITHUB_TOKEN_FEWENSA |
GitHub credential used by the flow | ghp_... |
The complete acceptance loop reviews the pull request, requests or applies a revision when the reviewed candidate misses a sealed requirement, runs the landing preflight checks, merges the clean pull request, and closes the linked issue after landing is confirmed.
CODEON_DATABASE_URL=postgres://codeon:codeon@localhost/codeon \
CODEON_MCP_BEARER_TOKEN=secret-token \
GITHUB_TOKEN_FEWENSA=ghp_... \
codeon run --repo fewensa/rttp --pr 455 --flow full