use std::{collections::HashMap, sync::Arc, time::Instant};
use crate::{FilterPipeline, HttpFilterContext, SubRequestResponseMode};
#[derive(Clone, Copy)]
pub(super) struct SubrequestRuntimeResources<'a> {
pub(super) client_addr: Option<std::net::IpAddr>,
pub(super) downstream_tls: bool,
pub(super) health_registry: Option<&'a praxis_core::health::HealthRegistry>,
pub(super) id_generator: &'a praxis_core::id::IdGenerator,
pub(super) kv_stores: Option<&'a praxis_core::kv::KvStoreRegistry>,
pub(super) session_stores: Option<&'a Arc<crate::SessionStoreRegistry>>,
pub(super) peer_identity: Option<&'a Arc<praxis_tls::TlsPeerIdentity>>,
pub(super) request_start: Instant,
pub(super) subrequest_client: Option<&'a praxis_core::subrequest::SubRequestClient>,
pub(super) time_source: &'a dyn praxis_core::time::TimeSource,
}
#[expect(clippy::too_many_lines, reason = "all fields must be initialized")]
pub(super) fn build_sub_filter_context<'a>(
pipeline: &'a FilterPipeline,
request: &'a crate::Request,
runtime: SubrequestRuntimeResources<'a>,
) -> HttpFilterContext<'a> {
HttpFilterContext {
grpc_completion: None,
buffered_request_body: None,
body_done_indices: Vec::new(),
branch_iterations: HashMap::new(),
client_addr: runtime.client_addr,
cluster: None,
current_filter_id: None,
downstream_tls: runtime.downstream_tls,
extensions: crate::extensions::RequestExtensions::default(),
executed_branch_filters: Vec::new(),
executed_filter_indices: Vec::new(),
extra_request_headers: Vec::new(),
filter_metadata: HashMap::new(),
filter_results: HashMap::new(),
filter_state: HashMap::new(),
health_registry: runtime.health_registry,
id_generator: runtime.id_generator,
kv_stores: runtime.kv_stores,
session_stores: runtime.session_stores,
metrics_route: None,
peer_identity: runtime.peer_identity.cloned(),
prior_pre_read_mutations: Vec::new(),
pre_read_mutations: Vec::new(),
request,
request_body_bytes: 0,
request_body_mode: pipeline.body_capabilities().request_body_mode,
request_headers_to_remove: Vec::new(),
request_headers_to_set: Vec::new(),
request_start: runtime.request_start,
response_body_bytes: 0,
response_body_mode: pipeline.body_capabilities().response_body_mode,
response_header: None,
response_headers_modified: false,
upstream_reached: false,
rewritten_path: None,
selected_endpoint_index: None,
attempted_endpoints: Vec::new(),
retry_policy: None,
route_retry_policy: None,
cluster_retry_state: None,
cluster_retry_state_released: false,
endpoint_reselector: None,
pinned_endpoint_address: None,
structured_metadata: HashMap::new(),
subrequest_client: runtime.subrequest_client,
subrequest_response_mode: SubRequestResponseMode::Buffered,
time_source: runtime.time_source,
upstream: None,
}
}