使用 hyper 时如何直接控制 http body(大尺寸)?
How do I directly control the http body (big size) when using hyper?
目前,我们正在将用 c 编写的 API 网关引擎切换到 tokio、hyper、rustls of rust。
在分析hyper_rustls(tokio_rustls)提供的echo server example时,有部分不懂,求助。
(我正在努力参考的例子不多)
https://github.com/rustls/hyper-rustls/blob/main/examples/server.rs
这是我想到的流程:
当收到一个 POST 请求体大小较大时,读取所有 http body → 读取到 content-length 后,执行传递给 make_service_fn 的 future 代码(示例中的 echo 操作)。
但是,一旦收到请求,就会执行传递给 make_service_fn 的代码并向客户端发送响应,并且 tokio::io::AsyncRead 的 poll_read 函数trait 被执行了很多次。这是 运行。
问:make_fn_service 代码 运行 的确切时间是什么时候,这是我可以控制的吗?
问:使用hyper的时候,好像是存储在内存中积累的body。因此,如果主体尺寸非常大,我想将其下载到一个单独的文件中。有没有什么方法可以直接控制每次本体来的时候?
- 我可以使用 hyper::body::HttpBody 特性吗?
关于第一季度:
let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(echo)) });
您调用 make_fn_service
将异步函数转换为可以传递给 serve()
的函数。它有一个 &AddrStream
类型的参数,可以做各种花哨的事情,比如过滤和节流,但如果你不需要这些,只需用你的异步函数调用 service_fn
。
然后您的函数,示例中的 echo
,将根据客户端请求调用一次。
关于第二季度:
正文不在记忆中累积:
*response.body_mut() = req.into_body();
但是这些是 Body
类型,实现了 Stream<Item=Result<Bytes>>
,因为这些 Bytes
正文的块 request/response。
并且通过将一个 Stream
分配给另一个 Stream
,一个非常大的 ping 应该通过 echo
函数无痛地流式传输,一次一个块。
如果您想自己管理数据,您可以轮询流 (StreamExt::next()
) 并单独处理每一块正文。只是不要调用 Body::to_bytes()
或 Body::aggregate()
.
关于使用 HttpBody
特征:
当然你可以直接使用它,但这并不简单。我认为它通常是这样实现的,例如,您可以直接从请求中获取 JSON 对象,或者 XML 或 urlencoded 映射或任何 Content-Type 指示的对象,而无需执行中间操作字节数组和解析。
但正如您可能猜到的那样,在异步模式下处理巨大的 XML/JSON 有效载荷并不容易。如果你真的需要它,你可以更容易地驱动一个普通 Body
.
的字节块
目前,我们正在将用 c 编写的 API 网关引擎切换到 tokio、hyper、rustls of rust。
在分析hyper_rustls(tokio_rustls)提供的echo server example时,有部分不懂,求助。 (我正在努力参考的例子不多)
https://github.com/rustls/hyper-rustls/blob/main/examples/server.rs
这是我想到的流程: 当收到一个 POST 请求体大小较大时,读取所有 http body → 读取到 content-length 后,执行传递给 make_service_fn 的 future 代码(示例中的 echo 操作)。
但是,一旦收到请求,就会执行传递给 make_service_fn 的代码并向客户端发送响应,并且 tokio::io::AsyncRead 的 poll_read 函数trait 被执行了很多次。这是 运行。
问:make_fn_service 代码 运行 的确切时间是什么时候,这是我可以控制的吗?
问:使用hyper的时候,好像是存储在内存中积累的body。因此,如果主体尺寸非常大,我想将其下载到一个单独的文件中。有没有什么方法可以直接控制每次本体来的时候?
- 我可以使用 hyper::body::HttpBody 特性吗?
关于第一季度:
let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(echo)) });
您调用 make_fn_service
将异步函数转换为可以传递给 serve()
的函数。它有一个 &AddrStream
类型的参数,可以做各种花哨的事情,比如过滤和节流,但如果你不需要这些,只需用你的异步函数调用 service_fn
。
然后您的函数,示例中的 echo
,将根据客户端请求调用一次。
关于第二季度:
正文不在记忆中累积:
*response.body_mut() = req.into_body();
但是这些是 Body
类型,实现了 Stream<Item=Result<Bytes>>
,因为这些 Bytes
正文的块 request/response。
并且通过将一个 Stream
分配给另一个 Stream
,一个非常大的 ping 应该通过 echo
函数无痛地流式传输,一次一个块。
如果您想自己管理数据,您可以轮询流 (StreamExt::next()
) 并单独处理每一块正文。只是不要调用 Body::to_bytes()
或 Body::aggregate()
.
关于使用 HttpBody
特征:
当然你可以直接使用它,但这并不简单。我认为它通常是这样实现的,例如,您可以直接从请求中获取 JSON 对象,或者 XML 或 urlencoded 映射或任何 Content-Type 指示的对象,而无需执行中间操作字节数组和解析。
但正如您可能猜到的那样,在异步模式下处理巨大的 XML/JSON 有效载荷并不容易。如果你真的需要它,你可以更容易地驱动一个普通 Body
.