spin_trigger_http/
outbound_http.rs1use std::{
2 net::{IpAddr, Ipv4Addr, SocketAddr},
3 sync::Arc,
4};
5
6use http::uri::Scheme;
7use spin_core::async_trait;
8use spin_factor_outbound_http::intercept::{self, InterceptOutcome, InterceptRequest};
9use spin_factor_outbound_networking::parse_service_chaining_target;
10use spin_factors::RuntimeFactors;
11use spin_http::routes::RouteMatch;
12use wasmtime_wasi_http::{HttpError, HttpResult};
13
14use crate::HttpServer;
15
16pub struct OutboundHttpInterceptor<F: RuntimeFactors> {
18 server: Arc<HttpServer<F>>,
19}
20
21impl<F: RuntimeFactors> OutboundHttpInterceptor<F> {
22 pub fn new(server: Arc<HttpServer<F>>) -> Self {
23 Self { server }
24 }
25}
26
27const CHAINED_CLIENT_ADDR: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
28
29#[async_trait]
30impl<F: RuntimeFactors> intercept::OutboundHttpInterceptor for OutboundHttpInterceptor<F> {
31 async fn intercept(&self, request: InterceptRequest) -> HttpResult<InterceptOutcome> {
32 if let Some(component_id) = parse_service_chaining_target(request.uri()) {
34 let req = request.into_hyper_request();
35 let path = req.uri().path().to_owned();
36 let route_match = RouteMatch::synthetic(component_id, path);
37 let resp = self
38 .server
39 .handle_trigger_route(req, route_match, Scheme::HTTP, CHAINED_CLIENT_ADDR)
40 .await
41 .map_err(HttpError::trap)?;
42 Ok(InterceptOutcome::Complete(resp))
43 } else {
44 Ok(InterceptOutcome::Continue(request))
45 }
46 }
47}