Context
Headers.Builder and HttpHeaderName.fromString validate header names and values at the model layer: they reject blank names and control characters (the C0 range plus DEL), but deliberately permit non-ASCII (e.g. UTF-8) bytes. The stated rationale is a conservative, transport-agnostic contract — don't reject at the model layer something a transport might legitimately accept.
Problem
Both shipped reference transports reject non-ASCII header names and values:
- OkHttp restricts names to
0x21–0x7e and values to horizontal tab + 0x20–0x7e.
- JDK
java.net.http enforces its own field-name/value grammar (non-token / non-ASCII bytes rejected).
So today, a caller who sets a non-ASCII header name or value — explicitly allowed by the model — has it silently dropped from the wire on every reference transport (the adapters catch the transport's IllegalArgumentException and drop the offending header). The "some transports accept it" rationale currently has no in-tree example, so the model accepts input that no concrete path can actually send.
Decision needed
Pick a direction:
- Keep the permissive model contract for hypothetical future transports that accept non-ASCII, and document the gap clearly so callers understand non-ASCII names/values are accepted by the model but dropped by the current transports.
- Tighten the model layer to reject non-ASCII as well, giving callers a single fail-fast contract that matches what the transports can actually emit.
References
Introduced alongside the shared name/value validation and the drop-not-throw transport behavior in #140.
Context
Headers.BuilderandHttpHeaderName.fromStringvalidate header names and values at the model layer: they reject blank names and control characters (the C0 range plus DEL), but deliberately permit non-ASCII (e.g. UTF-8) bytes. The stated rationale is a conservative, transport-agnostic contract — don't reject at the model layer something a transport might legitimately accept.Problem
Both shipped reference transports reject non-ASCII header names and values:
0x21–0x7eand values to horizontal tab +0x20–0x7e.java.net.httpenforces its own field-name/value grammar (non-token / non-ASCII bytes rejected).So today, a caller who sets a non-ASCII header name or value — explicitly allowed by the model — has it silently dropped from the wire on every reference transport (the adapters catch the transport's
IllegalArgumentExceptionand drop the offending header). The "some transports accept it" rationale currently has no in-tree example, so the model accepts input that no concrete path can actually send.Decision needed
Pick a direction:
References
Introduced alongside the shared name/value validation and the drop-not-throw transport behavior in #140.