Sign in

    mocket

    A web framework for MoonBit.

    http
    server
    Download zip
    Author
    Version
    0.9.2
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    2K

    #oboard/mocket

    Version GitHub Workflow Status (with event) License

    A web framework for MoonBit.

    #Quick Start

    async fn main {
    let app = @mocket.new()
    app.get("/", _ => "Hello, Mocket!")
    app.listen(":80")
    }

    Mocket supports both js and native backends.

    #JavaScript Backend

    Set the backend of MoonBit to js in Visual Studio Code

    Command: MoonBit: Select Backend -> js

    moon run src/example --target js

    #Native Backend

    Set the backend of MoonBit to native in Visual Studio Code

    Command: MoonBit: Select Backend -> native

    moon run src/example --target native

    Then visit http://localhost:4000

    #Usage

    Minimum Example: https://github.com/oboard/mocket_example

    🙌快来吧!🙌

    QQ 群号:949886784

    QQ 群

    ErrorHandler

    type ErrorHandler = (MocketEvent, Error) -> &Responder

    HttpHandler

    type HttpHandler = async (MocketEvent) -> &Responder

    Middleware

    type Middleware = async (MocketEvent, async () -> &Responder) -> &Responder

    MiddlewareNext

    type MiddlewareNext = async () -> &Responder

    WebSocketHandler

    type WebSocketHandler = (WebSocketEvent) -> Unit

    BodyReader

    pub(open) trait BodyReader {
    fn from_request(req : HttpRequest) -> Self raise
    }

    impl BodyReader for Bytes
    impl BodyReader for Json

    Responder

    pub(open) trait Responder {
    fn options(Self, res : HttpResponse) -> Unit
    fn output(Self, buf :
    Buffer
    ) -> Unit
    }

    impl Responder for String
    impl Responder for Bytes
    impl Responder for Json
    impl Responder for ToJson

    ServeStaticProvider

    pub(open) trait ServeStaticProvider {
    async fn get_meta(Self, id : StringView) -> StaticAssetMeta?
    async fn get_contents(Self, id : StringView) -> &Responder
    fn get_type(Self, ext : String) -> String?
    fn get_encodings(Self) -> Map[String, String]
    fn get_index_names(Self) -> Array[String]
    fn get_fallthrough(Self) -> Bool
    }

    A backend for Mocket::static_assets.

    Asset ids handed to the provider are virtual absolute paths rooted at the mount point: they always start with "/" and are already normalized, so "." / ".." segments can never escape the provider's root. Providers should join the id onto their root directly.

    ExecError

    pub suberror ExecError

    IOError

    pub suberror IOError

    NetworkError

    pub suberror NetworkError

    CookieItem

    pub(all) struct CookieItem {
    name : String
    value : String
    max_age : Int?
    path : String?
    domain : String?
    secure : Bool?
    http_only : Bool?
    same_site : SameSiteOption?
    } derive(Eq)

    impl Show for CookieItem

    Html

    type Html

    impl Responder for Html

    HttpRequest

    pub(all) struct HttpRequest {
    http_method : String
    url : String
    query : String
    headers : Map[
    CaseInsensitiveString
    , StringView]
    raw_body : Bytes
    }

    HttpRequest::body

    fn[T : BodyReader] HttpRequest::body(self : HttpRequest) -> T raise

    fn HttpRequest::get_cookie(self : HttpRequest, name : String) -> CookieItem?

    HttpRequest::json

    HttpRequest::query

    fn HttpRequest::query(self : HttpRequest) -> Map[String, String]

    HttpResponse

    pub(all) struct HttpResponse {
    status_code : StatusCode
    headers : Map[
    CaseInsensitiveString
    , StringView]
    cookies : Map[String, CookieItem]
    raw_body : Bytes
    }

    HttpResponse::body

    fn HttpResponse::body(self : HttpResponse, body : &Responder) -> HttpResponse

    Sets the response body from any Responder.

    The body responder's default Content-Type is carried into this response only when no explicit "Content-Type" header was set on this response. Explicit response headers always take precedence.

    Only the default Content-Type is inferred. The responder's status, other headers, cookies, and any other responder effects are not merged, so self.status_code is preserved.
    fn HttpResponse::delete_cookie(self : HttpResponse, key : String) -> Unit

    HttpResponse::json

    fn HttpResponse::json(self : HttpResponse, obj : &ToJson) -> HttpResponse

    Sets a JSON response body.

    Infers Content-Type: application/json; charset=utf-8 under the same rule as HttpResponse::body: an explicit "Content-Type" header already present on this response takes precedence, and self.status_code is preserved.

    HttpResponse::new

    fn HttpResponse::new(status_code : StatusCode, headers? : Map[
    CaseInsensitiveString
    , StringView], cookies? : Map[String, CookieItem], raw_body? : Bytes) -> HttpResponse

    HttpResponse::read_body

    fn[T : BodyReader] HttpResponse::read_body(self : HttpResponse) -> T raise

    fn HttpResponse::set_cookie(self : HttpResponse, name : String, value : String, max_age? : Int, path? : String, domain? : String, secure? : Bool, http_only? : Bool, same_site? : SameSiteOption) -> Unit

    HttpResponse::to_responder

    fn HttpResponse::to_responder(self : HttpResponse) -> &Responder

    Mocket

    #alias(T)
    pub(all) struct Mocket {
    base_path : String
    mappings : Map[(String, String), async (MocketEvent) -> &Responder]
    middlewares : Array[(String, async (MocketEvent, async () -> &Responder) -> &Responder)]
    static_routes : Map[String, Map[String, async (MocketEvent) -> &Responder]]
    dynamic_routes : Map[String, Array[(String, async (MocketEvent) -> &Responder)]]
    ws_static_routes : Map[String, (WebSocketEvent) -> Unit]
    ws_dynamic_routes : Array[(String, (WebSocketEvent) -> Unit)]
    ws_clients : Map[String, Unit]
    ws_channels : Map[String, Map[String, Unit]]
    ws_client_port : Map[String, Int]
    max_body_size : Int
    error_handler : (MocketEvent, Error) -> &Responder
    // private fields
    }

    Mocket::acl

    fn Mocket::acl(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::all

    fn Mocket::all(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::bind

    fn Mocket::bind(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::checkin

    fn Mocket::checkin(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::checkout

    fn Mocket::checkout(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::connect

    fn Mocket::connect(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::copy

    fn Mocket::copy(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::delete

    fn Mocket::delete(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::get

    fn Mocket::get(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::group

    fn Mocket::group(self : Mocket, base_path : String, configure : (Mocket) -> Unit) -> Unit

    Mocket::head

    fn Mocket::head(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::label

    fn Mocket::label(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    fn Mocket::link(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::listen

    async fn Mocket::listen(self : Mocket, address : String) -> Unit noraise

    Mocket::lock

    fn Mocket::lock(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::merge

    fn Mocket::merge(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::mkactivity

    fn Mocket::mkactivity(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::mkcalendar

    fn Mocket::mkcalendar(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::mkcol

    fn Mocket::mkcol(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::mkredirectref

    fn Mocket::mkredirectref(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::mkworkspace

    fn Mocket::mkworkspace(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::move_

    fn Mocket::move_(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::on

    fn Mocket::on(self : Mocket, event : String, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::on_error

    fn Mocket::on_error(self : Mocket, handler : (MocketEvent, Error) -> &Responder) -> Unit

    Mocket::options

    fn Mocket::options(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::orderpatch

    fn Mocket::orderpatch(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::patch

    fn Mocket::patch(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::post

    fn Mocket::post(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::pri

    fn Mocket::pri(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::propfind

    fn Mocket::propfind(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::proppatch

    fn Mocket::proppatch(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::put

    fn Mocket::put(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::query

    fn Mocket::query(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::rebind

    fn Mocket::rebind(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::report

    fn Mocket::report(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::search

    fn Mocket::search(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::serve

    #deprecated("use `Mocket::listen(address)` instead")
    async fn Mocket::serve(self : Mocket, port~ : Int) -> Unit noraise

    Mocket::static_assets

    fn Mocket::static_assets(self : Mocket, path : String, provider : &ServeStaticProvider) -> Unit

    Mocket::trace

    fn Mocket::trace(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::unbind

    fn Mocket::unbind(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::uncheckout

    fn Mocket::uncheckout(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    fn Mocket::unlink(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::unlock

    fn Mocket::unlock(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::update

    fn Mocket::update(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::updateredirectref

    fn Mocket::updateredirectref(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::use_middleware

    fn Mocket::use_middleware(self : Mocket, middleware : async (MocketEvent, async () -> &Responder) -> &Responder, base_path? : String) -> Unit

    Mocket::version_control

    fn Mocket::version_control(self : Mocket, path : String, handler : async (MocketEvent) -> &Responder) -> Unit

    Mocket::ws

    fn Mocket::ws(self : Mocket, path : String, handler : (WebSocketEvent) -> Unit) -> Unit

    MocketEvent

    pub(all) struct MocketEvent {
    req : HttpRequest
    res : HttpResponse
    params : Map[String, StringView]
    }

    MultipartFormValue

    pub(all) struct MultipartFormValue {
    filename : String?
    content_type : String?
    data : BytesView
    }

    SameSiteOption

    pub(all) enum SameSiteOption {
    Lax
    Strict
    SameSiteNone
    } derive(Eq)

    StaticAssetMeta

    pub(all) struct StaticAssetMeta {
    asset_type : String?
    etag : String?
    mtime : Int64?
    path : String?
    size : Int64?
    encoding : String?
    }

    StaticAssetMeta::new

    fn StaticAssetMeta::new(asset_type? : String, etag? : String, mtime? : Int64, path? : String, size? : Int64, encoding? : String) -> StaticAssetMeta

    StatusCode

    pub(all) enum StatusCode {
    Continue
    SwitchingProtocols
    Processing
    EarlyHints
    OK
    Created
    Accepted
    NonAuthoritativeInfo
    NoContent
    ResetContent
    PartialContent
    MultiStatus
    AlreadyReported
    IMUsed
    MultipleChoices
    MovedPermanently
    Found
    SeeOther
    NotModified
    UseProxy
    TemporaryRedirect
    PermanentRedirect
    BadRequest
    Unauthorized
    PaymentRequired
    Forbidden
    NotFound
    MethodNotAllowed
    NotAcceptable
    ProxyAuthRequired
    RequestTimeout
    Conflict
    Gone
    LengthRequired
    PreconditionFailed
    RequestEntityTooLarge
    RequestUriTooLong
    UnsupportedMediaType
    RequestedRangeNotSatisfiable
    ExpectationFailed
    Teapot
    MisdirectedRequest
    UnprocessableEntity
    Locked
    FailedDependency
    TooEarly
    UpgradeRequired
    PreconditionRequired
    TooManyRequests
    RequestHeaderFieldsTooLarge
    UnavailableForLegalReasons
    InternalServerError
    NotImplemented
    BadGateway
    ServiceUnavailable
    GatewayTimeout
    HttpVersionNotSupported
    VariantAlsoNegotiates
    InsufficientStorage
    LoopDetected
    NotExtended
    NetworkAuthenticationRequired
    Custom(Int)
    } derive(Eq, ToJson)

    HTTP status codes as registered with IANA. See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

    StatusCode::from_int

    fn StatusCode::from_int(i : Int) -> StatusCode

    StatusCode::to_int

    fn StatusCode::to_int(self : StatusCode) -> Int

    WebSocketAggregatedMessage

    pub(all) enum WebSocketAggregatedMessage {
    Text(String)
    Binary(Bytes)
    Ping
    }

    WebSocketEvent

    pub(all) enum WebSocketEvent {
    Open(WebSocketPeer)
    Message(WebSocketPeer, WebSocketAggregatedMessage)
    Close(WebSocketPeer)
    }

    WebSocketPeer

    pub(all) struct WebSocketPeer {
    connection_id : String
    subscribed_channels : Array[String]
    }

    WebSocketPeer::binary

    fn WebSocketPeer::binary(self : WebSocketPeer, message : Bytes) -> Unit

    WebSocketPeer::pong

    fn WebSocketPeer::pong(self : WebSocketPeer) -> Unit

    WebSocketPeer::publish

    fn WebSocketPeer::publish(channel : String, message : String) -> Unit

    WebSocketPeer::subscribe

    fn WebSocketPeer::subscribe(self : WebSocketPeer, channel : String) -> Unit

    WebSocketPeer::text

    fn WebSocketPeer::text(self : WebSocketPeer, message : String) -> Unit

    WebSocketPeer::to_string

    fn WebSocketPeer::to_string(self : WebSocketPeer) -> String

    WebSocketPeer::unsubscribe

    fn WebSocketPeer::unsubscribe(self : WebSocketPeer, channel : String) -> Unit

    __ws_emit

    fn __ws_emit(event_type : Bytes, connection_id : Bytes, payload : Bytes) -> Unit

    fn cookie_to_string(cookie : Array[CookieItem]) -> String

    dispatch_http

    async fn dispatch_http(mocket : Mocket, http_method : String, url : String, headers : Map[
    CaseInsensitiveString
    , StringView], raw_body : Bytes) -> HttpResponse

    dispatch_ws_event

    fn dispatch_ws_event(handler : (WebSocketEvent) -> Unit, peer : WebSocketPeer, event_type : String, payload : Bytes) -> Unit

    将 WS 事件类型字符串和 payload 转换为 WebSocketEvent 并调用 handler

    encode_multipart

    fn encode_multipart(m : Map[String, MultipartFormValue], boundary : String) -> String

    escape_html

    fn escape_html(s : String) -> String

    execute_middlewares

    async fn execute_middlewares(middlewares : Array[(String, async (MocketEvent, async () -> &Responder) -> &Responder)], event : MocketEvent, final_handler : async (MocketEvent) -> &Responder) -> &Responder

    form_encode

    fn form_encode(map : Map[String, String]) -> String

    handle_not_found

    fn handle_not_found() -> (async (MocketEvent) -> &Responder)

    html

    fn html(html : &Show) -> &Responder

    listen_ffi

    async fn listen_ffi(mocket : Mocket, address : String) -> Unit noraise

    Listen and serve on address.

    The native listener enables SO_REUSEADDR (reuse_addr=true) so that a process can immediately rebind a port that a previous process left in TIME_WAIT. On macOS/BSD this has the side effect that a bind to a specific address may "steal" the specific interface from an existing wildcard bind (0.0.0.0), and a wildcard bind can bind to the remaining interfaces if a specific-interface bind already exists.

    new

    fn new(base_path? : String, max_body_size? : Int) -> Mocket

    fn parse_cookie(cookie : StringView) -> Map[String, CookieItem]

    parse_form_data

    fn parse_form_data(bytes : BytesView) -> Map[String, String]

    parse_multipart

    fn parse_multipart(bytes : BytesView, boundary : String) -> Map[String, MultipartFormValue]

    parse_query

    fn parse_query(query_string : StringView) -> Map[String, String]

    register_ws_connection

    fn register_ws_connection(connection_id : String, text_sender : (String) -> Unit, binary_sender : (Bytes) -> Unit, pong_sender : () -> Unit) -> Unit

    register_ws_handler

    fn register_ws_handler(mocket : Mocket, port : Int) -> Unit

    serve_ffi

    async fn serve_ffi(mocket : Mocket, port~ : Int) -> Unit noraise

    suspend

    async fn[T, E : Error] suspend(f : ((T) -> Unit, (E) -> Unit) -> Unit) -> T raise E

    suspend 会中断当前协程的运行。 suspend 会接受一个回调函数,并让这个回调函数来操作中断的协程

    text

    fn text(text : &Show) -> &Responder

    unregister_ws_connection

    fn unregister_ws_connection(connection_id : String) -> Unit

    url_decode

    fn url_decode(bytes : BytesView) -> String

    url_encode

    fn url_encode(s : String) -> String

    ws_pong

    fn ws_pong(id : String) -> Unit

    ws_publish

    fn ws_publish(channel : String, msg : String) -> Unit

    ws_send

    fn ws_send(id : String, msg : String) -> Unit

    ws_send_bytes

    fn ws_send_bytes(id : String, msg : Bytes) -> Unit

    ws_subscribe

    fn ws_subscribe(id : String, channel : String) -> Unit

    ws_unsubscribe

    fn ws_unsubscribe(id : String, channel : String) -> Unit