mooncat — a native ASGI 3.0 server for MoonBit (← uvicorn), built on moonbitlang/async and the moonasgi SEAM.
Dependencies
flowchart LR
net["moonbitlang/async<br/>(sockets · TLS · HTTP/1.1)"] --> cat["**mooncat**<br/>accept loop"]
cat -->|"Scope / Receive / Send"| asgi(["moonasgi SEAM"])
asgi --> app["your app<br/>(moonapi, …)"]// An ASGI app: respond 200 with a text body.
let app : @moonasgi.AsgiApp = (_scope, _receive, send) => {
send(@moonasgi.Event::HttpResponseStart(
status=200, headers=[("content-type", "text/plain")]))
send(@moonasgi.Event::HttpResponseBody(
body=b"Hello from mooncat!", more_body=false))
}
// Serve it (inside an async context / task group):
@mooncat.serve(app, host="127.0.0.1", port=8000)@mooncat.serve_tls(app,
certificate_file="certs/cert.pem", // PEM cert (OpenSSL platforms)
private_key_file="certs/key.pem", // PEM key (OpenSSL platforms)
pfx_file="certs/dev.pfx", // PKCS#12 (Windows / SChannel)
port=8443)let handle = @mooncat.ShutdownHandle::new()
g.spawn(() => @mooncat.serve_graceful(app, @mooncat.Config::new(port=8000), handle~))
// … later, from anywhere:
handle.shutdown() // stop accepting → drain in-flight → lifespan shutdown → close@mooncat.serve_h2c(app, host="127.0.0.1", port=8000)pub suberror FlowError {
FlowError(String)
}pub suberror Http3ConnError {
Http3ConnError(String)
}pub suberror Http3FrameError {
Http3FrameError(String)
}pub suberror LifespanError {
LifespanError(String)
}pub suberror QpackError {
QpackError(String)
}pub suberror QuicPayloadError {
QuicPayloadError(String)
}pub suberror ReassemblyError {
ReassemblyError(String)
}pub suberror StreamStateError {
StreamStateError(String)
}pub suberror WsError {
WsError(Int, String)
}pub(all) struct Config {
host : String
port : Int
backlog : Int
dual_stack : Bool
reuse_addr : Bool
server_headers : Map[String, String]
max_connections : Int?
allow_failure : Bool
graceful_timeout : Int?
root_path : String
logger : Logger
timeout_keep_alive : Int
limit_max_requests : Int?
limit_concurrency : Int?
max_head_size : Int
date_header : Bool
proxy_headers : Bool
forwarded_allow_ips : Array[String]
ws : WsConfig
}fn Config::new(host? : String, port? : Int, backlog? : Int, dual_stack? : Bool, reuse_addr? : Bool, server_headers? : Map[String, String], max_connections? : Int?, allow_failure? : Bool, graceful_timeout? : Int?, root_path? : String, logger? : Logger, timeout_keep_alive? : Int, limit_max_requests? : Int?, limit_concurrency? : Int?, max_head_size? : Int, date_header? : Bool, proxy_headers? : Bool, forwarded_allow_ips? : Array[String], ws? : WsConfig) -> Configpub struct Http3Conn {
role : Http3Role
local_settings : Http3Settings
peer_settings : Http3Settings?
control_seen : Bool
}pub(all) struct Http3Request {
meth : String
scheme : String
authority : String
path : String
headers : Array[(String, String)]
body : Bytes
}fn Http3Settings::new(qpack_max_table_capacity : UInt64, max_field_section_size : UInt64, qpack_blocked_streams : UInt64) -> Http3Settingspub(all) enum Http3UniEvent {
ControlEstablished(Http3Settings)
QpackEncoder
QpackDecoder
Push(UInt64)
Reserved(UInt64)
} derive(Eq, Debug)pub struct NewReno {
cwnd : Int64
ssthresh : Int64
bytes_in_flight : Int64
max_datagram_size : Int64
}pub struct PacketNumberSpace {
next_pn : Int64
received : AckRangeSet
largest_acked : Int64?
ack_eliciting_pending : Bool
}fn PacketNumberSpace::on_packet_received(self : PacketNumberSpace, pn : Int64, ack_eliciting : Bool) -> Unitpub(all) struct QpackDynamicTable {
entries : Array[(Bytes, Bytes)]
used : Int
capacity : Int
insert_count : Int
dropped : Int
}fn QpackDynamicTable::apply(self : QpackDynamicTable, inst : QpackEncoderInst) -> Bool raise QpackErrorpub struct QuicConnection {
is_server : Bool
initial_space : PacketNumberSpace
handshake_space : PacketNumberSpace
application_space : PacketNumberSpace
initial_crypto : StreamReassembler
handshake_crypto : StreamReassembler
application_crypto : StreamReassembler
}fn QuicConnection::build_ack(self : QuicConnection, level : QuicLevel, ack_delay : UInt64) -> QuicFrame?fn QuicConnection::on_ack_received(self : QuicConnection, level : QuicLevel, largest : Int64) -> Unitfn QuicConnection::on_crypto_frame(self : QuicConnection, level : QuicLevel, offset : UInt64, data : Bytes) -> Bytes raise ReassemblyErrorfn QuicConnection::on_packet_received(self : QuicConnection, level : QuicLevel, pn : Int64, ack_eliciting : Bool) -> Unitpub(all) enum QuicFrame {
Padding(Int)
Ping
Crypto(offset~ : UInt64, data~ : Bytes)
Stream(id~ : UInt64, offset~ : UInt64, fin~ : Bool, data~ : Bytes)
Ack(largest~ : UInt64, delay~ : UInt64, first_range~ : UInt64, ranges~ : Array[(UInt64, UInt64)])
AckEcn(largest~ : UInt64, delay~ : UInt64, first_range~ : UInt64, ranges~ : Array[(UInt64, UInt64)], ect0~ : UInt64, ect1~ : UInt64, ce~ : UInt64)
ResetStream(id~ : UInt64, error_code~ : UInt64, final_size~ : UInt64)
StopSending(id~ : UInt64, error_code~ : UInt64)
NewToken(token~ : Bytes)
MaxData(UInt64)
MaxStreamData(id~ : UInt64, max~ : UInt64)
MaxStreams(bidi~ : Bool, max~ : UInt64)
DataBlocked(UInt64)
StreamDataBlocked(id~ : UInt64, max~ : UInt64)
StreamsBlocked(bidi~ : Bool, max~ : UInt64)
NewConnectionId(seq~ : UInt64, retire_prior_to~ : UInt64, conn_id~ : Bytes, reset_token~ : Bytes)
RetireConnectionId(UInt64)
PathChallenge(Bytes)
PathResponse(Bytes)
HandshakeDone
ConnectionClose(error_code~ : UInt64, frame_type~ : UInt64?, reason~ : Bytes)
} derive(Eq, Debug)pub(all) struct QuicLongHeader {
packet_type : QuicLongPacketType
type_specific : Int
version : UInt
dcid : Bytes
scid : Bytes
} derive(Eq, Debug)pub struct QuicRecovery {
rtt : RttEstimator
tracker : SentPacketTracker
cc : NewReno
max_ack_delay : Int64
granularity : Int64
packet_threshold : Int64
pto_count : Int
last_sent_time : Int64
}fn QuicRecovery::new(max_datagram_size : Int64, max_ack_delay : Int64, granularity : Int64) -> QuicRecoveryfn QuicRecovery::on_ack_received(self : QuicRecovery, frame : QuicFrame, now : Int64, ack_delay : Int64) -> Array[Int64] raisefn QuicSendFlow::record_stream_sent(self : QuicSendFlow, id : UInt64, n : UInt64) -> Unit raise FlowErrorpub struct QuicSender {
sched : QuicStreamScheduler
recovery : QuicRecovery
data : Map[UInt64, Bytes]
in_packet : Map[Int64, Array[StreamSend]]
retransmit : Array[StreamSend]
next_pn : Int64
}fn QuicSender::new(initial_max_data : UInt64, initial_max_stream_data : UInt64, max_datagram_size : Int64, max_ack_delay : Int64, granularity : Int64, max_frame : UInt64) -> QuicSenderpub(all) struct QuicServeConfig {
version : UInt
idle_timeout : Int64
close_period : Int64
max_datagram : Int64
max_ack_delay : Int64
granularity : Int64
initial_max_data : UInt64
initial_max_stream_data : UInt64
max_frame : UInt64
}pub struct QuicServeConn[A] {
peer : A
cid : Bytes
peer_cid : Bytes
core : QuicServerConn
sender : QuicSender
cfg : QuicServeConfig
out : Array[Bytes]
received : Array[(QuicLevel, QuicFrame)]
rx : Int64
tx : Int64
packets : Int
validated : Bool
last_rx : Int64
idle_timeout : Int64
phase : QuicConnPhase
close_at : Int64
close_frame : QuicFrame?
close_level : QuicLevel
hs_rx : QuicPacketKeys?
hs_rx_secret : Bytes
hs_tx : QuicPacketKeys?
app_rx : QuicPacketKeys?
app_tx : QuicPacketKeys?
}fn[A] QuicServeConn::apply_peer_params(self : QuicServeConn[A], params : Array[TransportParam]) -> Unitfn[A] QuicServeConn::close(self : QuicServeConn[A], error_code : UInt64, reason : Bytes, now : Int64) -> Unitfn[A] QuicServeConn::install_app_keys(self : QuicServeConn[A], client_secret : Bytes, server_secret : Bytes) -> Unitfn[A] QuicServeConn::install_handshake_keys(self : QuicServeConn[A], client_secret : Bytes, server_secret : Bytes) -> Unitfn[A] QuicServeConn::send(self : QuicServeConn[A], level : QuicLevel, frames : Array[QuicFrame]) -> Unitfn[A] QuicServer::close(self : QuicServer[A], cid : Bytes, error_code : UInt64, reason : Bytes, now : Int64) -> Unitpub struct QuicServerConn {
initial_keys : QuicPacketKeys
handshake : TlsServerHandshake
conn : QuicConnection
}fn QuicServerConn::on_frames(self : QuicServerConn, level : QuicLevel, frames : Array[QuicFrame], pn : Int64) -> Array[Int] raisefn QuicServerConn::on_handshake_frames(self : QuicServerConn, frames : Array[QuicFrame], pn : Int64, client_hs_secret : Bytes) -> Bool raisefn QuicServerConn::receive_handshake(self : QuicServerConn, packet : Bytes, client_hs_keys : QuicPacketKeys, client_hs_secret : Bytes) -> Bool raisefn QuicServerConn::send_handshake_flight(self : QuicServerConn, server_hs_secret : Bytes, encrypted_extensions : Bytes, certificate : Bytes, certificate_verify : Bytes, out_dcid : Bytes, out_scid : Bytes, pn : Int64) -> Bytes raisefn QuicServerConn::send_handshake_flight_signed(self : QuicServerConn, server_hs_secret : Bytes, encrypted_extensions : Bytes, certificate : Bytes, signing_key : EcdsaPrivateKey, out_dcid : Bytes, out_scid : Bytes, pn : Int64) -> Bytes raisefn QuicServerConn::send_server_hello(self : QuicServerConn, server_hello : TlsServerHello, out_dcid : Bytes, out_scid : Bytes, pn : Int64) -> Bytespub struct QuicStreamScheduler {
flow : QuicSendFlow
streams : Map[UInt64, StreamOut]
order : Array[UInt64]
cursor : Int
max_frame : UInt64
}fn QuicStreamScheduler::on_max_stream_data(self : QuicStreamScheduler, id : UInt64, new_max : UInt64) -> Unitpub struct RecvFlow {
received : UInt64
consumed : UInt64
limit : UInt64
window : UInt64
}type RecvStreampub struct RttEstimator {
latest_rtt : Int64
min_rtt : Int64
smoothed_rtt : Int64
rttvar : Int64
has_sample : Bool
}fn RttEstimator::update(self : RttEstimator, latest_rtt : Int64, ack_delay : Int64, max_ack_delay : Int64) -> Unitpub struct SendFlow {
sent : UInt64
limit : UInt64
}pub(all) struct SentPacket {
pn : Int64
time_sent : Int64
size : Int64
}fn SentPacketTracker::detect_lost_packets(self : SentPacketTracker, now : Int64, packet_threshold : Int64, time_threshold : Int64) -> Array[SentPacket]fn SentPacketTracker::detect_lost_time(self : SentPacketTracker, now : Int64, time_threshold : Int64) -> Array[Int64]fn SentPacketTracker::on_ack_ranges(self : SentPacketTracker, ranges : Array[(Int64, Int64)]) -> Int64fn SentPacketTracker::on_sent(self : SentPacketTracker, pn : Int64, time_sent : Int64, size : Int64) -> Unitpub struct StreamManager {
streams : Map[UInt64, RecvStream]
conn_flow : RecvFlow
conn_bytes : UInt64
stream_window : UInt64
}fn StreamManager::on_stream_frame(self : StreamManager, id : UInt64, offset : UInt64, data : Bytes, fin : Bool) -> Bytes raisepub(all) struct StreamOut {
pending : UInt64
offset : UInt64
fin_queued : Bool
fin_sent : Bool
}pub struct StreamReassembler {
consumed : UInt64
intervals : Array[(UInt64, Bytes)]
final_size : UInt64?
}fn StreamReassembler::insert(self : StreamReassembler, offset : UInt64, data : Bytes, fin : Bool) -> Unit raise ReassemblyErrorpub(all) struct StreamSend {
stream : UInt64
offset : UInt64
length : UInt64
fin : Bool
}pub(all) struct TlsCert {
certificate_file : String
private_key_file : String
pfx_file : String
}pub(all) struct TlsClientHello {
random : Bytes
session_id : Bytes
cipher_suites : Array[Int]
extensions : Array[TlsExtension]
} derive(Eq, Debug)fn TlsRecordKeys::seal(self : TlsRecordKeys, content_type : Int, content : Bytes) -> Bytes raise TlsAlertfn TlsRecordKeys::seal_padded(self : TlsRecordKeys, content_type : Int, content : Bytes, padding : Int) -> Bytes raise TlsAlertpub struct TlsRecordLayer {
inbox : Bytes
partial : Bytes
read : TlsRecordKeys?
write : TlsRecordKeys?
compat : Bool
}fn TlsRecordLayer::feed(self : TlsRecordLayer, bytes : Bytes) -> Array[TlsRecordEvent] raise TlsAlertpub struct TlsServerHandshake {
state : TlsServerState
transcript : TranscriptHash
buffer : Bytes
client_hello : Bytes
}fn TlsServerHandshake::sent_flight(self : TlsServerHandshake, request_client_cert : Bool) -> Unit raisepub(all) struct TlsServerHello {
random : Bytes
session_id : Bytes
cipher_suite : Int
extensions : Array[TlsExtension]
} derive(Eq, Debug)pub struct Tlv {
tag : Int
value : BytesView
raw : BytesView
}pub(all) struct WsConfig {
max_size : Int
}fn ack_fields_to_ranges(largest : UInt64, first_range : UInt64, pairs : Array[(UInt64, UInt64)]) -> Array[(UInt64, UInt64)] raise QuicAckErrorfn aes128_gcm_open(key : Bytes, nonce : Bytes, packet : Bytes, aad : Bytes) -> Bytes?fn aes128_gcm_seal(key : Bytes, nonce : Bytes, plaintext : Bytes, aad : Bytes) -> Bytesfn base64_decode(data : Bytes) -> Bytesfn base64_encode(data : Bytes) -> Bytesfn der_bit_string(content : Bytes) -> Bytesfn der_context(tag : Int, n : Int) -> Boolfn der_explicit(tag_num : Int, content : Bytes) -> Bytesfn der_integer(magnitude : Bytes) -> Bytesfn der_length(n : Int) -> Bytesfn der_tlv(tag : Int, value : Bytes) -> Bytesfn der_utc_time(s : String) -> Byteslet h3_settings_max_field_section_size : UInt64let h3_settings_qpack_blocked_streams : UInt64let h3_settings_qpack_max_table_capacity : UInt64fn hkdf_expand(prk : Bytes, info : Bytes, length : Int) -> Bytesfn hkdf_expand_label(secret : Bytes, label : Bytes, context : Bytes, length : Int) -> Bytesfn hkdf_extract(salt : Bytes, ikm : Bytes) -> Bytesfn hmac_sha256(key : Bytes, msg : Bytes) -> Bytesfn http3_request(meth : String, scheme : String, authority : String, path : String, headers : Array[(String, String)], body : Bytes) -> Bytesfn http3_serve(request_bytes : Bytes, handler : (Http3Request) -> Http3Response) -> Bytes raise Http3FrameErrorfn http_date(ms : Int64) -> Stringfn http_date_now() -> Stringfn qpack_decode_field_section_dyn(input : Bytes, table : QpackDynamicTable, max_entries : Int) -> Array[(String, String)] raise QpackErrorfn qpack_decode_required_insert_count(encoded : Int, max_entries : Int, total_inserts : Int) -> Int raise QpackErrorfn qpack_decode_section_prefix(input : BytesView, max_entries : Int, total_inserts : Int) -> (Int, Int, Int)? raise QpackErrorfn qpack_encode_dynamic(headers : Array[(String, String)], table : QpackDynamicTable, max_entries : Int, huffman? : Bool) -> (Bytes, Bytes)fn qpack_encode_section_prefix(req_insert_count : Int, base : Int, max_entries : Int) -> Bytesfn qpack_encode_string(data : Bytes, prefix_bits : Int, pattern : Int, huffman : Bool) -> Bytesfn qpack_entry_size(name : Bytes, value : Bytes) -> Intfn qpack_int_decode(input : BytesView, prefix_bits : Int) -> (Int, Int)?fn qpack_int_encode(value : Int, prefix_bits : Int, flags : Int) -> Bytesfn qpack_max_entries(max_capacity : Int) -> Intfn qpack_static_find(name : String, value : String) -> Int?fn qpack_static_find_name(name : String) -> Int?fn qpack_static_get(index : Int) -> (String, String)?fn qpack_static_len() -> Intlet quic_amplification_factor : Int64fn quic_application_keys(master_secret : Bytes, transcript_hash : Bytes, is_client : Bool) -> QuicPacketKeysfn quic_client_initial_secret(dcid : Bytes) -> Bytesfn quic_effective_idle_timeout(ours : Int64, theirs : Int64) -> Int64fn quic_handshake_keys(handshake_secret : Bytes, transcript_hash : Bytes, is_client : Bool) -> QuicPacketKeysfn quic_header_protect(packet : Bytes, pn_offset : Int, pn_length : Int, hp_key : Bytes) -> Bytesfn quic_header_unprotect(packet : Bytes, pn_offset : Int, hp_key : Bytes) -> (Bytes, Int)fn quic_hp_mask(hp_key : Bytes, sample : Bytes) -> Bytesfn quic_initial_secret(dcid : Bytes) -> Bytesfn quic_key_update(secret : Bytes) -> Byteslet quic_min_initial_datagram : Intfn quic_now() -> Int64fn quic_pad_payload(payload : Bytes, min_size : Int) -> Bytesfn quic_pn_decode(largest_pn : Int64, truncated_pn : Int64, pn_nbits : Int) -> Int64fn quic_pn_encode(full_pn : Int64, largest_acked : Int64?) -> Bytesfn quic_pn_len(full_pn : Int64, largest_acked : Int64?) -> Intfn quic_protect_handshake(version : UInt, dcid : Bytes, scid : Bytes, packet_number : Int64, pn_length : Int, payload : Bytes, key : Bytes, iv : Bytes, hp : Bytes) -> Bytesfn quic_protect_initial(version : UInt, dcid : Bytes, scid : Bytes, token : Bytes, packet_number : Int64, pn_length : Int, payload : Bytes, key : Bytes, iv : Bytes, hp : Bytes) -> Bytesfn quic_protect_short(spin : Bool, key_phase : Bool, dcid : Bytes, packet_number : Int64, pn_length : Int, payload : Bytes, key : Bytes, iv : Bytes, hp : Bytes) -> Bytesfn quic_recv_handshake(packet : Bytes, keys : QuicPacketKeys) -> (Array[QuicFrame], Int64)? raise QuicPayloadErrorfn quic_recv_initial(packet : Bytes, keys : QuicPacketKeys) -> (Array[QuicFrame], Int64)? raise QuicPayloadErrorfn quic_recv_short(packet : Bytes, dcid_len : Int, keys : QuicPacketKeys) -> (Array[QuicFrame], Int64)? raise QuicPayloadErrorfn quic_retry_integrity_tag(retry_without_tag : Bytes, odcid : Bytes) -> Bytesfn quic_retry_verify(retry_packet : Bytes, odcid : Bytes) -> Boolfn quic_send_handshake(version : UInt, dcid : Bytes, scid : Bytes, packet_number : Int64, pn_length : Int, frames : Array[QuicFrame], keys : QuicPacketKeys) -> Bytesfn quic_send_initial(version : UInt, dcid : Bytes, scid : Bytes, token : Bytes, packet_number : Int64, pn_length : Int, frames : Array[QuicFrame], keys : QuicPacketKeys) -> Bytesfn quic_send_short(spin : Bool, key_phase : Bool, dcid : Bytes, packet_number : Int64, pn_length : Int, frames : Array[QuicFrame], keys : QuicPacketKeys) -> Bytesasync fn quic_serve_endpoint(ep : QuicUdpEndpoint, server : QuicServer[Addr], tick_ms? : Int) -> Unitfn quic_server_initial_secret(dcid : Bytes) -> Bytesfn quic_unprotect_initial(packet : Bytes, pn_offset : Int, key : Bytes, iv : Bytes, hp : Bytes) -> (Bytes, Int64)?fn quic_unprotect_short(packet : Bytes, dcid_len : Int, key : Bytes, iv : Bytes, hp : Bytes) -> (Bytes, Int64)?fn quic_varint_decode(b : BytesView) -> (UInt64, Int)?fn quic_varint_encode(v : UInt64) -> Bytesfn recv_stream_next(state : RecvStreamState, event : RecvStreamEvent) -> RecvStreamState raise StreamStateErrorasync fn reload_watch(path : String, on_reload : async () -> Unit) -> Unitfn send_stream_next(state : SendStreamState, event : SendStreamEvent) -> SendStreamState raise StreamStateErrorasync fn serve_graceful(app : async (Scope, async () -> Event, async (Event) -> Unit) -> Unit, config : Config, handle? : ShutdownHandle) -> Unitfn stream_is_client_initiated(id : UInt64) -> Boolfn stream_is_locally_initiated(id : UInt64, is_server : Bool) -> Boolfn stream_is_writable(id : UInt64, is_server : Bool) -> Boolfn stream_sequence(id : UInt64) -> UInt64fn tls13_certificate_verify_check(key : EcdsaPublicKey, context : String, transcript_hash : Bytes, body : Bytes) -> Boolfn tls13_certificate_verify_content(context : String, transcript_hash : Bytes) -> Bytesfn tls13_certificate_verify_sign(key : EcdsaPrivateKey, context : String, transcript_hash : Bytes) -> Bytesfn tls13_client_ap_traffic_secret(master_secret : Bytes, transcript_hash : Bytes) -> Bytesfn tls13_client_hs_traffic_secret(handshake_secret : Bytes, transcript_hash : Bytes) -> Byteslet tls13_cv_context_client : Stringlet tls13_cv_context_server : Stringfn tls13_derive_secret(secret : Bytes, label : Bytes, transcript_hash : Bytes) -> Bytesfn tls13_early_secret(psk : Bytes) -> Bytesfn tls13_ecdhe_handshake_traffic_secret(private_key : Bytes, peer_public : Bytes, transcript_hash : Bytes, is_client : Bool) -> Bytesfn tls13_ecdhe_secrets_from_client_hello(client_hello : Bytes, server_private : Bytes, transcript_hash : Bytes) -> (Bytes, Bytes)?fn tls13_ecdhe_shared(private_key : Bytes, peer_public : Bytes) -> Bytesfn tls13_finished_key(base_key : Bytes) -> Bytesfn tls13_finished_verify(base_key : Bytes, transcript_hash : Bytes, verify_data : Bytes) -> Boolfn tls13_finished_verify_data(base_key : Bytes, transcript_hash : Bytes) -> Bytesfn tls13_handshake_secret(early_secret : Bytes, ecdhe : Bytes) -> Bytesfn tls13_handshake_secret_from_ecdhe(private_key : Bytes, peer_public : Bytes) -> Byteslet tls13_hello_retry_random : Bytesfn tls13_master_secret(handshake_secret : Bytes) -> Bytesfn tls13_server_ap_traffic_secret(master_secret : Bytes, transcript_hash : Bytes) -> Bytesfn tls13_server_hello(random : Bytes, session_id : Bytes, cipher_suite : Int, extensions : Array[TlsExtension]) -> TlsServerHellofn tls13_server_hs_secret_from_client_hello(client_hello : Bytes, server_private : Bytes, transcript_hash : Bytes) -> Bytes?fn tls13_server_hs_traffic_secret(handshake_secret : Bytes, transcript_hash : Bytes) -> Bytesfn tls13_transcript_hash(messages : Bytes) -> Bytesfn tls13_x25519_public(private_key : Bytes) -> Byteslet tls_alert_access_denied : Intlet tls_alert_bad_certificate : Intlet tls_alert_bad_certificate_status_response : Intlet tls_alert_bad_record_mac : Intlet tls_alert_certificate_expired : Intlet tls_alert_certificate_required : Intlet tls_alert_certificate_revoked : Intlet tls_alert_certificate_unknown : Intlet tls_alert_close_notify : Intlet tls_alert_decode_error : Intlet tls_alert_decrypt_error : Intlet tls_alert_handshake_failure : Intlet tls_alert_illegal_parameter : Intlet tls_alert_inappropriate_fallback : Intlet tls_alert_insufficient_security : Intlet tls_alert_internal_error : Intlet tls_alert_level_fatal : Intlet tls_alert_level_warning : Intlet tls_alert_missing_extension : Intlet tls_alert_no_application_protocol : Intlet tls_alert_protocol_version : Intlet tls_alert_record_overflow : Intlet tls_alert_unexpected_message : Intlet tls_alert_unknown_ca : Intlet tls_alert_unknown_psk_identity : Intlet tls_alert_unrecognized_name : Intlet tls_alert_unsupported_certificate : Intlet tls_alert_unsupported_extension : Intlet tls_alert_user_canceled : Intlet tls_client_hello : Intfn tls_decode_key_share_entry(view : BytesView) -> (Int, Bytes, Int)?fn tls_decode_key_share_retry(view : BytesView) -> Int?fn tls_decode_key_share_server(view : BytesView) -> (Int, Bytes)?fn tls_decode_supported_versions_server(view : BytesView) -> Int?fn tls_encode_handshake(msg_type : Int, body : Bytes) -> Bytesfn tls_encode_key_share_entry(group : Int, key : Bytes) -> Bytesfn tls_encode_key_share_retry(group : Int) -> Bytesfn tls_encode_key_share_server(group : Int, key : Bytes) -> Bytesfn tls_encode_supported_versions_server(version : Int) -> Byteslet tls_ext_alpn : Intlet tls_ext_key_share : Intlet tls_ext_quic_transport_params : Intlet tls_ext_signature_algorithms : Intlet tls_ext_supported_groups : Intlet tls_ext_supported_versions : Intlet tls_legacy_version : Intfn tls_parse_handshake(b : BytesView) -> (Int, Bytes)?let tls_record_application_data : Intlet tls_record_ccs : Byteslet tls_record_change_cipher_spec : Intlet tls_record_header_len : Intfn tls_record_inner(content_type : Int, content : Bytes, padding : Int) -> Byteslet tls_record_max_encrypted : Intlet tls_record_max_fragment : Intfn tls_record_nonce(iv : Bytes, seq : UInt64) -> Byteslet tls_server_hello : Intfn tls_server_send_flight(state : TlsServerState, request_client_cert : Bool) -> TlsServerState raise TlsAlertlet tls_sig_ecdsa_secp256r1_sha256 : Intlet tls_sig_rsa_pss_rsae_sha256 : Intlet tls_version_13 : Intlet tp_ack_delay_exponent : UInt64let tp_active_connection_id_limit : UInt64let tp_initial_max_data : UInt64let tp_initial_max_stream_data_bidi_local : UInt64let tp_initial_max_stream_data_bidi_remote : UInt64let tp_initial_max_stream_data_uni : UInt64let tp_initial_max_streams_bidi : UInt64let tp_initial_max_streams_uni : UInt64let tp_initial_source_connection_id : UInt64let tp_max_ack_delay : UInt64let tp_max_idle_timeout : UInt64let tp_max_udp_payload_size : UInt64fn websocket_accept_key(sec_websocket_key : String) -> Stringlet websocket_guid : Stringfn websocket_handshake_response(sec_websocket_key : String, subprotocol : String?, extra_headers : Array[(String, String)]) -> Bytesfn ws_close_payload(code : Int, reason : String) -> Byteslet ws_max_size : Intfn x25519(k : Bytes, u : Bytes) -> Bytesfn x25519_base() -> Bytesfn x509_alg_ec_public_key() -> Bytesfn x509_alg_ecdsa_sha256() -> Bytesfn x509_common_name(cn : String) -> Byteslet x509_eku_server_auth : Stringlet x509_oid_cn : Stringfn x509_self_signed(key : EcdsaPrivateKey, serial : Bytes, common_name : String, not_before : String, not_after : String) -> Bytesfn x509_tbs_certificate(serial : Bytes, common_name : String, not_before : String, not_after : String, pub_key : EcdsaPublicKey) -> Bytesfn x509_validity(not_before : String, not_after : String) -> BytesInstall
Download zipmooncat — a native ASGI 3.0 server for MoonBit (← uvicorn), built on moonbitlang/async and the moonasgi SEAM.
Dependencies