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