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 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 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 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 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 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); 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}