Return a response which echoes the request headers, body, and trailers.
(request: Request)
| 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`: |
nothing calls this directly
no test coverage detected