Skip to main content

HttpTransport

Trait HttpTransport 

Source
pub trait HttpTransport:
    Send
    + Sync
    + Debug {
    // Required method
    fn execute<'life0, 'async_trait>(
        &'life0 self,
        req: HttpRequest,
    ) -> Pin<Box<dyn Future<Output = Result<HttpResponse, HttpTransportError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             Self: 'async_trait;
}
Expand description

Performs outbound HTTP on PPE’s behalf.

Implemented by the host, never by this crate. A proxy implements it over its own client so PPE’s outbound calls share the process’s pool, TLS material, egress policy, and tracing. A WASM host implements it over host imports. Tests implement it over a canned table, which is how timeout and error mapping become assertable without socket timing.

§One instance, shared

An implementation is never cloned. The host constructs exactly one, hands it over as Arc<dyn HttpTransport>, and every holder downstream — the engine, each request’s Extensions, each plugin’s filtered view — carries a refcount bump on that same object. So the connection pool, the TLS material, and any circuit-breaker state are process-wide by construction rather than by discipline. That is the whole point: a second instance would be a second pool against the same IdP, which is what this seam exists to prevent.

The trait therefore does not require Clone, and an implementation holding a pool need not make one cheap to copy. It does need interior mutability and to be safe to call concurrently from many tasks, since one instance serves every request in the process.

§Retries

An implementation must not retry at the application level. Two of PPE’s three callers issue non-idempotent POSTs — a token exchange and a CIBA backchannel registration — where a blind repeat mints a second credential or asks a human to approve the same thing twice. The transport cannot know which requests are safe to repeat; the caller can, and owns the decision. See HttpTransportError::may_have_reached_peer.

One narrow exception is not an application retry and is expected: if a connection came from a keepalive pool and turned out to be closed before any request bytes were written, resending on a fresh connection is invisible to the peer and correct even for a POST. The distinction is whether the peer could have observed the request, never whether the failure looked transient.

§Runtime binding

An implementation must not bind pooled connections to whichever runtime happened to construct it. A host may build the transport during a short-lived initialization runtime that is dropped before the first request arrives, at which point connections created eagerly are already dead. Build pools lazily on first use.

Required Methods§

Source

fn execute<'life0, 'async_trait>( &'life0 self, req: HttpRequest, ) -> Pin<Box<dyn Future<Output = Result<HttpResponse, HttpTransportError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Perform one request and buffer the response.

§Errors

Returns HttpTransportError when no response was obtained. A response carrying any status, including 5xx, is Ok.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§