diff --git a/Cargo.toml b/Cargo.toml index 801fb2e..442d0ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ggemini" -version = "0.20.1" +version = "0.18.0" edition = "2024" license = "MIT" readme = "README.md" @@ -11,10 +11,10 @@ repository = "https://github.com/YGGverse/ggemini" [dependencies.gio] package = "gio" -version = "0.21.0" +version = "0.20.9" features = ["v2_70"] [dependencies.glib] package = "glib" -version = "0.21.0" +version = "0.20.9" features = ["v2_66"] diff --git a/README.md b/README.md index 03c633e..d81850e 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,7 @@ fn main() -> ExitCode { }, Priority::DEFAULT, Cancellable::new(), - None, // optional auth `GTlsCertificate` - None, // optional TOFU `GTlsCertificate` array + None, // optional `GTlsCertificate` |result| match result { Ok((response, _connection)) => match response { Response::Success(success) => match success.mime().unwrap().as_str() { diff --git a/src/client.rs b/src/client.rs index 2152781..cff557e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -59,8 +59,7 @@ impl Client { request: Request, priority: Priority, cancellable: Cancellable, - client_certificate: Option, - server_certificates: Option>, + certificate: Option, callback: impl FnOnce(Result<(Response, Connection), Error>) + 'static, ) { // Begin new connection @@ -74,33 +73,30 @@ impl Client { move |result| match result { Ok(socket_connection) => { match Connection::build( - socket_connection.clone(), + socket_connection, network_address, - client_certificate, - server_certificates, + certificate, is_session_resumption, ) { - Ok(connection) => connection.clone().request_async( + Ok(connection) => connection.request_async( request, priority, cancellable, move |result| { callback(match result { Ok(response) => Ok(response), - Err(e) => Err(Error::Request(connection, e)), + Err(e) => Err(Error::Connection(e)), }) }, ), - Err(e) => { - callback(Err(Error::Connection(socket_connection, e))) - } + Err(e) => callback(Err(Error::Connection(e))), } } - Err(e) => callback(Err(Error::Connect(network_address, e))), + Err(e) => callback(Err(Error::Connect(e))), } }) } - Err(e) => callback(Err(Error::NetworkAddress(e))), + Err(e) => callback(Err(Error::Request(e))), } } diff --git a/src/client/connection.rs b/src/client/connection.rs index 6be90f1..d1cd849 100644 --- a/src/client/connection.rs +++ b/src/client/connection.rs @@ -6,16 +6,17 @@ pub use error::Error; pub use request::{Mode, Request}; pub use response::Response; +// Local dependencies + use gio::{ Cancellable, IOStream, NetworkAddress, SocketConnection, TlsCertificate, TlsClientConnection, - prelude::{IOStreamExt, OutputStreamExtManual, TlsCertificateExt, TlsConnectionExt}, + prelude::{IOStreamExt, OutputStreamExtManual, TlsConnectionExt}, }; use glib::{ Bytes, Priority, object::{Cast, ObjectExt}, }; -#[derive(Debug, Clone)] pub struct Connection { pub network_address: NetworkAddress, pub socket_connection: SocketConnection, @@ -29,19 +30,17 @@ impl Connection { pub fn build( socket_connection: SocketConnection, network_address: NetworkAddress, - client_certificate: Option, - server_certificates: Option>, + certificate: Option, is_session_resumption: bool, ) -> Result { Ok(Self { tls_client_connection: match new_tls_client_connection( &socket_connection, Some(&network_address), - server_certificates, is_session_resumption, ) { Ok(tls_client_connection) => { - if let Some(ref c) = client_certificate { + if let Some(ref c) = certificate { tls_client_connection.set_certificate(c); } tls_client_connection @@ -137,7 +136,6 @@ impl Connection { fn new_tls_client_connection( socket_connection: &SocketConnection, server_identity: Option<&NetworkAddress>, - server_certificates: Option>, is_session_resumption: bool, ) -> Result { match TlsClientConnection::new(socket_connection, server_identity) { @@ -151,19 +149,9 @@ fn new_tls_client_connection( // https://geminiprotocol.net/docs/protocol-specification.gmi#closing-connections tls_client_connection.set_require_close_notify(true); - // [TOFU](https://geminiprotocol.net/docs/protocol-specification.gmi#tls-server-certificate-validation) - tls_client_connection.connect_accept_certificate(move |_, c, _| { - server_certificates - .as_ref() - .is_none_or(|server_certificates| { - for server_certificate in server_certificates { - if server_certificate.is_same(c) { - return true; - } - } - false - }) - }); + // @TODO validate + // https://geminiprotocol.net/docs/protocol-specification.gmi#tls-server-certificate-validation + tls_client_connection.connect_accept_certificate(|_, _, _| true); Ok(tls_client_connection) } diff --git a/src/client/error.rs b/src/client/error.rs index 73031da..6083e77 100644 --- a/src/client/error.rs +++ b/src/client/error.rs @@ -2,29 +2,22 @@ use std::fmt::{Display, Formatter, Result}; #[derive(Debug)] pub enum Error { - Connect(gio::NetworkAddress, glib::Error), - Connection(gio::SocketConnection, crate::client::connection::Error), - NetworkAddress(crate::client::connection::request::Error), - Request( - crate::client::connection::Connection, - crate::client::connection::Error, - ), + Connect(glib::Error), + Connection(crate::client::connection::Error), + Request(crate::client::connection::request::Error), } impl Display for Error { fn fmt(&self, f: &mut Formatter) -> Result { match self { - Self::Connect(_, e) => { + Self::Connection(e) => { + write!(f, "Connection error: {e}") + } + Self::Connect(e) => { write!(f, "Connect error: {e}") } - Self::Connection(_, e) => { - write!(f, "Connection init error: {e}") - } - Self::NetworkAddress(e) => { - write!(f, "Network address error: {e}") - } - Self::Request(_, e) => { - write!(f, "Connection error: {e}") + Self::Request(e) => { + write!(f, "Request error: {e}") } } } diff --git a/src/gio/file_output_stream.rs b/src/gio/file_output_stream.rs index 2dffb5e..a8e5d70 100644 --- a/src/gio/file_output_stream.rs +++ b/src/gio/file_output_stream.rs @@ -33,13 +33,13 @@ pub fn from_stream_async( size.total += bytes.len(); on_chunk(bytes.clone(), size.total); - if let Some(limit) = size.limit - && size.total > limit - { - return on_complete(Err(Error::BytesTotal(size.total, limit))); + if let Some(limit) = size.limit { + if size.total > limit { + return on_complete(Err(Error::BytesTotal(size.total, limit))); + } } - if bytes.is_empty() { + if bytes.len() == 0 { return on_complete(Ok((file_output_stream, size.total))); } diff --git a/src/gio/file_output_stream/size.rs b/src/gio/file_output_stream/size.rs index 5d0c911..285d9f1 100644 --- a/src/gio/file_output_stream/size.rs +++ b/src/gio/file_output_stream/size.rs @@ -5,13 +5,3 @@ pub struct Size { pub limit: Option, pub total: usize, } - -impl Default for Size { - fn default() -> Self { - Self { - chunk: 0x10000, // 64KB - limit: None, - total: 0, - } - } -} diff --git a/src/gio/memory_input_stream/size.rs b/src/gio/memory_input_stream/size.rs index 9a10bd3..b95ef39 100644 --- a/src/gio/memory_input_stream/size.rs +++ b/src/gio/memory_input_stream/size.rs @@ -4,13 +4,3 @@ pub struct Size { pub limit: usize, pub total: usize, } - -impl Default for Size { - fn default() -> Self { - Self { - chunk: 0x10000, // 64KB - limit: 0xfffff, // 1 MB - total: 0, - } - } -}