Kill reqwest — minimal HTTP client on raw hyper + tokio-rustls

New src/agent/api/http.rs: ~240 lines, supports GET/POST, JSON/form
bodies, SSE streaming via chunk(), TLS via rustls. No tracing dep.

Removes reqwest from the main crate and telegram channel crate.
Cargo.lock drops ~900 lines of transitive dependencies.

tracing now only pulled in by tui-markdown.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-07 12:50:40 -04:00
parent a421c3c9f3
commit 1cf4f504c0
9 changed files with 360 additions and 915 deletions

View file

@ -9,7 +9,6 @@ capnp-rpc = "0.25"
dirs = "6"
futures = "0.3"
poc-memory = { path = "../.." }
reqwest = { version = "0.13", default-features = false, features = ["json", "form", "rustls"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }

View file

@ -64,7 +64,7 @@ struct State {
/// Telegram API offset
last_offset: i64,
connected: bool,
client: reqwest::Client,
client: poc_memory::agent::api::http::HttpClient,
/// Registered notification callbacks
subscribers: Vec<channel_client::Client>,
}
@ -79,7 +79,7 @@ impl State {
channel_logs: std::collections::BTreeMap::new(),
last_offset,
connected: false,
client: reqwest::Client::new(),
client: poc_memory::agent::api::http::HttpClient::new(),
subscribers: Vec::new(),
}
}
@ -172,9 +172,7 @@ async fn poll_once(state: &SharedState) -> Result<(), Box<dyn std::error::Error>
};
let client = state.borrow().client.clone();
let resp: serde_json::Value = client.get(&url)
.timeout(std::time::Duration::from_secs(35))
.send().await?.json().await?;
let resp: serde_json::Value = client.get(&url).await?.json().await?;
if !state.borrow().connected {
state.borrow_mut().connected = true;
@ -199,9 +197,10 @@ async fn poll_once(state: &SharedState) -> Result<(), Box<dyn std::error::Error>
let msg_chat_id = msg["chat"]["id"].as_i64().unwrap_or(0);
if msg_chat_id != chat_id {
let reject_url = format!("https://api.telegram.org/bot{token}/sendMessage");
let _ = client.post(&reject_url)
.form(&[("chat_id", msg_chat_id.to_string()), ("text", "This is a private bot.".to_string())])
.send().await;
let _ = client.post_form(&reject_url, &[
("chat_id", &msg_chat_id.to_string()),
("text", "This is a private bot."),
]).await;
continue;
}
@ -273,9 +272,10 @@ impl channel_server::Server for ChannelServerImpl {
let s = state.borrow();
(s.api_url("sendMessage"), s.client.clone(), s.config.chat_id)
};
let _ = client.post(&url)
.form(&[("chat_id", &chat_id.to_string()), ("text", &message)])
.send().await;
let _ = client.post_form(&url, &[
("chat_id", &chat_id.to_string()),
("text", &message),
]).await;
let ts = now() as u64;
append_history(&format!("{ts} [agent] {message}"));