Skip to main content

wasi_hyperium/hyperium1/
incoming.rs

1use std::task::{Context, Poll};
2
3use bytes::Bytes;
4use http_body1::Frame;
5
6use crate::{
7    incoming::{IncomingHttpBody, IncomingState},
8    poll::PollableRegistry,
9    wasi::{IncomingRequest, IncomingResponse},
10    Error,
11};
12
13pub fn incoming_request<Registry>(
14    request: IncomingRequest<Registry>,
15) -> Result<http1::Request<IncomingHttpBody<Registry>>, Error>
16where
17    Registry: PollableRegistry,
18{
19    let uri = {
20        let mut builder = http1::Uri::builder();
21        if let Some(scheme) = request.scheme() {
22            builder = builder.scheme(scheme);
23        }
24        if let Some(auth) = request.authority() {
25            builder = builder.authority(auth)
26        }
27        if let Some(p_and_q) = request.path_with_query() {
28            builder = builder.path_and_query(p_and_q);
29        }
30        builder.build()?
31    };
32    let mut builder = http1::Request::builder().method(request.method()).uri(uri);
33    for (name, val) in request.headers() {
34        builder = builder.header(name, val);
35    }
36    Ok(builder.body(request.into_body().into())?)
37}
38
39pub fn incoming_response<Registry>(
40    response: IncomingResponse<Registry>,
41) -> Result<http1::Response<IncomingHttpBody<Registry>>, Error>
42where
43    Registry: PollableRegistry,
44{
45    let mut builder = http1::Response::builder().status(response.status());
46    for (name, val) in response.headers() {
47        builder = builder.header(name, val);
48    }
49    Ok(builder.body(response.into_body().into())?)
50}
51
52impl<Registry> http_body1::Body for IncomingHttpBody<Registry>
53where
54    Registry: PollableRegistry,
55{
56    type Data = Bytes;
57    type Error = Error;
58
59    fn poll_frame(
60        mut self: std::pin::Pin<&mut Self>,
61        cx: &mut std::task::Context<'_>,
62    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
63        match &self.state {
64            IncomingState::Empty => Poll::Ready(None),
65            IncomingState::Body { .. } => match self.poll_incoming_body(cx)? {
66                Poll::Ready(Some(frame)) => Poll::Ready(Some(Ok(Frame::data(frame)))),
67                Poll::Ready(None) => self.poll_hyperium1_trailers(cx),
68                Poll::Pending => Poll::Pending,
69            },
70            IncomingState::Trailers(_) => self.poll_hyperium1_trailers(cx),
71        }
72    }
73}
74
75impl<Registry> IncomingHttpBody<Registry>
76where
77    Registry: PollableRegistry,
78{
79    #[allow(clippy::type_complexity)]
80    fn poll_hyperium1_trailers(
81        &mut self,
82        cx: &mut Context,
83    ) -> Poll<Option<Result<Frame<Bytes>, Error>>> {
84        match self.poll_incoming_trailers(cx)? {
85            Poll::Ready(Some(trailers)) => {
86                Poll::Ready(Some(Ok(Frame::trailers(trailers.try_into()?))))
87            }
88            Poll::Ready(None) => Poll::Ready(None),
89            Poll::Pending => Poll::Pending,
90        }
91    }
92}