use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio_rustls::rustls::{ client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}, ClientConfig, SignatureScheme, }; #[tokio::main] async fn main() -> Result<(), tokio_gemini::LibError> { let mut args = std::env::args(); let mut insecure = false; let mut url = "gemini://geminiprotocol.net/".to_owned(); if let Some(arg) = args.nth(1) { if arg == "-k" { insecure = true; if let Some(arg) = args.nth(2) { url = arg; } } else { url = arg; } } let client = if insecure { tokio_gemini::Client::from(get_insecure_config()) } else { tokio_gemini::Client::default() }; let mut resp = client.request(&url).await?; { let status_code = resp.status().status_code(); let status_num: u8 = status_code.into(); eprintln!("{} {:?}", status_num, status_code); } if resp.status().reply_type() == tokio_gemini::ReplyType::Success { let mime = resp.mime()?; eprintln!("Mime: {}", mime); let mut buf = [0u8, 128]; let body = resp.body(); if mime.type_() == mime::TEXT { loop { let n = body.read(&mut buf).await?; if n == 0 { break; } print!("{}", std::str::from_utf8(&buf[..n])?); } } else { eprintln!("Downloading into content.bin"); let mut f = tokio::fs::File::create("content.bin").await?; loop { let n = body.read(&mut buf).await?; if n == 0 { break; } f.write_all(&buf[..n]).await?; } } } else { eprintln!("Message: {}", resp.message()); } Ok(()) } fn get_insecure_config() -> ClientConfig { ClientConfig::builder() .dangerous() .with_custom_certificate_verifier(std::sync::Arc::new(NoCertVerification {})) .with_no_client_auth() } #[derive(Debug)] struct NoCertVerification; impl ServerCertVerifier for NoCertVerification { fn verify_server_cert( &self, end_entity: &tokio_rustls::rustls::pki_types::CertificateDer<'_>, intermediates: &[tokio_rustls::rustls::pki_types::CertificateDer<'_>], server_name: &tokio_rustls::rustls::pki_types::ServerName<'_>, ocsp_response: &[u8], now: tokio_rustls::rustls::pki_types::UnixTime, ) -> Result { Ok(ServerCertVerified::assertion()) } fn verify_tls12_signature( &self, message: &[u8], cert: &tokio_rustls::rustls::pki_types::CertificateDer<'_>, dss: &tokio_rustls::rustls::DigitallySignedStruct, ) -> Result { Ok(HandshakeSignatureValid::assertion()) } fn verify_tls13_signature( &self, message: &[u8], cert: &tokio_rustls::rustls::pki_types::CertificateDer<'_>, dss: &tokio_rustls::rustls::DigitallySignedStruct, ) -> Result { Ok(HandshakeSignatureValid::assertion()) } fn supported_verify_schemes(&self) -> Vec { vec![ SignatureScheme::ECDSA_NISTP256_SHA256, SignatureScheme::ECDSA_NISTP384_SHA384, SignatureScheme::ECDSA_NISTP521_SHA512, ] } }