net.http 包
功能介绍
http 包提供 HTTP/1.1、HTTP/2 和 WebSocket 协议的 server、client 端实现。
关于协议的详细内容可参考 RFC 9110、9112、9113、9218、7541 等。
使用本包需要外部依赖 OpenSSL 3
的 ssl
和 crypto
动态库文件,故使用前需安装相关工具:
- 对于
Linux
操作系统,可参考以下方式:- 如果系统的包管理工具支持安装
OpenSSL 3
开发工具包,可通过这个方式安装,并确保系统安装目录下含有libssl.so
、libssl.so.3
、libcrypto.so
和libcrypto.so.3
这些动态库文件,例如Ubuntu 22.04
系统上可使用sudo apt install libssl-dev
命令安装libssl-dev
工具包; - 如果无法通过上面的方式安装,可自行下载
OpenSSL 3.x.x
源码编译安装软件包,并确保安装目录下含有libssl.so
、libssl.so.3
、libcrypto.so
和libcrypto.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.dll
、libcrypto.dll.a
(或libcrypto.lib
)、libcrypto-3-x64.dll
这些库文件; - 将
libssl.dll.a
(或libssl.lib
)、libcrypto.dll.a
(或libcrypto.lib
) 所在的目录路径设置到环境变量LIBRARY_PATH
中,将libssl-3-x64.dll
、libcrypto-3-x64.dll
所在的目录路径设置到环境变量PATH
中。
- 自行下载
- 对于
macOS
操作系统,可参考以下方式:- 使用
brew install openssl@3
安装,并确保系统安装目录下含有libcrypto.dylib
和libcrypto.3.dylib
这两个动态库文件; - 如果无法通过上面的方式安装,可自行下载
OpenSSL 3.x.x
源码编译安装软件包,并确保安装目录下含有libcrypto.dylib
和libcrypto.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 请求。 |
接口
接口名 | 功能 |
---|---|
CookieJar | Client 用来管理 Cookie 的工具。 |
HttpRequestDistributor | Http request 分发器接口,将一个 request 按照 url 中的 path 分发给对应的 HttpRequestHandler 处理。 |
HttpRequestHandler | Http request 处理器。 |
ProtocolServiceFactory | Http 服务实例工厂,用于生成 ProtocolService 实例。 |
类
类名 | 功能 |
---|---|
Client | Client 类,用户可以通过 Client 实例发送 HTTP/1.1 或 HTTP/2 请求。 |
ClientBuilder | 用于 Client 实例的构建,Client 没有公开的构造函数,用户只能通过 ClientBuilder 得到 Client 实例。ClientBuilder 文档中未明确说明支持版本的配置,在 HTTP/1.1 与 HTTP/2 都会生效。 |
Cookie | HTTP 本身是无状态的,server 为了知道 client 的状态,提供个性化的服务,便可以通过 Cookie 来维护一个有状态的会话。 |
FileHandler | 用于处理文件下载或者文件上传。 |
FuncHandler | HttpRequestHandler 接口包装类,把单个函数包装成 HttpRequestHandler。 |
HttpContext | Http 请求上下文,作为 HttpRequestHandler.handle 函数的参数在服务端使用。 |
HttpHeaders | 用于表示 Http 报文中的 header 和 trailer,定义了相关增、删、改、查操作。 |
HttpRequest | Http 请求类。 |
HttpRequestBuilder | HttpRequestBuilder 类用于构造 HttpRequest 实例。 |
HttpResponse | Http 响应类。 |
HttpResponseBuilder | 用于构造 HttpResponse 实例。 |
HttpResponsePusher | HTTP/2 服务器推送。 |
HttpResponseWriter | HTTP response消息体 Writer,支持用户控制消息体的发送过程。 |
NotFoundHandler | 便捷的 Http 请求处理器,404 Not Found 处理器。 |
OptionsHandler | 便捷的 Http 处理器,用于处理 OPTIONS 请求。固定返回 "Allow: OPTIONS,GET,HEAD,POST,PUT,DELETE" 响应头。 |
ProtocolService | Http协议服务实例,为单个客户端连接提供 Http 服务,包括对客户端 request 报文的解析、 request 的分发处理、 response 的发送等。 |
RedirectHandler | 便捷的 Http 处理器,用于回复重定向响应。 |
Server | 提供 HTTP 服务的 Server 类。 |
ServerBuilder | 提供 Server 实例构建器。 |
WebSocket | 提供 WebSocket 服务的相关类,提供 WebSocket 连接的读、写、关闭等函数。用户通过 upgradeFrom 函数以获取 WebSocket 连接。 |
WebSocketFrame | WebSocket 用于读的基本单元。 |
枚举
枚举名 | 功能 |
---|---|
FileHandlerType | 用于设置 FileHandler 是上传还是下载模式。 |
Protocol | 定义 HTTP 协议类型枚举。 |
WebSocketFrameType | 定义 WebSocketFrame 的枚举类型。 |
结构体
结构体名 | 功能 |
---|---|
HttpStatusCode | 用来表示网页服务器超文本传输协议响应状态的 3 位数字代码。 |
ServicePoolConfig | Http Server 协程池配置。 |
TransportConfig | 传输层配置类,服务器建立连接使用的传输层配置。 |
异常类
异常类名 | 功能 |
---|---|
ConnectionException | Http 的tcp连接异常类。 |
CoroutinePoolRejectException | Http 的协程池拒绝请求处理异常类。 |
HttpException | Http 的通用异常类。 |
HttpStatusException | Http 的响应状态异常类。 |
HttpTimeoutException | Http 的超时异常类。 |
WebSocketException | WebSocket 的通用异常类。 |