Skip to main content

mockforge_proxy/
client.rs

1//! HTTP client for proxy operations
2
3use mockforge_core::{Error, Result};
4use std::collections::HashMap;
5
6/// HTTP client for making proxy requests
7pub struct ProxyClient {
8    /// HTTP client instance
9    client: reqwest::Client,
10}
11
12impl ProxyClient {
13    /// Create a new proxy client
14    pub fn new() -> Self {
15        let client = reqwest::Client::new();
16        Self { client }
17    }
18
19    /// Build a client with the configured upstream timeout and redirect policy.
20    pub fn with_options(timeout_seconds: u64, follow_redirects: bool) -> Result<Self> {
21        let redirects = if follow_redirects {
22            reqwest::redirect::Policy::limited(10)
23        } else {
24            reqwest::redirect::Policy::none()
25        };
26        let client = reqwest::Client::builder()
27            .timeout(std::time::Duration::from_secs(timeout_seconds))
28            .redirect(redirects)
29            .build()
30            .map_err(|e| Error::internal(format!("Cannot configure proxy client: {e}")))?;
31        Ok(Self { client })
32    }
33
34    /// Send an HTTP request
35    pub async fn send_request(
36        &self,
37        method: reqwest::Method,
38        url: &str,
39        headers: &HashMap<String, String>,
40        body: Option<&[u8]>,
41    ) -> Result<reqwest::Response> {
42        let mut request = self.client.request(method, url);
43
44        // Add headers
45        for (key, value) in headers {
46            request = request.header(key, value);
47        }
48
49        // Add body if present
50        if let Some(body_data) = body {
51            request = request.body(body_data.to_vec());
52        }
53
54        request
55            .send()
56            .await
57            .map_err(|e| Error::internal(format!("Proxy request failed: {}", e)))
58    }
59}
60
61/// Response from a proxy request
62pub struct ProxyResponse {
63    /// HTTP status code
64    pub status_code: u16,
65    /// Response headers
66    pub headers: HashMap<String, String>,
67    /// Response body
68    pub body: Option<Vec<u8>>,
69}
70
71impl Default for ProxyClient {
72    fn default() -> Self {
73        Self::new()
74    }
75}