#httpconn —— 自研 HTTP/1.1 传输实现

    Transport trait 的真实实现:自己拨号(TCP / TLS / CONNECT 隧道)、自己写请求、自己读响应。 2026-09-30 起是 Client::new 的缺省传输——不传 transport~ 就是它 (旧栈 moonbitlang/async/http 已删除,设计与行为对照见 docs/18-httpconn-transport.md)。

    import { "q2316367743/moonhttp/httpconn", }

    #公开 API

    项说明
    HttpConnTransport::new(max_idle_per_host?, idle_timeout_ms?)创建传输实现,内置连接池(缺省每 host 留 4 条空闲、保活 30 秒);max_idle_per_host = 0 禁池(每请求一条连接)
    Transport 实现send(PreparedRequest) -> RawResponse:建连 → 写头写体(含上传进度回调)→ 等响应头 → 按分帧交出响应体流
    parse_target(url) -> Target把绝对 URL 切成拨号要的形状(scheme / use_tls / host / port / 请求目标);非 http(s) 抛 TransportError::Unsupported
    host_header(target)Host 头的值(默认端口按 RFC 9112 §7.2 省略)

    Target 的字段是 pub(all),但它是实现的内部形状,使用者一般不需要碰。

    #行为要点

    • 协议:HTTP/1.0 / 1.1(h2 等上游 ALPN);缓冲请求体一律 Content-Length(无体发 0), 流式请求体按 content_length 的有无定长或 chunked(docs/20,分帧头由栈接管)。
    • 连接池(docs/21,缺省开启):空闲连接按目标分桶复用,请求不发 Connection 头 (1.1 持久是默认);响应体读满才回池,取消 / 半途放弃一律关闭;坏连接自动换新连接重试一次; 禁池时恢复每请求一条连接、发 Connection: close。
    • 自定义方法:PROPFIND 等按原样落进请求行;token 校验在建连前 (拼不进请求行的方法不值得一次握手)。
    • 默认 User-Agent:用户没设时自动补 moonhttp/0.4.0(版本号与 moon.mod 一致); 显式设置的同名头永远优先。GitHub 等服务端会拒绝无 UA 的请求。
    • gzip 自持:请求没声明 Accept-Encoding 时由本实现声明 gzip 并在响应侧流式解压, 解压后摘掉 Content-Encoding / Content-Length(「谁解压谁声明」,见 docs/15-response-compression.md)。
    • 代理:http 与 https 目标都走 CONNECT 隧道,Proxy-Authorization 只落在 CONNECT 请求上;SOCKS5 在路线图上(连接层已留位),见 docs/09-proxy.md。
    • 取消 / 超时:整跳(建连、TLS / CONNECT 握手、写头写体、等响应头)包在取消作用域里、 受 timeout 约束;响应体阶段由 ResponseBody 按单次读取管,见 docs/12-cancellation.md。

    #用法

    // 缺省即自研栈:不传 transport~ 就是 HttpConnTransport

    ///|
    let client = @moonhttp.Client::new()

    ///|
    // 也可以显式注入(与自定义实现走同一入口)

    ///|
    let transport : &@transport.Transport = @httpconn.HttpConnTransport::new()

    ///|
    let explicit = @moonhttp.Client::new(transport~)

    HttpConnTransport

    pub struct HttpConnTransport {
    // private fields
    }

    自研 HTTP/1.x 传输实现。状态只有池:同一个实例派生的所有 Client(Client::create 共享 transport 引用)共享同一池。

    HttpConnTransport::new

    fn HttpConnTransport::new(max_idle_per_host? : Int, idle_timeout_ms? : Int) -> HttpConnTransport

    创建自研传输实现。

    • max_idle_per_host:每 host 的空闲连接上限,缺省 4; 传 0 禁用池(行为退回 phase 1:每请求一条连接 + Connection: close)。
    • idle_timeout_ms:空闲连接的保活时长,缺省 30 秒; 传非正数表示不过期(对端关闭由取用时的重试兜底)。

    Target

    pub(all) struct Target {
    scheme : String
    use_tls : Bool
    host : String
    port : Int
    target : String
    } derive(
    Debug
    )

    一个可以拨号的请求目标。

    Target::to_repr

    host_header

    fn host_header(target : Target) -> String

    Host 头的值:默认端口按 RFC 9112 §7.2 省略,非默认端口必须带上。

    parse_target

    解析绝对 URL。相对地址与非 http(s)/socks5 协议抛 Unsupported: 它们的共同点是「请求还没发出去就失败了」,正是这个分类的定义。

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io