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:
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:
- 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.
The shape and public API of RequestView are stable; the
integration step is purely "switch the reactor's internal call
site," which lands without breaking handlers. The integration
portion is 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 §
def 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 §
def __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 §
def url(self) -> StringSlice[origin]
Borrowed URL slice.
Args
| self | Self |
Returns
| StringSlice[origin] |
fn headers §
def 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 §
def 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.