mod request_view
srcZero-copy HTTP request view.
RequestView[origin] borrows method, URL, headers, and body
from the connection's read_buf rather than owning them. For a
13-byte plaintext request the difference is invisible (a few
String allocations vs. a few offsets); for a 1MB / 16MB
multipart upload it's the difference between one memcpy of
the whole body and zero.
Pieces in place after this commit:
RequestView[origin]value type (this file).parse_request_view(data: Span[UInt8, origin]) raises -> RequestView[origin]parser that scans the request line + headers + body slice without per-header / per-token allocations.RequestView.into_owned() raises -> Requestmaterialises aRequestfor handlers that need to keep request state past one event-loop iteration.
Pieces that come later (deferred to S3 follow-up — explicit notes in the relevant commit bodies):
- A
ViewHandlertrait whoseserve_viewtakesRequestView[origin]directly. Today'sHandler.servesignature stays as-is; the reactor's read path can adopt a view-basedrun_reactor_loop_viewonce the trait surface lands. - Replacing
_parse_http_request_byteswith the view parser inside the cancel-aware reactor path. The view parser exists here as a standalone public function; the reactor will adopt it once the trait integration is settled.
This intentional split keeps the diff reviewable. The shape and
public API of RequestView are stable from this commit
forward; the integration step is purely "switch the reactor's
internal call site," which lands without breaking handlers.
Closes the type portion of Track 1.1; the integration portion moves to a follow-up alongside the reactor surgery.
Example:
var raw = "GET /a?q=1 HTTP/1.1
Host: x
".as_bytes()
var view = parse_request_view(Span[UInt8, _](raw))
print(view.method) # GET
print(view.url) # /a?q=1
print(view.headers.get("Host")) # x
print(len(view.body)) # 0
# Materialise an owned ``Request`` if you need one:
var owned = view.into_owned()
Functions
| fn parse_request_view | Parse an HTTP/1.1 request from a byte buffer into a ``RequestView`` borrowing into the buffer. |
Structs
| struct RequestView | Borrowed HTTP request. |
Functions
fn parse_request_view §
parse_request_view[origin: Origin[mut=origin.mut]](data: Span[UInt8, origin], max_header_size: Int = 8192, max_body_size: Int = 10485760, max_uri_length: Int = 8192, peer: SocketAddr = SocketAddr(IpAddr(String("127.0.0.1"), False), UInt16(0)), expose_errors: Bool = False) -> RequestView[origin]
Parse an HTTP/1.1 request from a byte buffer into a ``RequestView`` borrowing into the buffer.
Mirrors _parse_http_request_bytes in shape and validation
rules but produces a borrowed view: no per-header String
allocation, no body copy. The body slice points into data.
Parameters
| origin | Origin[mut=origin.mut] |
Args
| data | Span[UInt8, origin] |
Raw HTTP/1.1 request bytes (request line + headers + body, terminated or not). |
| max_header_size | Int |
Cap on header bytes; raises if exceeded. Default:8192
|
| max_body_size | Int |
Cap on body length; raises if Content-Length exceeds. Default:10485760
|
| max_uri_length | Int |
Cap on URI length; raises if exceeded. Default:8192
|
| peer | SocketAddr |
Kernel-reported peer address; threaded onto the view. Default:SocketAddr(IpAddr(String("127.0.0.1"), False), UInt16(0))
|
| expose_errors | Bool |
Whether 4xx response bodies may echo handler error messages. Default:False
|
Returns
| RequestView[origin] | A |
Raises
Error: On malformed request line (no spaces / wrong
number of components), URI exceeding the cap, headers
exceeding the cap, body exceeding the cap, or the
HeaderMapView parser rejecting a header line.
Structs
struct RequestView §
struct RequestView[origin: Origin[mut=origin.mut]]
Borrowed HTTP request.
Stores one Span[UInt8, origin] (the underlying buffer)
plus offset-and-length pairs for the URL, body, and the
individual headers. Per-field accessors (url(),
body(), header(name)) reconstruct the borrowed slice
on demand from the buffer. This avoids Mojo's borrow-checker
rejection of "two [origin]-tied fields aliasing the same
memory" that a flatter design (one StringSlice for URL +
one Span for body + one HeaderMapView for headers)
triggers.
Fields:
method: ASCII method token ("GET", "POST",
...). Owned String.
version: HTTP version ("HTTP/1.1"). Owned.
peer: Kernel-reported peer SocketAddr.
expose_errors: Whether 4xx response bodies may echo
handler-error messages.
buf: Underlying byte buffer borrowed from the
caller (typically ConnHandle.read_buf).
url_start / url_len: Byte range of the request URL
within buf.
body_start / body_len: Byte range of the request body
within buf.
header_offsets: Flat List[Int] of stride 4
(name_start, name_len, value_start,
value_len) — the same shape
HeaderMapView uses internally.
Fields
| method | String | |
| version | String | |
| peer | SocketAddr | |
| expose_errors | Bool | |
| buf | Span[UInt8, origin] | |
| url_start | Int | |
| url_len | Int | |
| body_start | Int | |
| body_len | Int | |
| header_offsets | List[Int] |
Methods
| fn __init__ | |
| fn url | Borrowed URL slice. |
| fn body | Borrowed body slice. |
| fn headers | Build a ``HeaderMapView`` over this view's headers. |
| fn into_owned | Materialise a ``Request`` whose fields are owned copies of the borrowed bytes. |
fn __init__ static §
__init__(out self, method: String, version: String, peer: SocketAddr, expose_errors: Bool, buf: Span[UInt8, origin], url_start: Int, url_len: Int, body_start: Int, body_len: Int, var header_offsets: List[Int])
Args
| method | String | |
| version | String | |
| peer | SocketAddr | |
| expose_errors | Bool | |
| buf | Span[UInt8, origin] | |
| url_start | Int | |
| url_len | Int | |
| body_start | Int | |
| body_len | Int | |
| header_offsets var | List[Int] | |
| self out | Self |
Returns
| Self |
fn url §
url(self) -> StringSlice[origin]
Borrowed URL slice.
Args
| self | Self |
Returns
| StringSlice[origin] |
fn headers §
headers(self) -> HeaderMapView[origin]
Build a ``HeaderMapView`` over this view's headers.
Cheap: copies the offsets list (typically a few ints) and
re-binds the buffer span. The returned view shares the
same origin.
Args
| self | Self |
Returns
| HeaderMapView[origin] |
fn into_owned §
into_owned(self) -> Request
Materialise a ``Request`` whose fields are owned copies of the borrowed bytes.
Use when a handler needs to keep request state past one
event-loop iteration (background work, audit logging,
cross-request bookkeeping). Allocates: one String for
the URL, one HeaderMap worth of headers, one
List[UInt8] for the body.
Args
| self | Self |
Returns
| Request |
Raises
May raise an exception.