use crate::transport::post;
use origin_domain::{AppError, Result};
use tokio::io::{AsyncBufReadExt, AsyncWrite, AsyncWriteExt, BufReader};
const PING: &str = r#"{"jsonrpc":"2.0","id":0,"method":"ping","params":{}}"#;
pub async fn is_alive(url: &str, token: Option<&str>) -> bool {
match post(url, token, PING).await {
Ok(body) => serde_json::from_str::<serde_json::Value>(&body)
.map(|value| value.get("result").is_some())
.unwrap_or(false),
Err(_) => false,
}
}
pub async fn proxy_streams<R, W>(
input: BufReader<R>,
mut output: W,
url: &str,
token: Option<&str>,
) -> Result<()>
where
R: tokio::io::AsyncRead + Unpin,
W: AsyncWrite + Unpin,
{
tracing::info!(url, "proxying stdio to a running instance over http");
let mut lines = input.lines();
loop {
let line = match lines.next_line().await {
Ok(Some(line)) => line,
Ok(None) => break,
Err(error) => {
return Err(AppError::internal(format!("cannot read stdin: {error}")));
}
};
if line.trim().is_empty() {
continue;
}
let body = post(url, token, &line).await?;
if body.trim().is_empty() {
continue;
}
output
.write_all(body.as_bytes())
.await
.map_err(|error| AppError::internal(format!("cannot write stdout: {error}")))?;
output
.write_all(b"\n")
.await
.map_err(|error| AppError::internal(format!("cannot write stdout: {error}")))?;
output
.flush()
.await
.map_err(|error| AppError::internal(format!("cannot flush stdout: {error}")))?;
}
Ok(())
}