use std::process;
use argh::FromArgs;
use fetch::HttpClient;
use fetch::tls::{ClientIdentity, TlsOptions};
use fetch::tokio::TokioDeps;
use serde_json::Value;
use tracing::info;
#[path = "util/utils.rs"]
mod utils;
#[derive(FromArgs)]
struct Args {
#[argh(option)]
cert: String,
#[argh(option)]
key: String,
#[argh(option)]
url: String,
}
#[tokio::main]
async fn main() -> Result<(), ohno::AppError> {
utils::init_tracing();
if std::env::args_os().nth(1).is_none() {
info!("No arguments provided; nothing to do. See the module docs for usage.");
return Ok(());
}
let args: Args = argh::from_env();
if !args.url.starts_with("https://") {
eprintln!("Error: --url must use the https:// scheme (got '{}')", args.url);
process::exit(2);
}
let identity = {
info!("Loading client certificate from: {}", args.cert);
info!("Loading client private key from: {}", args.key);
let cert_pem = std::fs::read(&args.cert).expect("failed to read certificate PEM file");
let key_pem = std::fs::read(&args.key).expect("failed to read private key PEM file");
ClientIdentity::from_pem(&cert_pem, &key_pem).expect("failed to parse PKCS#8 PEM identity")
};
info!("Client identity loaded successfully");
let client = HttpClient::builder_tokio(TokioDeps::default())
.tls_options(TlsOptions::builder().client_identity(identity).build())
.build();
info!("Sending GET request to {} ...", args.url);
let response = client.get(args.url.as_str()).fetch().await?;
info!("Response status: {}", response.status());
let body_text = response.into_body().into_text().await?;
let json: Value = serde_json::from_str(&body_text).expect("response is not valid JSON");
let pretty = serde_json::to_string_pretty(&json).expect("failed to pretty-print JSON");
println!("\n--- Response Body ---");
println!("{pretty}");
println!("--- End ---");
Ok(())
}