wasi_hyperium/hyperium1/
incoming.rs1use 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}