scuffle_http/backend/h3/
utils.rs1use bytes::{Buf, Bytes};
2use h3::quic::SendStream;
3use h3::server::RequestStream;
4use http_body::Body;
5
6use crate::service::{HttpService, HttpServiceFactory};
7
8pub(crate) async fn copy_response_body<S, F>(
10 mut send: RequestStream<S, Bytes>,
11 body: <F::Service as HttpService>::ResBody,
12) -> Result<(), crate::error::HttpError<F>>
13where
14 F: HttpServiceFactory,
15 F::Error: std::error::Error,
16 <F::Service as HttpService>::Error: std::error::Error,
17 S: SendStream<Bytes>,
18 <F::Service as HttpService>::ResBody: http_body::Body,
19 <<F::Service as HttpService>::ResBody as http_body::Body>::Error: std::error::Error,
20{
21 let mut body = std::pin::pin!(body);
22
23 while let Some(frame) = std::future::poll_fn(|cx| body.as_mut().poll_frame(cx)).await {
24 match frame
25 .map_err(crate::error::HttpError::ResBodyError)?
26 .into_data()
27 .map_err(|f| f.into_trailers())
28 {
29 Ok(mut data) => send.send_data(data.copy_to_bytes(data.remaining())).await?,
30 Err(Ok(trailers)) => {
31 send.send_trailers(trailers).await?;
32 return Ok(());
33 }
34 Err(Err(_)) => continue,
35 }
36 }
37
38 send.finish().await?;
39
40 Ok(())
41}