net.http 包

功能介绍

http 包提供 HTTP/1.1、HTTP/2 和 WebSocket 协议的 server、client 端实现。

关于协议的详细内容可参考 RFC 91109112911392187541 等。

使用本包需要外部依赖 OpenSSL 3sslcrypto 动态库文件,故使用前需安装相关工具:

  • 对于 Linux 操作系统,可参考以下方式:
    • 如果系统的包管理工具支持安装 OpenSSL 3 开发工具包,可通过这个方式安装,并确保系统安装目录下含有 libssl.solibssl.so.3libcrypto.solibcrypto.so.3 这些动态库文件,例如 Ubuntu 22.04 系统上可使用 sudo apt install libssl-dev 命令安装 libssl-dev 工具包;
    • 如果无法通过上面的方式安装,可自行下载 OpenSSL 3.x.x 源码编译安装软件包,并确保安装目录下含有 libssl.solibssl.so.3libcrypto.solibcrypto.so.3 这些动态库文件,然后可选择下面任意一种方式来保证系统链接器可以找到这些文件:
      • 在系统未安装 OpenSSL 的场景,安装时选择直接安装到系统路径下;
      • 安装在自定义目录的场景,将这些文件所在目录设置到环境变量 LD_LIBRARY_PATH 以及 LIBRARY_PATH 中。
  • 对于 Windows 操作系统,可按照以下步骤:
    • 自行下载 OpenSSL 3.x.x 源码编译安装 x64 架构软件包或者自行下载安装第三方预编译的供开发人员使用的 OpenSSL 3.x.x 软件包;
    • 确保安装目录下含有 libssl.dll.a(或 libssl.lib)、libssl-3-x64.dlllibcrypto.dll.a(或 libcrypto.lib)、libcrypto-3-x64.dll 这些库文件;
    • libssl.dll.a(或 libssl.lib)、libcrypto.dll.a(或 libcrypto.lib) 所在的目录路径设置到环境变量 LIBRARY_PATH 中,将 libssl-3-x64.dlllibcrypto-3-x64.dll 所在的目录路径设置到环境变量 PATH 中。
  • 对于 macOS 操作系统,可参考以下方式:
    • 使用 brew install openssl@3 安装,并确保系统安装目录下含有 libcrypto.dyliblibcrypto.3.dylib 这两个动态库文件;
    • 如果无法通过上面的方式安装,可自行下载 OpenSSL 3.x.x 源码编译安装软件包,并确保安装目录下含有 libcrypto.dyliblibcrypto.3.dylib 这两个动态库文件,然后可选择下面任意一种方式来保证系统链接器可以找到这些文件:
      • 在系统未安装 OpenSSL 的场景,安装时选择直接安装到系统路径下;
      • 安装在自定义目录的场景,将这些文件所在目录设置到环境变量 DYLD_LIBRARY_PATH 以及 LIBRARY_PATH 中。

如果未安装 OpenSSL 3软件包或者安装低版本的软件包,程序可能无法使用并抛出 TLS 相关异常。

http

用户可以选择 http 协议的版本,如 HTTP/1.1、HTTP/2。http 包的多数 API 并不区分这两种协议版本,只有当用户用到某个版本的特有功能时,才需要做这种区分,如 HTTP/1.1 中的 chunked 的 transfer-encoding,HTTP/2 中的 server push。

http 库默认使用 HTTP/1.1 版本。当开发者需要使用 HTTP/2 协议时,需要为 Client/Server 配置 tls,并且设置 alpn 的值为 h2;不支持 HTTP/1.1 通过 Upgrade: h2c 协议升级的方式升级到 HTTP/2。

如果创建 HTTP/2 连接握手失败,Client/Server 会自动将协议退回 HTTP/1.1。

  • 用户通过 ClientBuilder 构建一个 Client 实例,构建过程可以指定多个参数,如 httpProxy、logger、cookieJar、是否自动 redirect、连接池大小等。

  • 用户通过 ServerBuilder 构建一个 Server 实例,构建过程可以指定多个参数,如 addr、port、logger、distributor 等。

用户如果需要自己设置 Logger,需要保证它是线程安全的。

Client、Server 的大多数参数在构建后便不允许修改,如果想要更改,用户需要重新构建一个新的 Client 或 Server 实例;如果该参数支持动态修改,本实现会提供显式的功能,如 Server 端 cert、CA 的热更新。

  • 通过 Client 实例,用户可以发送 http request、接收 http response。

  • 通过 Server 实例,用户可以配置 request 转发处理器,启动 http server。在 server handler 中,用户可以通过 HttpContext 获取 client 发来的 request 的详细信息,构造发送给 client 的 response。 Server 端根据 Client 端请求,创建对应的 ProtocolService 实例,同一个 Server 实例可同时支持两种协议:HTTP/1.1、HTTP/2。

  • 在 client 端,用户通过 HttpRequestBuilder 构造 request,构建过程可以指定多个参数,如 method、url、version、headers、body、trailers 等等;构建之后的request 不允许再进行修改。

  • 在 server 端,用户通过 HttpResponseBuilder 构造 response,构建过程可以指定多个参数,如 status、headers、body、trailers 等等;构建之后的 response 不允许再进行修改。

