mirror of
https://github.com/aramperes/nut-rs.git
synced 2025-09-10 05:44:03 -04:00
Bring Tokio side up to date
This commit is contained in:
parent
162c015680
commit
3b3f9278de
9 changed files with 461 additions and 62 deletions
110
rups/src/tokio/client.rs
Normal file
110
rups/src/tokio/client.rs
Normal file
|
@ -0,0 +1,110 @@
|
|||
use crate::tokio::stream::ConnectionStream;
|
||||
use crate::{Config, Error, Host, NutError, TcpHost};
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
/// An asynchronous NUT client, using Tokio.
|
||||
pub struct Client {
|
||||
/// The client configuration.
|
||||
config: Config,
|
||||
/// The client connection.
|
||||
pub(crate) stream: ConnectionStream,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Connects to a remote NUT server using a blocking connection.
|
||||
pub async fn new(config: &Config) -> crate::Result<Self> {
|
||||
match &config.host {
|
||||
Host::Tcp(host) => Self::new_tcp(config, host).await,
|
||||
}
|
||||
// TODO: Support Unix domain sockets
|
||||
}
|
||||
|
||||
/// Connects to a remote NUT server using a blocking TCP connection.
|
||||
async fn new_tcp(config: &Config, host: &TcpHost) -> crate::Result<Self> {
|
||||
let tcp_stream = TcpStream::connect(&host.addr).await?;
|
||||
let mut client = Client {
|
||||
config: config.clone(),
|
||||
stream: ConnectionStream::Tcp(tcp_stream).buffered(),
|
||||
};
|
||||
|
||||
client = client.enable_ssl().await?;
|
||||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
/// Authenticates to the given UPS device with the username and password set in the config.
|
||||
pub async fn login(&mut self, ups_name: String) -> crate::Result<()> {
|
||||
if let Some(auth) = self.config.auth.clone() {
|
||||
// Pass username and check for 'OK'
|
||||
self.set_username(auth.username).await?;
|
||||
|
||||
// Pass password and check for 'OK'
|
||||
if let Some(password) = auth.password {
|
||||
self.set_password(password).await?;
|
||||
}
|
||||
|
||||
// Submit login
|
||||
self.exec_login(ups_name).await
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async-ssl")]
|
||||
async fn enable_ssl(mut self) -> crate::Result<Self> {
|
||||
if self.config.ssl {
|
||||
self.exec_start_tls().await?;
|
||||
|
||||
// Initialize SSL configurations
|
||||
let mut ssl_config = rustls::ClientConfig::new();
|
||||
let dns_name: webpki::DNSName;
|
||||
|
||||
if self.config.ssl_insecure {
|
||||
ssl_config
|
||||
.dangerous()
|
||||
.set_certificate_verifier(std::sync::Arc::new(
|
||||
crate::ssl::InsecureCertificateValidator::new(&self.config),
|
||||
));
|
||||
|
||||
dns_name = webpki::DNSNameRef::try_from_ascii_str("www.google.com")
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
} else {
|
||||
// Try to get hostname as given (e.g. localhost can be used for strict SSL, but not 127.0.0.1)
|
||||
let hostname = self
|
||||
.config
|
||||
.host
|
||||
.hostname()
|
||||
.ok_or(Error::Nut(NutError::SslInvalidHostname))?;
|
||||
|
||||
dns_name = webpki::DNSNameRef::try_from_ascii_str(&hostname)
|
||||
.map_err(|_| Error::Nut(NutError::SslInvalidHostname))?
|
||||
.to_owned();
|
||||
|
||||
ssl_config
|
||||
.root_store
|
||||
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
};
|
||||
|
||||
let config = tokio_rustls::TlsConnector::from(std::sync::Arc::new(ssl_config));
|
||||
|
||||
// Un-buffer to get back underlying stream
|
||||
self.stream = self.stream.unbuffered();
|
||||
|
||||
// Upgrade to SSL
|
||||
self.stream = self
|
||||
.stream
|
||||
.upgrade_ssl_client(config, dns_name.as_ref())
|
||||
.await?;
|
||||
|
||||
// Re-buffer
|
||||
self.stream = self.stream.buffered();
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "async-ssl"))]
|
||||
async fn enable_ssl(self) -> crate::Result<Self> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue