v2026.8.3
All Bundles
Bundle Shared networking types used across all HTTP libraries: Url (parsing and construction), Response (status code, headers, body), Cookie, and WebDownloader for streaming downloads. Compile with -lib net.

HeaderCheck

Validates an HTTP request header name/value pair. Header content reaches the wire verbatim: HTTP/1.1 and HTTPS serialize the whole request as text here in Objeck ("name: value" + CRLF), so a CR or LF in a value ends the field and starts a new one -- request splitting, not a parse error. HTTP/2 and HTTP/3 hand off to native code that performs no validation of its own on submit. Octets per RFC 9110 5.1/5.5, tightened by RFC 9113 8.2.1. Rejects CR, LF, NUL, DEL and every other C0 control (SP and HTAB are legal), leading or trailing whitespace, an empty name, and any name beginning with ':' -- HTTP/2 and HTTP/3 build the pseudo-headers themselves and a duplicate is malformed (RFC 9114 4.3.1), the classic request-smuggling primitive.

Operations

Flatten # function

Flattens request headers into a String[] of alternating key/value, the shape the HTTP/2 and HTTP/3 traps consume. Lives here rather than in each client because both need it, and because lang.obs -- which declares the trap-facing method -- compiles with -strict and no libraries, so it cannot name Hash at all. Invalid pairs are dropped rather than emitted, and the array is sized to the surviving pairs so there are no trailing Nil holes: the native walker reads exactly Size() elements and must never meet one. AddHeader already refuses these, so this is defence in depth against any other insertion path. The result length is therefore always even.

function : Flatten(headers:Hash<String,String>) ~ String[]

Parameters

NameTypeDescription
headersHash<String,String>header map, may be Nil

Return

TypeDescription
Stringalternating key/value array, never Nil

IsValidName # function

Validates an HTTP header name. Accepts the RFC 9110 5.1 token characters, lower-case only -- callers pass name->ToLower(), because HTTP/2 and HTTP/3 require lower-case field names (RFC 9113 8.2.1) and an upper-case letter here is malformed. A name beginning with ':' is refused: HTTP/2 and HTTP/3 build the pseudo-headers themselves, and a caller-supplied duplicate is the classic request-smuggling primitive (RFC 9114 4.3.1).

function : IsValidName(n:String) ~ Bool

Parameters

NameTypeDescription
nStringheader name, may be Nil

Return

TypeDescription
Booltrue when safe to serialize as a field name

IsValidRequestTarget # function

Validates a request target (path) or authority (host) for the HTTP/1.1 request line. These are appended verbatim into the request line, so a CR, LF or space splits the request itself -- a strictly worse version of header injection, and reachable from a Url, which is the input most likely to come from untrusted data. Url->New does not sanitize. Rejects every control character (RFC 9110 forbids CTL in a request target) plus space, which would terminate the target early.

function : IsValidRequestTarget(s:String) ~ Bool

Parameters

NameTypeDescription
sStringpath or host

Return

TypeDescription
Booltrue when safe to place in a request line

IsValidValue # function

Validates an HTTP header value. Rejects DEL and every C0 control except HTAB -- so CR, LF and NUL are refused, which is the request-splitting primitive: a CR or LF in a value ends the field and starts a new one. SP and HTAB are legal per RFC 9110 5.5, but not leading or trailing, since a recipient strips them and two values differing only in surrounding whitespace would compare equal.

function : IsValidValue(v:String) ~ Bool

Parameters

NameTypeDescription
vStringheader value, may be Nil

Return

TypeDescription
Booltrue when safe to serialize into a header field