logos.std.io.http

Module std · package logos-std

Traits

traitService

trait Service

Turns a Request into a Response; implement to plug a handler into the conn loop.

Implemented by: FnService

Types

structChunkedReader

struct ChunkedReader

Decodes a chunked-encoded Read source, exposing the body as a plain Read.

Implements: Read

Fields

reader: R
remaining: i64
state: i32

structChunkedWriter

struct ChunkedWriter

Frames each write call to the wrapped Write sink as one chunked-encoded record. Call finish to emit the terminator; dropping without it leaves the stream malformed. For chatty producers, wrap the sink in a BufWriter first to coalesce small chunks.

Implements: Write

Fields

finished: bool
writer: W

structConnTask

struct ConnTask

Packs a connection fd + type-erased service pointer for handoff to a worker. Heap-allocated by the acceptor, freed by the worker fiber after it is consumed.

Fields

fd: i32

Raw fd of the accepted connection.

pad: i32

Alignment padding; unused.

svc: i64

Type-erased *mut FnService (as i64) shared with the worker thread.

structContentLengthReader

struct ContentLengthReader

Caps reads from a Read source at a fixed byte budget; frames a Content-Length: N body. Returns 0 (EOF) once the budget is exhausted; never reads past it on the underlying reader.

Implements: Read

Fields

reader: R
remaining: i64

structFnService

struct FnService

Service adapter wrapping a plain fn(&Request) -> Response handler.

Implements: Service

Fields

f: fn(&Request) -> Response

Methods

fn call(self: &mut FnService, req: &Request) -> Response

structHeaders

struct Headers

Ordered list of HTTP header (name, value) pairs; duplicates allowed. Name lookup is ASCII case-insensitive (RFC 7230 §3.2).

Fields

buf: String

Backing storage: every name and value back-to-back, NUL-separated.

entries: Vec<Header>

Per-header offset/length quads indexing into buf.

Methods

fn append(self: &mut Headers, name: &[u8], value: &[u8]) -> void

Appends a (name, value) pair unconditionally (preserves duplicates).

fn contains(self: &Headers, name: &[u8]) -> bool

Returns true if any header matches name (ASCII case-insensitive).

fn get(self: &Headers, name: &[u8]) -> Option

Returns the value of the first header matching name, or None.

fn len(self: &Headers) -> i64

Returns the number of header entries.

fn new() -> Headers

Creates an empty header list.

fn remove(self: &mut Headers, name: &[u8]) -> i64

Removes all headers matching name; returns the number removed.

fn set(self: &mut Headers, name: &[u8], value: &[u8]) -> void

Replaces the first header matching name with value, or appends if none matches. Later duplicates of name are left in place.

enumHttpError

enum HttpError

Errors produced by HTTP client and server operations.

Variants

BadStatus(i32)
BadUrl
Connect
Io
Parse

structMethod

struct Method

HTTP request method: a small integer code plus the literal token.

Fields

code: i32

Method code; known methods use 0–6, unknown/extension methods share 7.

name: String

Method token verbatim (e.g. "GET").

Methods

fn delete() -> Method

Returns the DELETE method.

fn eq_str(self: &Method, s: &[u8]) -> bool

Returns true if the method token equals s exactly (case-sensitive).

fn get() -> Method

Returns the GET method.

fn head() -> Method

Returns the HEAD method.

fn options() -> Method

Returns the OPTIONS method.

fn patch() -> Method

Returns the PATCH method.

fn post() -> Method

Returns the POST method.

fn put() -> Method

Returns the PUT method.

structRequest

struct Request

HTTP request: method, target URL, headers, and body.

Fields

body: Vec<u8>

Request body bytes.

headers: Headers

Request headers.

method: Method

Request method.

url: Url

Target URL.

version_minor: i32

HTTP version minor digit from the request line: 0 for HTTP/1.0, 1 for HTTP/1.1. Major is always 1 (higher majors are rejected by the parser).

Methods

fn new(method: Method, u: Url) -> Request

Creates a request with empty headers and body; version_minor defaults to 1.

structResponse

struct Response

HTTP response: status code, reason phrase, headers, and body.

Fields

body: Vec<u8>

Response body bytes.

headers: Headers

Response headers.

reason: String

Reason phrase for the status line.

status: i32

Status code (e.g. 200).

Methods

fn new(status: i32) -> Response

Creates a response with the canonical reason phrase for status, empty headers and body.

Functions

fnascii_ieq

fn ascii_ieq(a: *const u8, an: i64, b: *const u8, bn: i64) -> bool

Compares two byte ranges case-insensitively (ASCII only).

fnbody_length

fn body_length(h: &Headers) -> i64

Returns the body-framing decision for headers h. >= 0: Content-Length bytes; -1: no framing (caller decides; response → read to EOF, request → empty); -2: chunked; -3: malformed (invalid or conflicting Content-Length, non-chunked Transfer-Encoding, or TE with CL).

fnbytes_eq

fn bytes_eq(a: *const u8, an: i64, b: *const u8, bn: i64) -> bool

Compares two byte ranges exactly (ASCII, case-sensitive).

fnchunked_decode

