Summary
ipfs_pin::cat (crates/gitlawb-node/src/ipfs_pin.rs) fetches blob content from the IPFS HTTP API with no bounded timeout, so an unresponsive or slow IPFS endpoint hangs the caller indefinitely:
pub async fn cat(ipfs_api: &str, cid: &str) -> Result<Vec<u8>> {
...
let resp = reqwest::Client::new().post(&url).send().await?;
...
Ok(resp.bytes().await?.to_vec())
}
The client is built with reqwest::Client::new() (no .timeout(..)), and neither send() nor bytes() is wrapped in tokio::time::timeout.
Impact
cat is on the request-serving and replication paths:
crates/gitlawb-node/src/api/encrypted.rs — get_encrypted_blob (B1 authenticated fetch)
crates/gitlawb-node/src/sync.rs — peer-mirror replication
A stalled IPFS daemon can therefore hang an HTTP handler or a sync worker rather than failing fast and retrying.
Suggested fix
Give the client a bounded timeout (e.g. reqwest::Client::builder().timeout(Duration::from_secs(30)).build()), or wrap the call in tokio::time::timeout. ~30s matches the per-gateway recovery timeout already used on the gl read path.
Notes
cat is new code in the encrypted-replication stack (introduced in 74b7a40, "authenticated discovery and fetch for encrypted blobs", part of #36 / issue #18). Surfaced by CodeRabbit during review of #40; filing here so it's tracked against the B1 fetch work rather than the recipient-set-blinding PR.
Summary
ipfs_pin::cat(crates/gitlawb-node/src/ipfs_pin.rs) fetches blob content from the IPFS HTTP API with no bounded timeout, so an unresponsive or slow IPFS endpoint hangs the caller indefinitely:The client is built with
reqwest::Client::new()(no.timeout(..)), and neithersend()norbytes()is wrapped intokio::time::timeout.Impact
catis on the request-serving and replication paths:crates/gitlawb-node/src/api/encrypted.rs—get_encrypted_blob(B1 authenticated fetch)crates/gitlawb-node/src/sync.rs— peer-mirror replicationA stalled IPFS daemon can therefore hang an HTTP handler or a sync worker rather than failing fast and retrying.
Suggested fix
Give the client a bounded timeout (e.g.
reqwest::Client::builder().timeout(Duration::from_secs(30)).build()), or wrap the call intokio::time::timeout. ~30s matches the per-gateway recovery timeout already used on theglread path.Notes
catis new code in the encrypted-replication stack (introduced in 74b7a40, "authenticated discovery and fetch for encrypted blobs", part of #36 / issue #18). Surfaced by CodeRabbit during review of #40; filing here so it's tracked against the B1 fetch work rather than the recipient-set-blinding PR.