Skip to content

Commit

Permalink
make session resumption optional
Browse files Browse the repository at this point in the history
  • Loading branch information
yggverse committed Dec 1, 2024
1 parent 096bd1d commit 94d63bd
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
61 changes: 40 additions & 21 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ pub use error::Error;
use gio::{prelude::SocketClientExt, Cancellable, SocketClient, SocketProtocol, TlsCertificate};
use glib::{Priority, Uri};

// Defaults

pub const DEFAULT_TIMEOUT: u32 = 10;
pub const DEFAULT_SESSION_RESUMPTION: bool = false;

/// Main point where connect external crate
///
/// Provides high-level API for session-safe interaction with
/// [Gemini](https://geminiprotocol.net) socket server
pub struct Client {
is_session_resumption: bool,
pub socket: SocketClient,
}

Expand All @@ -39,7 +43,10 @@ impl Client {
socket.set_timeout(DEFAULT_TIMEOUT);

// Done
Self { socket }
Self {
is_session_resumption: DEFAULT_SESSION_RESUMPTION,
socket,
}
}

// Actions
Expand All @@ -60,29 +67,41 @@ impl Client {
// * [NetworkAddress](https://docs.gtk.org/gio/class.NetworkAddress.html) required for valid
// [SNI](https://geminiprotocol.net/docs/protocol-specification.gmi#server-name-indication)
match crate::gio::network_address::from_uri(&uri, crate::DEFAULT_PORT) {
Ok(network_address) => self.socket.connect_async(
&network_address.clone(),
Some(&cancellable.clone()),
move |result| match result {
Ok(socket_connection) => {
match Connection::new(socket_connection, certificate, Some(network_address))
{
Ok(connection) => connection.request_async(
uri.to_string(),
priority,
cancellable,
move |result| match result {
Ok(response) => callback(Ok(response)),
Ok(network_address) => {
self.socket
.connect_async(&network_address.clone(), Some(&cancellable.clone()), {
let is_session_resumption = self.is_session_resumption;
move |result| match result {
Ok(socket_connection) => {
match Connection::new(
socket_connection,
certificate,
Some(network_address),
is_session_resumption,
) {
Ok(connection) => connection.request_async(
uri.to_string(),
priority,
cancellable,
move |result| match result {
Ok(response) => callback(Ok(response)),
Err(e) => callback(Err(Error::Connection(e))),
},
),
Err(e) => callback(Err(Error::Connection(e))),
},
),
Err(e) => callback(Err(Error::Connection(e))),
}
}
Err(e) => callback(Err(Error::Connect(e))),
}
}
Err(e) => callback(Err(Error::Connect(e))),
},
),
})
}
Err(e) => callback(Err(Error::NetworkAddress(e))),
}
}

// Setters

pub fn set_session_resumption(&mut self, is_enabled: bool) {
self.is_session_resumption = is_enabled
}
}
5 changes: 4 additions & 1 deletion src/client/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ impl Connection {
socket_connection: SocketConnection,
certificate: Option<TlsCertificate>,
server_identity: Option<NetworkAddress>,
is_session_resumption: bool,
) -> Result<Self, Error> {
Ok(Self {
tls_client_connection: match new_tls_client_connection(
&socket_connection,
server_identity.as_ref(),
is_session_resumption,
) {
Ok(tls_client_connection) => {
if let Some(ref certificate) = certificate {
Expand Down Expand Up @@ -92,11 +94,12 @@ impl Connection {
pub fn new_tls_client_connection(
socket_connection: &SocketConnection,
server_identity: Option<&NetworkAddress>,
is_session_resumption: bool,
) -> Result<TlsClientConnection, Error> {
match TlsClientConnection::new(socket_connection, server_identity) {
Ok(tls_client_connection) => {
// Prevent session resumption (certificate change ability in runtime)
tls_client_connection.set_property("session-resumption-enabled", false);
tls_client_connection.set_property("session-resumption-enabled", is_session_resumption);

// @TODO handle
// https://geminiprotocol.net/docs/protocol-specification.gmi#closing-connections
Expand Down

0 comments on commit 94d63bd

Please sign in to comment.