fn chunked_decode(src: *const u8, len: i64, out: &mut Vec<u8>) -> i64

Decodes chunked bytes [src, src+len), appending body data to out. Returns total input bytes consumed (through the final trailer CRLF), or -1 on malformed input. Trailer headers are parsed and skipped.

fnchunked_encode

fn chunked_encode(data: *const u8, n: i64, out: &mut Vec<u8>) -> void

Encodes a whole body as one chunk plus the zero-length terminator, appended to out. For streaming, call chunked_write_chunk repeatedly, then chunked_finalize.

fnchunked_finalize

fn chunked_finalize(out: &mut Vec<u8>) -> void

Appends the chunked-stream terminator (0\r\n\r\n) to out.

fnchunked_reader_wrap

fn chunked_reader_wrap(r: R) -> ChunkedReader<R>

Wraps r in a ChunkedReader, taking ownership. To keep the underlying reader available afterwards, use read_chunked_body instead.

fnchunked_write_chunk

fn chunked_write_chunk(data: *const u8, n: i64, out: &mut Vec<u8>) -> void

Appends one chunk (hex-length + CRLF + data + CRLF) to out. n == 0 emits bytes identical to the stream terminator; use chunked_finalize for that.

fnchunked_writer_wrap

fn chunked_writer_wrap(w: W) -> ChunkedWriter<W>

Wraps w in a ChunkedWriter, taking ownership of the sink.

fncontent_length_reader_wrap

fn content_length_reader_wrap(r: R, n: i64) -> ContentLengthReader<R>

Wraps r in a ContentLengthReader capped at n bytes; negative n is clamped to 0.

fnfind_crlf

fn find_crlf(src: *const u8, len: i64, from: i64) -> i64

Returns the index of the first CRLF’s CR in [from, len), or -1 if absent.

fnfn_service

fn fn_service(f: fn(&Request) -> Response) -> FnService

Wraps f in a FnService so a fn-pointer handler can be used as a Service.

fnhttp_get

fn http_get(url_str: &[u8]) -> Result

