wasi-hyperium 0.3.0

Hyperium for WASI Preview2 HTTP
Documentation
use std::task::Poll;

use bytes::Bytes;
use wasi::http::types;

use crate::{
    incoming::{IncomingHttpBody, IncomingState},
    poll::PollableRegistry,
    wasi::IncomingRequest,
    Error,
};

pub fn incoming_request<Registry>(
    request: types::IncomingRequest,
    registry: Registry,
) -> Result<http0::Request<IncomingHttpBody<Registry>>, Error>
where
    Registry: PollableRegistry,
{
    let req = IncomingRequest::new(request, registry)?;
    let uri = {
        let mut builder = http0::Uri::builder();
        if let Some(scheme) = req.scheme() {
            builder = builder.scheme(scheme);
        }
        if let Some(auth) = req.authority() {
            builder = builder.authority(auth)
        }
        if let Some(p_and_q) = req.path_with_query() {
            builder = builder.path_and_query(p_and_q);
        }
        builder.build()?
    };
    let mut builder = http0::Request::builder().method(req.method()).uri(uri);
    for (name, val) in req.headers() {
        builder = builder.header(name, val);
    }
    Ok(builder.body(req.into_body().into())?)
}

impl<Registry> http_body0::Body for IncomingHttpBody<Registry>
where
    Registry: PollableRegistry,
{
    type Data = Bytes;
    type Error = Error;

    fn poll_data(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
        let IncomingState::Body { .. } = &self.state else {
            return Poll::Ready(None);
        };
        self.poll_incoming_body(cx)
    }

    fn poll_trailers(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> Poll<Result<Option<http0::HeaderMap>, Self::Error>> {
        match self.poll_incoming_trailers(cx)? {
            Poll::Ready(Some(trailers)) => Poll::Ready(Ok(Some(trailers.try_into()?))),
            Poll::Ready(None) => Poll::Ready(Ok(None)),
            Poll::Pending => Poll::Pending,
        }
    }
}