# parlov-probe
HTTP probe execution for parlov. Sends requests, captures the full response surface with timing.
## trait
```rust
pub trait Probe: Send + Sync {
fn execute(&self, def: &ProbeDefinition)
-> impl Future<Output = Result<ProbeExchange, Error>> + Send;
}
```
One call, one HTTP interaction, one `ProbeExchange` (paired request + response). The caller drives batching and sample collection. Request context is preserved alongside the response for downstream differential analysis.
## use it
```rust
use parlov_probe::http::HttpProbe;
use parlov_probe::Probe;
use parlov_core::ProbeDefinition;
use http::{Method, HeaderMap};
let client = HttpProbe::new();
let exchange = client.execute(&ProbeDefinition {
url: "https://api.example.com/users/123".into(),
method: Method::GET,
headers: HeaderMap::new(),
body: None,
}).await?;
println!("status: {}", exchange.response.status);
println!("timing: {}ms", exchange.response.timing_ns / 1_000_000);
```
On native targets, `HttpProbe` uses `reqwest` with connection pooling. On `wasm32-unknown-unknown` (Cloudflare Workers), the same `HttpProbe` API routes through `worker::Fetch` from the Cloudflare Workers Rust SDK — the conversion preserves multi-valued headers (`Set-Cookie`, `WWW-Authenticate`, `Cache-Control`). Timing is measured via `std::time::Instant` around the request-to-response path. All headers from `ProbeDefinition` are forwarded — auth context is expressed as a plain `Authorization` header.
`HttpProbe` derives `Clone`. Cloning is `O(1)` — the inner client is `Arc`-backed — so a single configured instance can be shared across concurrent probe loops without re-initializing the connection pool. `HttpProbe::with_client(reqwest::Client)` accepts a caller-supplied client when non-default configuration is needed (custom redirect policy, pinned TLS roots, timeouts).
## custom probes
Implement `Probe` for custom execution strategies (e.g. HTTP/2 single-packet timing, mTLS client certs):
```rust
struct MyProbe { /* ... */ }
impl Probe for MyProbe {
fn execute(&self, def: &ProbeDefinition)
-> impl Future<Output = Result<ProbeExchange, Error>> + Send
{
async { todo!() }
}
}
```
## license
MIT OR Apache-2.0