1 use {
2 test_programs::p3::{
3 service::exports::wasi::http::handler::Guest as Handler,
4 wasi::http::{
5 client,
6 types::{ErrorCode, Fields, Request, Response, Scheme},
7 },
8 wit_future,
9 },
10 url::Url,
11 };
12
13 struct Component;
14
15 test_programs::p3::service::export!(Component);
16
17 impl Handler for Component {
18 // Forward the request body and trailers to a URL specified in a header.
handle(request: Request) -> Result<Response, ErrorCode>19 async fn handle(request: Request) -> Result<Response, ErrorCode> {
20 let headers = request.get_headers().copy_all();
21 Ok(
22 if let Some(url) = headers.iter().find_map(|(k, v)| {
23 (k == "url")
24 .then_some(v)
25 .and_then(|v| std::str::from_utf8(v).ok())
26 .and_then(|v| Url::parse(v).ok())
27 }) {
28 let method = request.get_method();
29 let (rx, trailers) = Request::consume_body(request, wit_future::new(|| Ok(())).1);
30 let outgoing_request = Request::new(Fields::new(), Some(rx), trailers, None).0;
31 outgoing_request.set_method(&method).unwrap();
32 outgoing_request
33 .set_path_with_query(Some(url.path()))
34 .unwrap();
35 outgoing_request
36 .set_scheme(Some(&match url.scheme() {
37 "http" => Scheme::Http,
38 "https" => Scheme::Https,
39 scheme => Scheme::Other(scheme.into()),
40 }))
41 .unwrap();
42 outgoing_request
43 .set_authority(Some(url.authority()))
44 .unwrap();
45 client::send(outgoing_request).await?
46 } else {
47 bad_request()
48 },
49 )
50 }
51 }
52
bad_request() -> Response53 fn bad_request() -> Response {
54 respond(400)
55 }
56
respond(status: u16) -> Response57 fn respond(status: u16) -> Response {
58 let response = Response::new(Fields::new(), None, wit_future::new(|| Ok(None)).1).0;
59 response.set_status_code(status).unwrap();
60 response
61 }
62
63 // Unused function; required since this file is built as a `bin`:
main()64 fn main() {}
65