Parses url_str as an absolute HTTP URL (http://host[:port]/path[?query]) and issues a GET. Only numeric IPv4 hosts are supported; a hostname or a non-http scheme yields HttpError::BadUrl.

fnhttp_get_at

fn http_get_at(host_ip: u32, port: u16, host_hdr: &[u8], path: &[u8]) -> Result

Issues a GET for path against host_ip:port, building a minimal Request with a Host header set to host_hdr.

fnhttp_reason_phrase

fn http_reason_phrase(status: i32) -> &[u8]

Returns the standard reason phrase for status; unknown codes yield "".

fnhttp_send

fn http_send(host_ip: u32, port: u16, req: &Request) -> Result

Sends req to host_ip:port over a fresh TCP connection and reads the response. Reads until the peer closes or a complete message is buffered. host_ip must be numeric IPv4 — DNS resolution is not implemented.

fnmethod_parse

fn method_parse(s: &[u8]) -> Method

Parses a method token (ASCII, case-sensitive per RFC 7230). Unknown tokens return code == 7 with the original name preserved.

fnparse_headers

fn parse_headers(src: *const u8, len: i64, pos: i64, h: &mut Headers) -> i64

Parses header lines from [pos, len) into h, appending each field. Returns the position just past the empty-CRLF terminator, or -1 on malformed input. Names must be RFC 7230 tokens; values are OWS-trimmed.

fnparse_request_buf

fn parse_request_buf(src: *const u8, len: i64) -> Result

Parses a complete HTTP request (request-line, headers, body) from [src, src+len). Body framing follows body_length: Content-Length is copied, chunked is decoded, no framing yields an empty body. Partial input is HttpError::Parse — the buffer must hold the whole message.

fnparse_request_stream

fn parse_request_stream(br: &mut BufReader<R>) -> Result

Reads and parses a request head (request-line + headers) from br; no body is read. Leaves br at the first body byte; the returned Request.body is empty — frame it via body_length(&req.headers). Stricter than parse_request_buf: requires HTTP/1.0|1.1, origin-/asterisk-form target, Host on 1.1, and no Transfer-Encoding on 1.0.

fnparse_response_buf

fn parse_response_buf(src: *const u8, len: i64) -> Result

Parses a complete HTTP response (status-line, headers, body) from [src, src+len). Body framing follows body_length: with no framing, the remainder of the buffer becomes the body (read-to-EOF semantics).

fnparse_response_stream

fn parse_response_stream(br: &mut BufReader<R>) -> Result

Reads and parses a response head (status-line + headers) from br; no body is read. Leaves br at the first body byte; the returned Response.body is empty — frame it via body_length(&resp.headers).

fnread_chunked_body

fn read_chunked_body(r: &mut R, out: &mut Vec<u8>) -> i64

Reads a full chunked-encoded body from r, appending decoded bytes to out. Returns bytes appended on success, -1 on malformed input / I/O error. Borrows r (unlike ChunkedReader), so e.g. an HTTP server can read the next request from the same BufReader afterwards.

fnread_request_message

fn read_request_message(s: &TcpStream, buf: &mut Vec<u8>) -> Result

Drains a full HTTP/1.1 request message from s into buf. Reads until headers are complete AND the entire Content-Length body (or chunked terminator) has arrived, or the peer closes. Returns Ok(bytes_in_buf) or Err on IO / framing failure.

fns2str

fn s2str(s: &String) -> &[u8]

Borrows a String’s contents as a str (no copy).

fnserialize_request

fn serialize_request(req: &Request, out: &mut Vec<u8>) -> void

Appends the full HTTP/1.1 request — request-line, headers, CRLF, body — to out. Wire form: METHOD /path?query HTTP/1.1\r\n<headers>\r\n<body>; empty path serializes as /, ?query only when non-empty. Headers are written as stored; no Content-Length is synthesized.

fnserialize_request_head_stream

fn serialize_request_head_stream(req: &Request, w: &mut W) -> i64

Writes only the request head — request-line, headers, terminator CRLF — to w. Request counterpart of serialize_response_head_stream; the caller writes the body afterwards. Returns 0 on success, negative errno on error.

fnserialize_request_stream

fn serialize_request_stream(req: &Request, w: &mut W) -> i64

Serializes the full request into one buffer and writes it to w via a single write_all. Returns 0 on success, negative errno on error.

fnserialize_response

fn serialize_response(resp: &Response, out: &mut Vec<u8>) -> void

Appends the full HTTP/1.1 response — status-line, headers, CRLF, body — to out. Wire form: HTTP/1.1 <status> <reason>\r\n<headers>\r\n<body>; headers are written as stored.

fnserialize_response_head_stream

fn serialize_response_head_stream(resp: &Response, w: &mut W) -> i64

Writes only the response head — status-line, headers, terminator CRLF — to w. Use when the body is large or framed by a different encoder (ChunkedWriter, an open file, ...); the caller writes the body afterwards through the same writer. Returns 0 on success, negative errno on error.

fnserialize_response_stream

fn serialize_response_stream(resp: &Response, w: &mut W) -> i64

Serializes the full response into one buffer and writes it to w via a single write_all. Returns 0 on success, negative errno on error.

fnserve_bounded

fn serve_bounded(port: u16, count: i64, svc: &mut S) -> Result

Accepts up to count connections serially, running each through serve_connection (keep-alive works per connection). Returns Ok(()) after count connections have been served or accept fails; Err(Connect) if bind fails. For tests and “single request batch” scenarios.

fnserve_connection

fn serve_connection(stream: TcpStream, svc: &mut S) -> i64

Serves HTTP/1.1 requests from stream through svc in a keep-alive loop. Handles Expect: 100-continue; drains Content-Length bodies and decodes chunked bodies into req.body. Closes on Connection: close from either side or on a framing/IO error (malformed requests get a 400 reply first). Always returns 0.

fnserve_mt

fn serve_mt(port: u16, n_workers: i32, svc: &mut FnService, stop_flag: *mut i64) -> Result

Runs a multi-worker server: accepts on the calling thread’s reactor and hands each connection round-robin to one of n_workers worker threads via serve_connection. Stops when *stop_flag != 0 or accept fails; Err(Connect) if bind fails or n_workers < 1. Safety: svc is shared by raw pointer across workers — safe only for stateless services (e.g. FnService); stateful services need their own sync.

fnserve_mt_bounded

fn serve_mt_bounded(port: u16, n_workers: i32, count: i64, svc: &mut FnService) -> *mut ThreadPool

Accepts exactly count connections, handing each round-robin to n_workers workers, then signals shutdown and returns the pool without joining it. Caller must thread_pool_join + thread_pool_free only after its own reactor has drained — joining inside the fiber would block the OS thread and deadlock peers.

fnserve_n

fn serve_n(port: u16, count: i64, handler: fn(&Request) -> Response) -> Result

Binds port, accepts count connections serially, invokes handler for each, writes the serialized response back, and closes — one request per connection. Returns Ok(()) once count connections have been served, or Err(Connect) on fatal bind/accept failure.

fnserve_until

fn serve_until(port: u16, svc: &mut S, stop_flag: *mut i64) -> Result

Accepts connections until *stop_flag != 0, serving each through serve_connection. The stop flag must be an i64 cell the caller mutates from another fiber / signal handler — checked between accepts; accept failure also stops. Returns Ok(()) on clean stop or Err(Connect) if bind fails.

fnvec_at_const_u8

fn vec_at_const_u8(v: &Vec<u8>, i: i64) -> *const u8

Returns a raw const pointer to the byte at index i of v.

fnvec_get_u8

fn vec_get_u8(v: &Vec<u8>, i: i64) -> u8

Returns the byte at index i of v.

fnvec_len_u8

fn vec_len_u8(v: &Vec<u8>) -> i64

Returns the number of bytes in v.

fnvec_push_u8

fn vec_push_u8(v: &mut Vec<u8>, b: u8) -> void

Pushes byte b onto v.

fnwrite_i64_decimal

fn write_i64_decimal(v: i64, out: &mut Vec<u8>) -> void

Appends the decimal ASCII representation of v to out. Supports non-negative values only; v < 0 appends nothing.