Skip to main content

ohttp_gateway/
state.rs

1use crate::{
2    config::AppConfig,
3    key_manager::{CipherSuiteConfig, KeyManager, KeyManagerConfig},
4    metrics::AppMetrics,
5};
6use std::sync::Arc;
7
8#[derive(Clone)]
9pub struct AppState {
10    pub key_manager: Arc<KeyManager>,
11    pub http_client: reqwest::Client,
12    pub config: AppConfig,
13    pub metrics: AppMetrics,
14}
15
16impl AppState {
17    pub async fn new(config: AppConfig) -> Result<Self, Box<dyn std::error::Error>> {
18        // Configure key manager based on app config
19        let key_manager_config = KeyManagerConfig {
20            rotation_interval: config.key_rotation_interval,
21            key_retention_period: config.key_retention_period,
22            auto_rotation_enabled: config.key_rotation_enabled,
23            cipher_suites: get_cipher_suites(&config),
24        };
25
26        // Initialize key manager with or without seed
27        let key_manager = if let Some(seed_hex) = &config.seed_secret_key {
28            let seed = hex::decode(seed_hex)?;
29            Arc::new(KeyManager::new_with_seed(key_manager_config, seed).await?)
30        } else {
31            Arc::new(KeyManager::new(key_manager_config).await?)
32        };
33
34        // Create optimized HTTP client for backend requests
35        let http_client = create_http_client(&config)?;
36
37        let metrics = AppMetrics::default();
38
39        Ok(Self {
40            key_manager,
41            http_client,
42            config,
43            metrics,
44        })
45    }
46}
47
48fn get_cipher_suites(config: &AppConfig) -> Vec<CipherSuiteConfig> {
49    // Default cipher suites matching the Go implementation
50    let mut suites = vec![
51        CipherSuiteConfig {
52            kem: "X25519_SHA256".to_string(),
53            kdf: "HKDF_SHA256".to_string(),
54            aead: "AES_128_GCM".to_string(),
55        },
56        CipherSuiteConfig {
57            kem: "X25519_SHA256".to_string(),
58            kdf: "HKDF_SHA256".to_string(),
59            aead: "CHACHA20_POLY1305".to_string(),
60        },
61    ];
62
63    // Add high-security suite if in production mode
64    if !config.debug_mode {
65        suites.push(CipherSuiteConfig {
66            kem: "P256_SHA256".to_string(),
67            kdf: "HKDF_SHA256".to_string(),
68            aead: "AES_256_GCM".to_string(),
69        });
70    }
71
72    suites
73}
74
75fn create_http_client(config: &AppConfig) -> Result<reqwest::Client, Box<dyn std::error::Error>> {
76    let mut client_builder = reqwest::Client::builder()
77        .timeout(config.request_timeout)
78        .pool_max_idle_per_host(100)
79        .pool_idle_timeout(std::time::Duration::from_secs(30))
80        .tcp_keepalive(std::time::Duration::from_secs(60))
81        .tcp_nodelay(true)
82        .user_agent("ohttp-gateway/1.0")
83        .danger_accept_invalid_certs(config.debug_mode); // Only in debug mode
84
85    // Configure proxy if needed
86    if let Ok(proxy_url) = std::env::var("HTTP_PROXY") {
87        client_builder = client_builder.proxy(reqwest::Proxy::http(proxy_url)?);
88    }
89    if let Ok(proxy_url) = std::env::var("HTTPS_PROXY") {
90        client_builder = client_builder.proxy(reqwest::Proxy::https(proxy_url)?);
91    }
92
93    Ok(client_builder.build()?)
94}