本文档解释了 Deno 中 HTTP 和 Fetch 功能的实现。它涵盖了服务器端 HTTP 服务功能和客户端 Fetch API。有关 WebSocket 实现的信息,请参阅 WebSocket Protocol。
Deno 提供了两个主要的 HTTP 通信接口
HTTP 服务器和客户端实现支持 HTTP/1.1 和 HTTP/2,而 Fetch API 提供了一个遵循 Web 标准的高级接口。
来源:ext/http/lib.rs144-241 ext/http/http_next.rs189-298 ext/http/00_serve.ts1-112 ext/fetch/lib.rs143-169 ext/websocket/lib.rs903-935
来源:ext/http/lib.rs589-756 ext/http/http_next.rs124-298 ext/http/service.rs76-156 ext/http/request_body.rs1-200 ext/http/response_body.rs1-500
HTTP 服务器构建在 Hyper 库之上,并提供用于创建能够处理请求和发送响应的 HTTP 服务器的功能。
HttpConn 类代表旧版 API 中的 HTTP 连接,而新的 serve API 使用 InnerRequest 和直接的操作调用。
来源:ext/http/01_http.js71-197 ext/http/00_serve.ts164-286 ext/http/lib.rs589-756 ext/http/service.rs127-200
服务器端实现包含几个关键的资源类型
HttpConnResource:代表一个 HTTP 连接HttpStreamReadResource:代表 HTTP 流的读取部分HttpStreamWriteResource:代表 HTTP 流的写入部分HttpRequestReader:处理从 HTTP 请求读取数据HttpResponseWriter:处理向 HTTP 响应写入数据来源:ext/http/http_next.rs321-423 ext/http/00_serve.ts444-600 ext/http/service.rs185-300
HTTP 服务器支持多种响应体类型和压缩格式
| Body 类型 | 描述 |
|---|---|
| 静态字节 | 在一次请求中发送的固定大小缓冲区 |
| 流式传输 | 从资源进行基于块的流式传输 |
| 空 | 没有响应体内容 |
| 压缩 | 描述 |
|---|---|
| 无 | 不应用压缩 |
| GZip | GZip 压缩 |
| Brotli | Brotli 压缩 |
HTTP 系统会根据 Accept-Encoding 标头和内容类型自动应用压缩。
来源:ext/http/response_body.rs50-278 ext/http/http_next.rs576-666
Fetch API 提供了一个现代的 HTTP 请求接口,类似于 Web 的 Fetch API。
来源:ext/fetch/26_fetch.js121-259 ext/fetch/lib.rs508-684 ext/fetch/lib.rs290-331
来源: ext/fetch/26_fetch.js121-259 ext/fetch/lib.rs508-684 ext/fetch/lib.rs686-1015
Fetch 实现支持多种 URL 方案
| URL 方案 | 处理器 |
|---|---|
http:, https: | HTTP 客户端 |
file | 文件系统处理程序 |
data | Data URL 处理程序 |
blob | Blob 存储处理程序 |
Fetch API 根据 fetch 规范处理重定向。它支持三种重定向模式:
follow:自动跟随重定向(默认)error:重定向时拒绝manual:将重定向响应返回给调用者来源: ext/fetch/26_fetch.js223-349
HTTP 连接可以使用 WebSocket 协议升级为 WebSocket 连接。此集成涉及 HTTP 和 WebSocket 扩展之间的协调。
来源: ext/http/http_next.rs260-298 ext/http/00_serve.ts236-284 ext/websocket/lib.rs609-626 ext/websocket/lib.rs555-601
HTTP 系统小心管理资源,以防止泄漏并确保正确清理。
HttpConn 类维护一组托管资源。来源: ext/http/01_http.js81-85 ext/http/01_http.js166-175
HTTP 服务器支持基于内容协商的自动压缩。
| 压缩类型 | 实现 | 触发条件 |
|---|---|---|
| Brotli | BrotliEncoder | Accept-Encoding: br + 可压缩内容 |
| GZip | GzipEncoder | Accept-Encoding: gzip + 可压缩内容 |
| 无 | 直接流式传输 | 小内容或不可压缩类型 |
压缩决策流程
压缩在 http_response() 中应用,并为大型响应使用流式编码器以保持低内存使用量。
来源: ext/http/http_next.rs1183-1245 ext/http/compressible.rs1-100 ext/http/response_body.rs278-350
Deno 提供了两个 HTTP 服务器 API:现代的 Deno.serve() API 和旧版的 serveHttp() API。
现代 API (Deno.serve())
旧版 API (serveHttp())
现代 API 内部使用 op_http_serve,而旧版 API 使用 op_http_accept 和手动连接管理。
来源: ext/http/00_serve.ts680-900 ext/http/01_http.js98-164 ext/http/01_http.js398-401
Fetch API 允许从 JavaScript 代码发出 HTTP 请求。
来源: ext/fetch/26_fetch.js350-419
HTTP 系统包括基于 OpenTelemetry 的遥测,用于通过 OtelInfo 和 OtelCollectors 系统监控服务器性能。
| 指标 | 类型 | 描述 | 单元 |
|---|---|---|---|
http.server.request.duration | 直方图 | HTTP 服务器请求时长 | 秒 |
http.server.active_requests | UpDownCounter | 活动 HTTP 服务器请求数 | 请求 |
http.server.request.body.size | 直方图 | HTTP 服务器请求体大小 | 字节 |
http.server.response.body.size | 直方图 | HTTP 服务器响应体大小 | 字节 |
遥测收集流程
当 OTEL_GLOBALS 功能启用并且配置了指标时,将自动收集遥测数据。
来源: ext/http/lib.rs442-556 ext/http/service.rs250-300
HTTP 和 Fetch 功能作为 Deno 扩展实现。
deno_http:提供 HTTP 服务器功能。deno_fetch:提供 Fetch API 功能。deno_websocket:提供 WebSocket 功能。这些扩展公开了操作 (ops),允许 JavaScript 代码与 Rust 实现进行交互。
来源: ext/http/lib.rs139-236 ext/fetch/lib.rs136-162 ext/websocket/lib.rs903-935