另外,本实现提供一些工具类,方便用户构造一些常用 response,如 RedirectHandler 构造 redirect response,NotFoundHandler 构造 404 response。

WebSocket

本实现为 WebSocket 提供 sub-protocol 协商,包括基础的 frame 解码、读取、消息发送、frame 编码、ping、pong、关闭等功能。

用户通过 WebSocket.upgradeFromClient 从一个 HTTP/1.1 或 HTTP/2 Client 实例升级到 WebSocket 协议,之后通过返回的 WebSocket 实例进行 WebSocket 通讯。

用户在一个 server 端的 handler 中,通过 WebSocket.upgradeFromServer 从 HTTP/1.1 或 HTTP/2 协议升级到 WebSocket 协议,之后通过返回的 WebSocket 实例进行 WebSocket 通讯。

按照协议,HTTP/1.1 中,升级后的 WebSocket 连接是建立在 tcp/tls 连接之上;HTTP/2 中,升级后的 WebSocket 连接是建立在 HTTP/2 connection 的一个 stream 之上。HTTP/1.1 中,close 最终会直接关闭 tcp/tls 连接;HTTP/2 中,close 只会关闭 connection 上的一个 stream。

API 列表

函数

函数名功能
handleError(HttpContext, UInt16)便捷的 Http 请求处理函数,用于回复错误请求。
notFound(HttpContext)便捷的 Http 请求处理函数,用于回复 404 响应。
upgrade(HttpContext)在 handler 内获取 StreamingSocket,可用于支持协议升级和处理 CONNECT 请求。

接口

接口名功能
CookieJarClient 用来管理 Cookie 的工具。
HttpRequestDistributorHttp request 分发器接口,将一个 request 按照 url 中的 path 分发给对应的 HttpRequestHandler 处理。
HttpRequestHandlerHttp request 处理器。
ProtocolServiceFactoryHttp 服务实例工厂,用于生成 ProtocolService 实例。

类名功能
ClientClient 类,用户可以通过 Client 实例发送 HTTP/1.1 或 HTTP/2 请求。
ClientBuilder用于 Client 实例的构建,Client 没有公开的构造函数,用户只能通过 ClientBuilder 得到 Client 实例。ClientBuilder 文档中未明确说明支持版本的配置,在 HTTP/1.1 与 HTTP/2 都会生效。
CookieHTTP 本身是无状态的,server 为了知道 client 的状态,提供个性化的服务,便可以通过 Cookie 来维护一个有状态的会话。
FileHandler用于处理文件下载或者文件上传。
FuncHandlerHttpRequestHandler 接口包装类,把单个函数包装成 HttpRequestHandler。
HttpContextHttp 请求上下文,作为 HttpRequestHandler.handle 函数的参数在服务端使用。
HttpHeaders用于表示 Http 报文中的 header 和 trailer,定义了相关增、删、改、查操作。
HttpRequestHttp 请求类。
HttpRequestBuilderHttpRequestBuilder 类用于构造 HttpRequest 实例。
HttpResponseHttp 响应类。
HttpResponseBuilder用于构造 HttpResponse 实例。
HttpResponsePusherHTTP/2 服务器推送。
HttpResponseWriterHTTP response消息体 Writer,支持用户控制消息体的发送过程。
NotFoundHandler便捷的 Http 请求处理器,404 Not Found 处理器。
OptionsHandler便捷的 Http 处理器,用于处理 OPTIONS 请求。固定返回 "Allow: OPTIONS,GET,HEAD,POST,PUT,DELETE" 响应头。
ProtocolServiceHttp协议服务实例,为单个客户端连接提供 Http 服务,包括对客户端 request 报文的解析、 request 的分发处理、 response 的发送等。
RedirectHandler便捷的 Http 处理器,用于回复重定向响应。
Server提供 HTTP 服务的 Server 类。
ServerBuilder提供 Server 实例构建器。
WebSocket提供 WebSocket 服务的相关类,提供 WebSocket 连接的读、写、关闭等函数。用户通过 upgradeFrom 函数以获取 WebSocket 连接。
WebSocketFrameWebSocket 用于读的基本单元。

枚举

枚举名功能
FileHandlerType用于设置 FileHandler 是上传还是下载模式。
Protocol定义 HTTP 协议类型枚举。
WebSocketFrameType定义 WebSocketFrame 的枚举类型。

结构体

结构体名功能
HttpStatusCode用来表示网页服务器超文本传输协议响应状态的 3 位数字代码。
ServicePoolConfigHttp Server 协程池配置。
TransportConfig传输层配置类,服务器建立连接使用的传输层配置。

异常类

异常类名功能
ConnectionExceptionHttp 的tcp连接异常类。
CoroutinePoolRejectExceptionHttp 的协程池拒绝请求处理异常类。
HttpExceptionHttp 的通用异常类。
HttpStatusExceptionHttp 的响应状态异常类。
HttpTimeoutExceptionHttp 的超时异常类。
WebSocketExceptionWebSocket 的通用异常类。