keyforkd: let server be runnable by other programs

This commit is contained in:
Ryan Heywood 2023-09-07 08:36:14 -05:00
parent a7feed1bcc
commit d20d9d965d
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
2 changed files with 71 additions and 62 deletions

70
keyforkd/src/lib.rs Normal file
View File

@ -0,0 +1,70 @@
use std::{collections::HashMap, path::PathBuf};
use keyfork_mnemonic_util::Mnemonic;
use tower::ServiceBuilder;
#[cfg(feature = "tracing")]
use tracing::debug;
mod error;
mod middleware;
mod server;
mod service;
use error::KeyforkdError;
use server::UnixServer;
use service::Keyforkd;
pub async fn start_and_run_server(mnemonic: Mnemonic) -> Result<(), Box<dyn std::error::Error>> {
let service = ServiceBuilder::new()
.layer(middleware::SerdeLayer::new())
.service(Keyforkd::new(mnemonic));
let runtime_vars = std::env::vars()
.filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str()))
.collect::<HashMap<String, String>>();
let mut runtime_path: PathBuf;
#[allow(clippy::single_match_else)]
match runtime_vars.get("KEYFORKD_SOCKET_PATH") {
Some(occupied) => {
runtime_path = PathBuf::from(occupied);
}
None => {
runtime_path = PathBuf::from(
runtime_vars
.get("XDG_RUNTIME_DIR")
.ok_or(KeyforkdError::NoSocketPath)?,
);
runtime_path.push("keyforkd");
#[cfg(feature = "tracing")]
debug!("ensuring directory exists: {}", runtime_path.display());
if !runtime_path.is_dir() {
tokio::fs::create_dir(&runtime_path).await?;
}
runtime_path.push("keyforkd.sock");
}
}
#[cfg(feature = "tracing")]
debug!(
"binding UNIX socket in runtime dir: {}",
runtime_path.display()
);
let mut server = match UnixServer::bind(&runtime_path) {
Ok(s) => s,
Err(e) => {
#[cfg(feature = "tracing")]
debug!(%e, "Encountered error attempting to bind socket: {}", runtime_path.display());
return Err(e.into());
}
};
match server.run(service).await {
Ok(_) => (),
Err(e) => {
#[cfg(feature = "tracing")]
debug!(%e, "Encountered error while running");
}
}
Ok(())
}

View File

@ -1,9 +1,6 @@
use std::{collections::HashMap, path::PathBuf};
use keyfork_mnemonic_util::Mnemonic;
use tokio::io::{self, AsyncBufReadExt, BufReader};
use tower::ServiceBuilder;
#[cfg(feature = "tracing")]
use tracing::debug;
@ -15,14 +12,6 @@ use tracing_subscriber::{
registry,
};
mod error;
mod server;
mod service;
mod middleware;
use error::KeyforkdError;
use server::UnixServer;
use service::Keyforkd;
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
async fn load_mnemonic() -> Result<Mnemonic> {
@ -54,55 +43,5 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
debug!("reading mnemonic from standard input");
let mnemonic = load_mnemonic().await?;
let service = ServiceBuilder::new()
.layer(middleware::SerdeLayer::new())
.service(Keyforkd::new(mnemonic));
let runtime_vars = std::env::vars()
.filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str()))
.collect::<HashMap<String, String>>();
let mut runtime_path: PathBuf;
#[allow(clippy::single_match_else)]
match runtime_vars.get("KEYFORKD_SOCKET_PATH") {
Some(occupied) => {
runtime_path = PathBuf::from(occupied);
}
None => {
runtime_path = PathBuf::from(
runtime_vars
.get("XDG_RUNTIME_DIR")
.ok_or(KeyforkdError::NoSocketPath)?,
);
runtime_path.push("keyforkd");
#[cfg(feature = "tracing")]
debug!("ensuring directory exists: {}", runtime_path.display());
if !runtime_path.is_dir() {
tokio::fs::create_dir(&runtime_path).await?;
}
runtime_path.push("keyforkd.sock");
}
}
#[cfg(feature = "tracing")]
debug!(
"binding UNIX socket in runtime dir: {}",
runtime_path.display()
);
let mut server = match UnixServer::bind(&runtime_path) {
Ok(s) => s,
Err(e) => {
#[cfg(feature = "tracing")]
debug!(%e, "Encountered error attempting to bind socket: {}", runtime_path.display());
return Err(e.into());
}
};
match server.run(service).await {
Ok(_) => (),
Err(e) => {
#[cfg(feature = "tracing")]
debug!(%e, "Encountered error while running");
}
}
Ok(())
keyforkd::start_and_run_server(mnemonic).await
}