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. 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 53 fn bad_request() -> Response { 54 respond(400) 55 } 56 57 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`: 64 fn main() {} 65