Sign in

    moonbitstack/moonapi/status does not have a README file

    One cookie, as Set-Cookie states it.

    An attribute left None is left out of the header, and means what leaving it out means: no Expires and no Max-Age is a session cookie, no Domain is the origin host alone, no Path is the request's own directory.

    Event

    One event on the wire.

    A field left None is left out of the frame. data carrying newlines goes out as several data: lines and comes back joined, which is the format's own rule and the reason a payload with a blank line in it cannot be sent as one.

    SameSite

    How far a cross-site request may carry a cookie.

    Strict sends it only on a same-site request, Lax also on a top-level navigation, and Unrestricted sends it everywhere. Unrestricted is the wire value None, spelled differently here because None is the empty option; a browser honours it only on a Secure cookie.

    Events

    pub struct Events {
    // private fields
    }

    The event side of a text/event-stream: each send is one frame, written as its own chunk.

    Events::ping

    async fn Events::ping(self : Events, comment? : String) -> Unit

    Send a comment line, which a client ignores and an idle proxy takes as traffic.

    Events::send

    async fn Events::send(self : Events, event :
    Event
    ) -> Unit

    Send event as one frame. A client dispatches it when it reads the frame's blank line, so it goes out on its own rather than waiting for the next.

    Stream

    pub(all) struct Stream {
    status : Int
    headers : Array[(String, String)]
    body : async (Writer) -> Unit
    early_hints : Array[Array[String]]
    trailers : Bool
    }

    A response whose body is written while it is sent (← Starlette's StreamingResponse): the head goes out first, then whatever body writes, a chunk per write. The app runs body beside a watch on the connection and cancels it when the client goes, so an endless stream ends with its reader.

    early_hints go out as 103 responses before the head (RFC 8297). trailers announces trailing fields, which body sets with [Writer::trailer] and the app sends after the last chunk.

    Stream::new

    fn Stream::new(body : async (Writer) -> Unit, status? : Int, headers? : Array[(String, String)], early_hints? : Array[Array[String]], trailers? : Bool) -> Stream

    Writer

    pub struct Writer {
    // private fields
    }

    Where a stream's body goes. The app makes one per response; a test or another driver makes one over its own sink.

    Writer::new

    fn Writer::new(sink : async (Bytes) -> Unit) -> Writer

    Writer::trailer

    fn Writer::trailer(self : Writer, name : String, value : String) -> Unit

    Add a trailing field, sent after the body when the stream announced trailers.

    Writer::trailers

    fn Writer::trailers(self : Writer) -> Array[(String, String)]

    The trailing fields set so far.

    Writer::write

    async fn Writer::write(self : Writer, chunk : Bytes) -> Unit

    Send chunk as one piece of the body. An empty chunk is not sent: it would say nothing.

    Writer::write_text

    async fn Writer::write_text(self : Writer, text : String) -> Unit

    Send text as UTF-8.

    HTTP_100_CONTINUE

    let HTTP_100_CONTINUE : Int

    Continue: the headers are acceptable, send the body.

    HTTP_101_SWITCHING_PROTOCOLS

    let HTTP_101_SWITCHING_PROTOCOLS : Int

    Switching Protocols: the server is changing to the protocol Upgrade asked for.

    HTTP_102_PROCESSING

    let HTTP_102_PROCESSING : Int

    Processing: WebDAV, the request is under way and the reply will follow.

    HTTP_103_EARLY_HINTS

    let HTTP_103_EARLY_HINTS : Int

    Early Hints: preload links sent ahead of the real response.

    HTTP_200_OK

    let HTTP_200_OK : Int

    OK.

    HTTP_201_CREATED

    let HTTP_201_CREATED : Int

    Created: the request made a new resource, named in Location.

    HTTP_202_ACCEPTED

    let HTTP_202_ACCEPTED : Int

    Accepted: taken for processing, outcome not yet known.

    HTTP_203_NON_AUTHORITATIVE_INFORMATION

    let HTTP_203_NON_AUTHORITATIVE_INFORMATION : Int

    Non-Authoritative Information: an intermediary altered the origin's payload.

    HTTP_204_NO_CONTENT

    let HTTP_204_NO_CONTENT : Int

    No Content: succeeded, and there is nothing to send back.

    HTTP_205_RESET_CONTENT

    let HTTP_205_RESET_CONTENT : Int

    Reset Content: succeeded; the client should clear the form that sent it.

    HTTP_206_PARTIAL_CONTENT

    let HTTP_206_PARTIAL_CONTENT : Int

    Partial Content: the byte ranges Range asked for.

    HTTP_207_MULTI_STATUS

    let HTTP_207_MULTI_STATUS : Int

    Multi-Status: WebDAV, one status per member of a collection.

    HTTP_208_ALREADY_REPORTED

    let HTTP_208_ALREADY_REPORTED : Int

    Already Reported: WebDAV, this member was enumerated earlier in the reply.

    HTTP_226_IM_USED

    let HTTP_226_IM_USED : Int

    IM Used: the body is the result of applying delta encodings.

    HTTP_300_MULTIPLE_CHOICES

    let HTTP_300_MULTIPLE_CHOICES : Int

    Multiple Choices: several representations, pick one.

    HTTP_301_MOVED_PERMANENTLY

    let HTTP_301_MOVED_PERMANENTLY : Int

    Moved Permanently: use Location from now on.

    HTTP_302_FOUND

    let HTTP_302_FOUND : Int

    Found: a temporary move. Clients rewrite POST to GET here, which is why 307 exists.

    HTTP_303_SEE_OTHER

    let HTTP_303_SEE_OTHER : Int

    See Other: fetch the outcome with a GET at Location — the redirect after a form post.

    HTTP_304_NOT_MODIFIED

    let HTTP_304_NOT_MODIFIED : Int

    Not Modified: the client's cached copy is still current.

    HTTP_305_USE_PROXY

    let HTTP_305_USE_PROXY : Int

    Use Proxy: deprecated by RFC 9110.

    HTTP_306_RESERVED

    let HTTP_306_RESERVED : Int

    Reserved: never standardised, and reserved so nothing else claims it.

    HTTP_307_TEMPORARY_REDIRECT

    let HTTP_307_TEMPORARY_REDIRECT : Int

    Temporary Redirect: like 302, but the method and body must be kept.

    HTTP_308_PERMANENT_REDIRECT

    let HTTP_308_PERMANENT_REDIRECT : Int

    Permanent Redirect: like 301, but the method and body must be kept.

    HTTP_400_BAD_REQUEST

    let HTTP_400_BAD_REQUEST : Int

    Bad Request: malformed enough that the server will not act on it.

    HTTP_401_UNAUTHORIZED

    let HTTP_401_UNAUTHORIZED : Int

    Unauthorized: not authenticated. The reply must carry WWW-Authenticate.

    HTTP_402_PAYMENT_REQUIRED

    let HTTP_402_PAYMENT_REQUIRED : Int

    Payment Required: reserved.

    HTTP_403_FORBIDDEN

    let HTTP_403_FORBIDDEN : Int

    Forbidden: authenticated, and still not allowed.

    HTTP_404_NOT_FOUND

    let HTTP_404_NOT_FOUND : Int

    Not Found.

    HTTP_405_METHOD_NOT_ALLOWED

    let HTTP_405_METHOD_NOT_ALLOWED : Int

    Method Not Allowed: the path exists under another verb, listed in Allow.

    HTTP_406_NOT_ACCEPTABLE

    let HTTP_406_NOT_ACCEPTABLE : Int

    Not Acceptable: nothing on offer matches the request's Accept.

    HTTP_407_PROXY_AUTHENTICATION_REQUIRED

    let HTTP_407_PROXY_AUTHENTICATION_REQUIRED : Int

    Proxy Authentication Required.

    HTTP_408_REQUEST_TIMEOUT

    let HTTP_408_REQUEST_TIMEOUT : Int

    Request Timeout: the client took too long to send it.

    HTTP_409_CONFLICT

    let HTTP_409_CONFLICT : Int

    Conflict: it clashes with the resource's current state.

    HTTP_410_GONE

    let HTTP_410_GONE : Int

    Gone: it existed and was removed on purpose.

    HTTP_411_LENGTH_REQUIRED

    let HTTP_411_LENGTH_REQUIRED : Int

    Length Required: Content-Length is missing and this server insists on it.

    HTTP_412_PRECONDITION_FAILED

    let HTTP_412_PRECONDITION_FAILED : Int

    Precondition Failed: an If-* header did not hold.

    HTTP_413_REQUEST_ENTITY_TOO_LARGE

    let HTTP_413_REQUEST_ENTITY_TOO_LARGE : Int

    Content Too Large — Starlette's name keeps RFC 7231's "Request Entity Too Large".

    HTTP_414_REQUEST_URI_TOO_LONG

    let HTTP_414_REQUEST_URI_TOO_LONG : Int

    URI Too Long — Starlette's name keeps RFC 7231's "Request-URI Too Long".

    HTTP_415_UNSUPPORTED_MEDIA_TYPE

    let HTTP_415_UNSUPPORTED_MEDIA_TYPE : Int

    Unsupported Media Type: the body's Content-Type is one this route cannot read.

    HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE

    let HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE : Int

    Range Not Satisfiable: no part of the requested range exists.

    HTTP_417_EXPECTATION_FAILED

    let HTTP_417_EXPECTATION_FAILED : Int

    Expectation Failed: the Expect header cannot be met.

    HTTP_418_IM_A_TEAPOT

    let HTTP_418_IM_A_TEAPOT : Int

    I'm a Teapot: RFC 2324's joke, kept because clients test for it.

    HTTP_421_MISDIRECTED_REQUEST

    let HTTP_421_MISDIRECTED_REQUEST : Int

    Misdirected Request: this connection is not authoritative for that authority.

    HTTP_422_UNPROCESSABLE_ENTITY

    let HTTP_422_UNPROCESSABLE_ENTITY : Int

    Unprocessable Content: well-formed, and it fails validation — what unprocessable returns.

    HTTP_423_LOCKED

    let HTTP_423_LOCKED : Int

    Locked: WebDAV, the resource is locked.

    HTTP_424_FAILED_DEPENDENCY

    let HTTP_424_FAILED_DEPENDENCY : Int

    Failed Dependency: WebDAV, a request this one depended on failed.

    HTTP_425_TOO_EARLY

    let HTTP_425_TOO_EARLY : Int

    Too Early: replaying this early-data request could be a replay attack.

    HTTP_426_UPGRADE_REQUIRED

    let HTTP_426_UPGRADE_REQUIRED : Int

    Upgrade Required: resend over the protocol named in Upgrade.

    HTTP_428_PRECONDITION_REQUIRED

    let HTTP_428_PRECONDITION_REQUIRED : Int

    Precondition Required: the server refuses to act on an unconditional write.

    HTTP_429_TOO_MANY_REQUESTS

    let HTTP_429_TOO_MANY_REQUESTS : Int

    Too Many Requests: rate limited; Retry-After says when to come back.

    HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE

    let HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE : Int

    Request Header Fields Too Large.
    let HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS : Int

    Unavailable For Legal Reasons.

    HTTP_500_INTERNAL_SERVER_ERROR

    let HTTP_500_INTERNAL_SERVER_ERROR : Int

    Internal Server Error: the fallback for an error the app did not map.

    HTTP_501_NOT_IMPLEMENTED

    let HTTP_501_NOT_IMPLEMENTED : Int

    Not Implemented: the server does not support the method at all.

    HTTP_502_BAD_GATEWAY

    let HTTP_502_BAD_GATEWAY : Int

    Bad Gateway: an upstream sent something invalid.

    HTTP_503_SERVICE_UNAVAILABLE

    let HTTP_503_SERVICE_UNAVAILABLE : Int

    Service Unavailable: down or overloaded, and expected back.

    HTTP_504_GATEWAY_TIMEOUT

    let HTTP_504_GATEWAY_TIMEOUT : Int

    Gateway Timeout: an upstream did not answer in time.

    HTTP_505_HTTP_VERSION_NOT_SUPPORTED

    let HTTP_505_HTTP_VERSION_NOT_SUPPORTED : Int

    HTTP Version Not Supported.

    HTTP_506_VARIANT_ALSO_NEGOTIATES

    let HTTP_506_VARIANT_ALSO_NEGOTIATES : Int

    Variant Also Negotiates: the negotiation is configured in a circle.

    HTTP_507_INSUFFICIENT_STORAGE

    let HTTP_507_INSUFFICIENT_STORAGE : Int

    Insufficient Storage: WebDAV, no room to store the representation.

    HTTP_508_LOOP_DETECTED

    let HTTP_508_LOOP_DETECTED : Int

    Loop Detected: WebDAV, the traversal is cyclic.

    HTTP_510_NOT_EXTENDED

    let HTTP_510_NOT_EXTENDED : Int

    Not Extended.

    HTTP_511_NETWORK_AUTHENTICATION_REQUIRED

    let HTTP_511_NETWORK_AUTHENTICATION_REQUIRED : Int

    Network Authentication Required: a captive portal wants a login first.

    WS_1000_NORMAL_CLOSURE

    let WS_1000_NORMAL_CLOSURE : Int

    Normal Closure: the purpose the connection was opened for is fulfilled.

    WS_1001_GOING_AWAY

    let WS_1001_GOING_AWAY : Int

    Going Away: the peer is shutting down or navigating off the page.

    WS_1002_PROTOCOL_ERROR

    let WS_1002_PROTOCOL_ERROR : Int

    Protocol Error.

    WS_1003_UNSUPPORTED_DATA

    let WS_1003_UNSUPPORTED_DATA : Int

    Unsupported Data: a frame of a type this endpoint cannot accept.

    WS_1005_NO_STATUS_RCVD

    let WS_1005_NO_STATUS_RCVD : Int

    No Status Received: reported locally when a close frame carried no code.

    WS_1006_ABNORMAL_CLOSURE

    let WS_1006_ABNORMAL_CLOSURE : Int

    Abnormal Closure: reported locally when the connection died without a close frame.

    WS_1007_INVALID_FRAME_PAYLOAD_DATA

    let WS_1007_INVALID_FRAME_PAYLOAD_DATA : Int

    Invalid Frame Payload Data: a text frame that is not valid UTF-8, say.

    WS_1008_POLICY_VIOLATION

    let WS_1008_POLICY_VIOLATION : Int

    Policy Violation: the generic refusal when no other code fits.

    WS_1009_MESSAGE_TOO_BIG

    let WS_1009_MESSAGE_TOO_BIG : Int

    Message Too Big.

    WS_1010_MANDATORY_EXT

    let WS_1010_MANDATORY_EXT : Int

    Mandatory Extension: the client required an extension the server did not negotiate.

    WS_1011_INTERNAL_ERROR

    let WS_1011_INTERNAL_ERROR : Int

    Internal Error: the server hit an unexpected condition.

    WS_1012_SERVICE_RESTART

    let WS_1012_SERVICE_RESTART : Int

    Service Restart.

    WS_1013_TRY_AGAIN_LATER

    let WS_1013_TRY_AGAIN_LATER : Int

    Try Again Later: overloaded; come back.

    WS_1014_BAD_GATEWAY

    let WS_1014_BAD_GATEWAY : Int

    Bad Gateway: the gateway got an invalid response upstream.

    WS_1015_TLS_HANDSHAKE

    let WS_1015_TLS_HANDSHAKE : Int

    TLS Handshake: reported locally when the handshake failed.

    data_response

    fn data_response(url : String, filename? : String, status? : Int, inline? : Bool) ->
    Response
    ?

    Serve what a data: URL carries (RFC 2397), under the media type it names — what canvas.toDataURL() and FileReader.readAsDataURL() hand back.

    None when it is not a data URL, so a handler tells "no picture" from "not a picture" without touching base64.

    data_url

    fn data_url(content : Bytes, media_type? : String) -> String

    The content as a data: URL, for embedding it instead of costing a second request.
    fn delete_cookie(resp :
    Response
    , name : String, path? : String?, domain? : String, secure? : Bool, http_only? : Bool, same_site? :
    SameSite
    ?) ->
    Response

    Expire the cookie named name (← FastAPI's response.delete_cookie): an empty value with Max-Age=0 and a date in the past, so a browser that honours only one of the two still drops it.

    A cookie is identified by name, domain and path together, so path and domain must match what set it — otherwise this writes a second, differently scoped cookie and the original survives.

    envelope

    fn envelope(length : Int, filename : String, media_type : String, inline : Bool) -> Array[(String, String)]

    What the body is, how long, and what to save it as.

    file_response

    fn file_response(content : Bytes, filename? : String, media_type? : String, status? : Int, inline? : Bool) ->
    Response

    A download (← FastAPI's FileResponse): a media type from filename's extension unless media_type names one, Content-Length, and a Content-Disposition. No filename, no disposition.

    Bytes rather than a path: the same app runs on four backends and only the server can read a file on any of them.

    Always the whole thing. [Context::serve] weighs the request first.

    html

    fn html(status : Int, body : String) ->
    Response

    An HTML response — what the documentation pages are served as.

    json

    fn json(status : Int, value : Json) ->
    Response

    A JSON response serialised from a Json value.

    redirect

    fn redirect(url : String, status? : Int) ->
    Response

    A redirect to url (← FastAPI's RedirectResponse).

    307 keeps the method and body, which 302 historically does not. Use 303 after a write, 301 / 308 for a permanent move.

    The URL is escaped as a whole URI reference, so an encoded one is not encoded twice and a \r\n cannot open a header of its own.
    fn set_cookie(resp :
    Response
    , name : String, value : String, max_age? : Int, expires? :
    Moment
    , path? : String?, domain? : String, secure? : Bool, http_only? : Bool, same_site? :
    SameSite
    ?) ->
    Response

    Add a Set-Cookie header to resp (← FastAPI's response.set_cookie), returning the response that carries it; the original is untouched, so a handler can hand the same base response to two callers.

    max_age is the lifetime in seconds and expires the moment it dies; giving neither makes it a session cookie. path defaults to /, and None omits the attribute so the cookie scopes to the request's own directory. http_only keeps it away from scripts, secure keeps it off plaintext connections, and same_site defaults to Lax — the browser default, and the one that stops a cross-site form post from carrying a session.

    sse

    fn sse(body : async (Events) -> Unit, status? : Int, headers? : Array[(String, String)], space? : Bool, wins? :
    Wins
    , clash? :
    OnClash
    [Array[(String, String)]]) -> Stream

    A text/event-stream response (← sse-starlette's EventSourceResponse). body sends frames for as long as it likes; the app cancels it when the client goes.

    Framing an event is moonhttp/sse's job. What belongs here is the response around the frames, and the three headers that stop an intermediary buffering or closing the stream. One named in headers too replaces ours rather than joining it, because a response carrying two content-type headers is not a response with a choice in it. wins=Base keeps ours, and clash can abort or take a callback instead — worth setting when overriding content-type, which stops the stream being a stream.

    text

    fn text(status : Int, body : String) ->
    Response

    A plain-text response.