1 use {
2     test_programs::p3::{
3         service::exports::wasi::http::handler::Guest as Handler,
4         wasi::http::types::{ErrorCode, Request, Response},
5         wit_future, wit_stream,
6     },
7     wit_bindgen::StreamResult,
8 };
9 
10 struct Component;
11 
12 test_programs::p3::service::export!(Component);
13 
14 impl Handler for Component {
15     /// Return a response which echoes the request headers, body, and trailers.
16     async fn handle(request: Request) -> Result<Response, ErrorCode> {
17         let headers = request.get_headers();
18         let (_, result_rx) = wit_future::new(|| Ok(()));
19         let (body, trailers) = Request::consume_body(request, result_rx);
20 
21         let (response, _result) = if headers
22             .get("x-host-to-host")
23             .into_iter()
24             .any(|v| v == b"true")
25         {
26             // This is the easy and efficient way to do it...
27             Response::new(headers, Some(body), trailers)
28         } else {
29             // ...but we do it the more difficult, less efficient way here to exercise various component model
30             // features (e.g. `future`s, `stream`s, and post-return asynchronous execution):
31             let (trailers_tx, trailers_rx) = wit_future::new(|| todo!());
32             let (mut pipe_tx, pipe_rx) = wit_stream::new();
33 
34             wit_bindgen::spawn(async move {
35                 let mut body_rx = body;
36                 let mut chunk = Vec::with_capacity(1024);
37                 loop {
38                     let (status, buf) = body_rx.read(chunk).await;
39                     chunk = buf;
40                     match status {
41                         StreamResult::Complete(_) => {
42                             chunk = pipe_tx.write_all(chunk).await;
43                             assert!(chunk.is_empty());
44                         }
45                         StreamResult::Dropped => break,
46                         StreamResult::Cancelled => unreachable!(),
47                     }
48                 }
49 
50                 drop(pipe_tx);
51 
52                 trailers_tx.write(trailers.await).await.unwrap();
53             });
54 
55             Response::new(headers, Some(pipe_rx), trailers_rx)
56         };
57 
58         Ok(response)
59     }
60 }
61 
62 // Unused function; required since this file is built as a `bin`:
63 fn main() {}
64