KoniKode · Software built with intention

KNOWLEDGE BASE

Documentation

DOCUMENTATION
CURRENT APPLICATIONClean Framework
DocumentationClean Framework

Clean Framework · DOCUMENTATION

HTTP request, upload, response, and emission boundaries

HTTP request, upload, response, and emission boundaries

Bounded candidate reference — 2026-10-20: 0.2.0-rc.1 is committed locally through 84f415b3098af5653577b2c65eea31fca21df79c, unpublished and not production-approved; stable PHP >=8.5.11 <8.6.0 is required. This is documentation, not adoption: this knowledge base retains its installed 0.1.0-rc.1 dependency and PHP 8.2.11 local profile. Dated PHP 8.2 evidence is historical; earlier dirty-source reports retain their original test provenance, not retroactive clean-commit proof. Candidate examples are illustrative: API signatures were reviewed, but candidate code was not executed by this editorial update. See current checkpoint, open criteria and adoption boundary.

Candidate delta: bounded header count/bytes/control/framing validation and safe malformed CSRF handling supplement these core APIs. See security threat model.

The HTTP layer keeps untrusted input raw and separates completed response values from SAPI emission. Controllers and middleware never call header(), set status codes, or echo response bytes directly.

Requests

Request can be built from explicit test data or once from globals in the front controller. It exposes original/effective method, URI/query string, application base path, normalized path, scheme, validated host/port, query, form, bounded JSON, raw body, line-aware case-insensitive headers, cookies, normalized uploads, selected server values, and immutable attributes.

Method override is accepted only for original POST requests and only for PUT, PATCH, or DELETE. JSON parsing requires application/json or a structured +json type and accepts an object/array rather than a scalar. RequestLimits bounds declared/actual body bytes, file count, individual upload size, and JSON depth before application logic consumes the data.

Framework attributes use framework.* constants in RequestAttribute; applications use app.*. Arbitrary unnamespaced keys are rejected. Matched route data is carried by immutable RouteContext, not flattened globals. originalPath() retains pre-canonical slash structure only for the router's explicit alias/redirect policy; handlers normally consume normalized path(). accepts() evaluates exact and wildcard media ranges with quality/specificity; acceptsJson() intentionally requires an explicit JSON media range so a wildcard client does not silently select JSON errors.

Trusted proxies

TrustedProxyPolicy accepts exact IP addresses or IPv4/IPv6 CIDRs during composition. X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host, and X-Forwarded-Port are ignored unless REMOTE_ADDR is trusted. Client address resolution walks the bounded forwarded chain from the immediate peer and returns the first untrusted origin address.

An empty trusted-proxy list is the safe default. Configure only addresses or networks actually controlled by the deployment. Never trust every address to make proxy headers appear to work.

Uploads

UploadedFile preserves client filename/media type only as bounded untrusted display metadata. Applications inspect bytes with detectedMediaType(), apply domain limits/scanning, and select any extension from inspected content. moveTo() generates a random server filename and requires private 0600 permissions; it never reuses the client path or filename.

Responses and emission

Response supports HTML, JSON, local or explicitly trusted-external redirects, no-content statuses, callback streams, contained files, downloads, ranges, and mutation-controlled header/cookie clones. send() may execute only once and delegates to ResponseEmitter; SapiResponseEmitter is the production adapter, while tests can inject an in-memory emitter. Same-origin redirects default to 303 for POST/Redirect/GET; 301, 302, 307, or 308 require an explicit status choice.

Streams and file bodies are emitted only at send time. Stream cleanup runs in finally; file handles close on completion, failure, or detected disconnect. HEAD routing removes both in-memory and streamed bodies while retaining GET headers.

Cookie validates names, values, path, domain, expiry, Max-Age, Secure, HttpOnly, and SameSite. SameSite=None requires Secure; __Secure- and __Host- prefix rules are enforced. Download filenames include an ASCII fallback and UTF-8 filename* value after CR/LF/path removal.

Authorization must occur before creating a private file response. A public asset response is not private-object authorization.

Editorial provenance

Source: docs/HTTP.md. Source SHA-256: 3c4f78961c28e0f578a3a2c17357fe0845539fa97d6637afa213c9ff7c4beea3.

Framework candidate reference; editorial checkpoint 2026-10-20. See candidate status and adoption boundary.

EXPLORE FURTHER

Drag a divider or use Left and Right Arrow keys to resize. Hold Shift for larger steps. Enter hides or restores the sidebar; Home and End select its minimum or maximum width. Double-click resets the width.

Install KoniKode