Sign in

    http

    Sans-IO HTTP vocabulary for MoonBit SDKs: request/response types, a Transport trait, an incremental SSE parser and a scripted fake transport. No dependencies; runs on every backend.

    http
    sans-io
    transport
    sse
    client
    Download zip
    Author
    Version
    0.2.1
    License
    Apache-2.0
    Last updated
    5 days ago
    Downloads
    1K

    No dependencies

    #gaato/http

    Sans-IO HTTP vocabulary for MoonBit SDKs: Request, Response, Headers, the Transport and BodyStream traits, middleware, a Clock trait (gaato/http/clock), an incremental WHATWG-conformant SSE parser (gaato/http/sse), and a scripted FakeTransport / FakeClock for tests (gaato/http/mock). No dependencies; runs on wasm-gc, wasm, js and native.

    The SSE parser bounds one event at max_event_bytes (16 MiB by default): the raw bytes of its data lines, of the event and id lines in effect (the id persists into later events, so it counts against each of them until replaced), and of the line being read. A stream that never ends a line, or never sends the blank line that ends an event, fails with HttpError::Protocol instead of growing memory without bound. Events completed before the oversized one are still delivered: when they arrive in the same chunk, SseParser::feed returns them and the next feed (an empty chunk is enough) or finish raises; each_event dispatches them and then raises without reading further. Pass max_event_bytes to SseParser::new or each_event to change it.

    An SDK built on this module never imports an async runtime: the caller passes a Transport and a Clock, for example from gaato/http-async.

    Unofficial and experimental. Source, issues and design notes: https://github.com/gaato/mbt-sdk

    Middleware

    type Middleware = async (Request, async (Request) -> Response raise HttpError) -> Response raise HttpError

    An async request wrapper receiving the next operation in the chain.

    BodyStream

    pub(open) trait BodyStream {
    async fn read_some(Self) -> Bytes? raise HttpError
    fn close(Self) -> Unit
    }

    A readable response body. None signals end of stream.

    Transport

    pub(open) trait Transport {
    async fn send(Self, Request) -> Response raise HttpError
    async fn send_stream(Self, Request) -> (ResponseHead, &BodyStream) raise HttpError
    }

    Sends requests without interpreting HTTP status codes as errors.

    HttpError

    pub(all) suberror HttpError {
    Connect(String)
    Timeout(Int)
    Protocol(String)
    } derive(
    Debug
    )

    Transport failures, separate from ordinary HTTP response statuses.

    HttpError::to_repr

    Debug representation of a transport failure.

    Headers

    pub struct Headers {
    // private fields
    } derive(Eq,
    Debug
    )

    Mutable, ordered header pairs with ASCII lowercase names. Equality compares normalized pairs, including their order.

    test {
    let headers = @http.Headers::from_array([("Accept", "text/plain")])
    assert_eq(headers.get("ACCEPT"), Some("text/plain"))
    }

    Headers::append

    fn Headers::append(self : Headers, name : String, value : String) -> Unit

    Appends one pair, retaining all existing values.

    Headers::contains

    fn Headers::contains(self : Headers, name : String) -> Bool

    Reports whether at least one value exists for a name.

    Headers::each

    fn Headers::each(self : Headers, f : (String, String) -> Unit raise?) -> Unit raise?

    Visits a snapshot of normalized pairs in insertion order.

    Headers::equal

    fn Headers::equal(Headers, Headers) -> Bool

    Explicit equality methods for normalized, ordered pairs.

    Headers::from_array

    fn Headers::from_array(pairs : Array[(String, String)]) -> Headers

    Copies pairs in their original order and normalizes their names.

    Headers::get

    fn Headers::get(self : Headers, name : String) -> String?

    Returns the first value for a name, ignoring ASCII case.

    Headers::get_all

    fn Headers::get_all(self : Headers, name : String) -> Array[String]

    Returns a fresh array containing every matching value in insertion order.

    Headers::iter

    fn Headers::iter(self : Headers) -> Iter[(String, String)]

    Iterates over a snapshot of normalized pairs in insertion order.

    Headers::length

    fn Headers::length(self : Headers) -> Int

    Returns the number of pairs, counting repeated names separately.

    Headers::new

    fn Headers::new() -> Headers

    Creates an empty header collection.

    Headers::not_equal

    fn Headers::not_equal(x : Headers, y : Headers) -> Bool

    Explicit equality methods for normalized, ordered pairs.

    Headers::remove

    fn Headers::remove(self : Headers, name : String) -> Unit

    Removes all pairs for a name, ignoring ASCII case.

    Headers::set

    fn Headers::set(self : Headers, name : String, value : String) -> Unit

    Replaces all values for a name at its first position, or appends a new name.

    Headers::to_repr

    Debug representation of the header pairs.

    Request

    pub(all) struct Request {
    http_method : String
    url : String
    headers : Headers
    body : Bytes
    } derive(Eq,
    Debug
    )

    An HTTP request with a byte body. Builders copy headers before returning.

    test {
    let request = @http.Request::post("/items")
    .header("Accept", "application/json")
    .body_text("hello")
    assert_eq(request.body, b"hello")
    }

    Request::body_bytes

    fn Request::body_bytes(self : Request, body : Bytes) -> Request

    Returns a new request with the supplied bytes and independent headers.

    Request::body_text

    fn Request::body_text(self : Request, body : String) -> Request

    Returns a new request whose body is the UTF-8 encoding of the text.

    Request::delete

    fn Request::delete(url : String) -> Request

    Creates a DELETE request.

    Request::equal

    fn Request::equal(Request, Request) -> Bool

    Compares all request fields.

    Request::get

    fn Request::get(url : String) -> Request

    Creates a GET request.

    Request::header

    fn Request::header(self : Request, name : String, value : String) -> Request

    Returns a new request with an appended header and independent headers.

    Request::json_body

    fn Request::json_body(self : Request, body : Json) -> Request

    Encodes JSON as UTF-8 and supplies application/json only if content-type is absent.

    Request::new

    fn Request::new(http_method : String, url : String) -> Request

    Creates a request with the supplied method, empty headers and an empty body.

    Request::not_equal

    fn Request::not_equal(x : Request, y : Request) -> Bool

    Compares all request fields.

    Request::patch

    fn Request::patch(url : String) -> Request

    Creates a PATCH request.

    Request::post

    fn Request::post(url : String) -> Request

    Creates a POST request.

    Request::put

    fn Request::put(url : String) -> Request

    Creates a PUT request.

    Request::to_repr

    Debug representation of a request.

    Response

    pub(all) struct Response {
    status : Int
    headers : Headers
    body : Bytes
    } derive(Eq,
    Debug
    )

    An HTTP response. Error status codes are ordinary responses.

    test {
    let response : @http.Response = {
    status: 200,
    headers: @http.Headers::new(),
    body: b"hello",
    }
    assert_eq(response.text(), "hello")
    assert_true(response.is_success())
    }

    Response::equal

    fn Response::equal(Response, Response) -> Bool

    Compares all response fields.

    Response::is_success

    fn Response::is_success(self : Response) -> Bool

    Reports whether the status is in the inclusive range 200 through 299.

    Response::json

    fn Response::json(self : Response) -> Json raise

    Parses the strictly decoded body, raising on malformed UTF-8 or invalid JSON.

    Response::not_equal

    fn Response::not_equal(x : Response, y : Response) -> Bool

    Compares all response fields.

    Response::text

    Strictly decodes the UTF-8 body, raising on malformed input.

    Response::to_repr

    Debug representation of a response.

    ResponseHead

    pub(all) struct ResponseHead {
    status : Int
    headers : Headers
    } derive(Eq,
    Debug
    )

    Status and headers available before consuming a streamed body.

    ResponseHead::equal

    Compares status and headers.

    ResponseHead::not_equal

    fn ResponseHead::not_equal(x : ResponseHead, y : ResponseHead) -> Bool

    Compares status and headers.

    ResponseHead::to_repr

    Debug representation of a response head.

    append_query

    fn append_query(url : String, name : String, value : String) -> String

    Appends an encoded query pair, using ampersand if the URL contains ?.

    percent_encode

    fn percent_encode(value : String) -> String

    Percent-encodes UTF-8 bytes, preserving only RFC 3986 unreserved bytes.

    percent_encode_path

    fn percent_encode_path(value : String) -> String

    Percent-encodes a multi-segment path, also preserving slash separators.

    send_with

    async fn send_with(transport : &Transport, middleware : Array[async (Request, async (Request) -> Response raise HttpError) -> Response raise HttpError], request : Request) -> Response raise HttpError

    Sends through middleware in array order, with the first element outermost.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io