make session resumption optional

This commit is contained in:
yggverse 2024-12-01 12:57:54 +02:00
parent 096bd1d862
commit 94d63bd6de
2 changed files with 44 additions and 22 deletions

View file

@ -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,
}
@ -39,7 +43,10 @@ impl Client {
socket.set_timeout(DEFAULT_TIMEOUT);
// Done
Self { socket }
Self {
is_session_resumption: DEFAULT_SESSION_RESUMPTION,
socket,
}
}
// Actions
@ -60,13 +67,18 @@ 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()),
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))
{
match Connection::new(
socket_connection,
certificate,
Some(network_address),
is_session_resumption,
) {
Ok(connection) => connection.request_async(
uri.to_string(),
priority,
@ -80,9 +92,16 @@ impl Client {
}
}
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
}
}

View file

@ -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 {
@ -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