diff --git a/src/client.rs b/src/client.rs index 02824c1..119fc87 100644 --- a/src/client.rs +++ b/src/client.rs @@ -60,15 +60,22 @@ impl Client { .as_ref(), move |result| match result { Ok(connection) => { - match Connection::from(network_address, connection, certificate) { + match Connection::new_for( + &connection, + certificate.as_ref(), + Some(&network_address), + ) { Ok(result) => request_async( result, uri.to_string(), match priority { - Some(priority) => priority, - None => Priority::DEFAULT, + Some(priority) => Some(priority), + None => Some(Priority::DEFAULT), + }, + match cancellable { + Some(ref cancellable) => Some(cancellable.clone()), + None => None::, }, - cancellable.unwrap(), // @TODO move |result| callback(result), ), Err(reason) => callback(Err(Error::Connection(reason))), @@ -83,30 +90,36 @@ impl Client { } } -// Private helpers - -fn request_async( +/// Make new request for constructed `Connection` +/// * callback with `Result`on success or `Error` on failure +pub fn request_async( connection: Connection, query: String, - priority: Priority, - cancellable: Cancellable, + priority: Option, + cancellable: Option, callback: impl Fn(Result) + 'static, ) { connection.stream().output_stream().write_bytes_async( &Bytes::from(format!("{query}\r\n").as_bytes()), - priority, - Some(&cancellable.clone()), + match priority { + Some(priority) => priority, + None => Priority::DEFAULT, + }, + match cancellable { + Some(ref cancellable) => Some(cancellable.clone()), + None => None::, + } + .as_ref(), move |result| match result { - Ok(_) => Response::from_request_async( - connection, - Some(priority), - Some(cancellable), - move |result| match result { - Ok(response) => callback(Ok(response)), - Err(reason) => callback(Err(Error::Response(reason))), - }, - ), - Err(reason) => callback(Err(Error::Write(reason))), + Ok(_) => { + Response::from_request_async(connection, priority, cancellable, move |result| { + callback(match result { + Ok(response) => Ok(response), + Err(reason) => Err(Error::Response(reason)), + }) + }) + } + Err(reason) => callback(Err(Error::OutputStream(reason))), }, ); } diff --git a/src/client/connection.rs b/src/client/connection.rs index a86a85b..1dede2a 100644 --- a/src/client/connection.rs +++ b/src/client/connection.rs @@ -19,10 +19,10 @@ impl Connection { // Constructors /// Create new `Self` - pub fn from( - network_address: NetworkAddress, // @TODO struct cert as sni - socket_connection: SocketConnection, - certificate: Option, + pub fn new_for( + socket_connection: &SocketConnection, + certificate: Option<&TlsCertificate>, + server_identity: Option<&NetworkAddress>, ) -> Result { if socket_connection.is_closed() { return Err(Error::SocketConnectionClosed); @@ -31,7 +31,7 @@ impl Connection { Ok(Self { socket_connection: socket_connection.clone(), tls_client_connection: match certificate { - Some(certificate) => match auth(network_address, socket_connection, certificate) { + Some(certificate) => match auth(socket_connection, certificate, server_identity) { Ok(tls_client_connection) => Some(tls_client_connection), Err(reason) => return Err(reason), }, @@ -53,19 +53,19 @@ impl Connection { // Tools pub fn auth( - server_identity: NetworkAddress, // @TODO impl IsA ? - socket_connection: SocketConnection, - certificate: TlsCertificate, + socket_connection: &SocketConnection, + certificate: &TlsCertificate, + server_identity: Option<&NetworkAddress>, ) -> Result { if socket_connection.is_closed() { return Err(Error::SocketConnectionClosed); } // https://geminiprotocol.net/docs/protocol-specification.gmi#the-use-of-tls - match TlsClientConnection::new(&socket_connection, Some(&server_identity)) { + match TlsClientConnection::new(socket_connection, server_identity) { Ok(tls_client_connection) => { // https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates - tls_client_connection.set_certificate(&certificate); + tls_client_connection.set_certificate(certificate); // @TODO handle exceptions // https://geminiprotocol.net/docs/protocol-specification.gmi#closing-connections diff --git a/src/client/error.rs b/src/client/error.rs index 65771c0..b6df128 100644 --- a/src/client/error.rs +++ b/src/client/error.rs @@ -6,9 +6,9 @@ pub enum Error { Connectable(String), Connection(crate::client::connection::Error), NetworkAddress(crate::gio::network_address::Error), + OutputStream(glib::Error), Request(glib::Error), Response(crate::client::response::Error), - Write(glib::Error), } impl Display for Error { @@ -26,15 +26,15 @@ impl Display for Error { Self::NetworkAddress(reason) => { write!(f, "Network address error: {reason}") } + Self::OutputStream(reason) => { + write!(f, "Output stream error: {reason}") + } Self::Request(reason) => { write!(f, "Request error: {reason}") } Self::Response(reason) => { write!(f, "Response error: {reason}") } - Self::Write(reason) => { - write!(f, "I/O Write error: {reason}") - } } } }