Skip to main content

rama_http/layer/upgrade/http_proxy_connect/
response.rs

1use crate::{
2    Request, Response, StatusCode, layer::upgrade::UpgradeResponse,
3    service::web::response::IntoResponse as _,
4};
5use rama_core::{Service, extensions::Extensions, telemetry::tracing};
6use rama_net::{ConnectorTargetInputExt, Protocol, client::ConnectorTarget};
7
8#[derive(Debug, Clone, Default)]
9#[non_exhaustive]
10/// A default [`Service`] which responds on an http (proxy) connect with
11/// a default http response.
12///
13/// It can also be used for other HTTP connect purposes,
14/// but that is not what the service is intended for.
15pub struct DefaultHttpProxyConnectReplyService;
16
17impl DefaultHttpProxyConnectReplyService {
18    #[inline(always)]
19    #[must_use]
20    /// Create a new [`DefaultHttpProxyConnectReplyService`].
21    pub fn new() -> Self {
22        Self
23    }
24}
25
26impl<Body> Service<Request<Body>> for DefaultHttpProxyConnectReplyService
27where
28    Body: Send + 'static,
29{
30    type Output = UpgradeResponse<Request<Body>, Response>;
31    type Error = Response;
32
33    async fn serve(&self, req: Request<Body>) -> Result<Self::Output, Self::Error> {
34        let extensions = Extensions::new();
35
36        if let Some(authority) = req.connector_target_with_default_port(Protocol::HTTP_DEFAULT_PORT)
37        {
38            tracing::info!(
39                server.address = %authority.host,
40                server.port = authority.port,
41                "accept CONNECT: insert proxy (connector) target into extensions",
42            );
43            extensions.insert(ConnectorTarget(authority));
44        } else {
45            tracing::error!("http proxy, error extracting connector target");
46            return Err(StatusCode::BAD_REQUEST.into_response());
47        }
48
49        Ok(UpgradeResponse {
50            request: req,
51            response: StatusCode::OK.into_response(),
52            extensions,
53        })
54    }
55}