pub struct SubRequestClient { /* private fields */ }Expand description
Hardened sub-request executor wrapping a shared connector.
Provides a safe, bounded execution API that enforces:
- An overall deadline covering admission, connect, and I/O.
- Bounded response body reads: each call supplies a per-call limit, clamped to the client-wide ceiling set at
construction via
with_max_response_bytes. The server derives this ceiling frombody_limits.max_response_bytes. - Hop-by-hop header sanitization on both request and response.
- Proper
Hostframing.
Callers own routing, retries, circuit breaking, SSRF policy, depth propagation, and status interpretation.
Supports both buffered (execute()) and streaming
(send_streaming()) response modes.
use praxis_core::subrequest::{SubRequestClient, SubRequestConnector};
let connector = SubRequestConnector::new(128, None);
let client = SubRequestClient::new(connector);Implementations§
Source§impl SubRequestClient
impl SubRequestClient
Sourcepub fn new(connector: SubRequestConnector) -> Self
pub fn new(connector: SubRequestConnector) -> Self
Create a client wrapping the given shared connector.
Defaults the client-wide response ceiling to
ABSOLUTE_MAX_BODY_BYTES (64 MiB). Use
with_max_response_bytes for a tighter cap.
Sourcepub fn with_max_response_bytes(
connector: SubRequestConnector,
max_response_bytes: usize,
) -> Self
pub fn with_max_response_bytes( connector: SubRequestConnector, max_response_bytes: usize, ) -> Self
Create a client with an explicit response ceiling.
Every execute() call clamps its per-call limit to
min(per_call, ceiling), preventing callers from
exceeding the global cap.
Sourcepub fn connector(&self) -> &SubRequestConnector
pub fn connector(&self) -> &SubRequestConnector
Access the underlying connector for direct pool operations.
Sourcepub fn evict_idle_circuits(&self, idle_threshold: Duration) -> usize
pub fn evict_idle_circuits(&self, idle_threshold: Duration) -> usize
Evict idle circuit breaker entries that have been healthy for
at least idle_threshold. Returns the number of entries
removed, or 0 if no circuit breaker is configured.
Sourcepub async fn send_streaming(
&self,
peer: &HttpPeer,
request: &SubRequest,
timeout: Duration,
limits: StreamLimits,
framework_headers: Option<&FrameworkHeaders>,
) -> Result<StreamingSubResponse, SubRequestError>
pub async fn send_streaming( &self, peer: &HttpPeer, request: &SubRequest, timeout: Duration, limits: StreamLimits, framework_headers: Option<&FrameworkHeaders>, ) -> Result<StreamingSubResponse, SubRequestError>
Send a streaming sub-request.
Acquires admission, connects to peer, sends request, reads
response headers, and returns a StreamingSubResponse with
an opaque body handle for incremental chunk reads.
Circuit breaker success is finalized only when the header exchange completes cleanly (header-only response or a streaming body); a header-incomplete or H2-error termination records a failure. Late body failures only affect stream metrics.
Timeout semantics: timeout bounds only the header phase
(connect + send + receive headers). Body reads are governed by
StreamLimits: idle_timeout per chunk, optional
max_stream_duration for end-to-end lifetime, and the peer’s
configured read_timeout. Callers needing a single end-to-end
deadline should set max_stream_duration accordingly.
§Errors
Returns SubRequestError on admission timeout, connection
failure, I/O error, or deadline expiry during the header phase.
Sourcepub async fn execute(
&self,
peer: &HttpPeer,
request: &SubRequest,
max_response_bytes: usize,
timeout: Duration,
framework_headers: Option<&FrameworkHeaders>,
) -> Result<SubResponse, SubRequestError>
pub async fn execute( &self, peer: &HttpPeer, request: &SubRequest, max_response_bytes: usize, timeout: Duration, framework_headers: Option<&FrameworkHeaders>, ) -> Result<SubResponse, SubRequestError>
Execute a buffered sub-request.
Acquires an admission permit (inside the deadline), connects
to peer, sends request, reads the full response (bounded
by max_response_bytes), and returns a SubResponse.
Transport-level headers (hop-by-hop, Connection-nominated)
and reserved internal headers (x-praxis-*, x-ext-*) are
stripped from both request and response.
framework_headers are injected after all sanitisation
passes. The FrameworkHeaders type validates at insertion
time that no transport-level or reserved internal header
(x-praxis-*, x-ext-*) can be added, so callers cannot
reintroduce sanitised headers.
§Errors
Returns SubRequestError on admission timeout, connection
failure, I/O error, response body exceeding the size limit,
or deadline expiry.
Trait Implementations§
Source§impl Clone for SubRequestClient
impl Clone for SubRequestClient
Source§fn clone(&self) -> SubRequestClient
fn clone(&self) -> SubRequestClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more