add config file and data dirs with SSL keys
This commit is contained in:
parent
514dee438f
commit
1cf07a4f97
9 changed files with 255 additions and 39 deletions
135
Cargo.lock
generated
135
Cargo.lock
generated
|
@ -415,6 +415,15 @@ dependencies = [
|
||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
|
@ -560,7 +569,7 @@ dependencies = [
|
||||||
"pear",
|
"pear",
|
||||||
"serde",
|
"serde",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"toml",
|
"toml 0.8.23",
|
||||||
"uncased",
|
"uncased",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
@ -1168,12 +1177,16 @@ dependencies = [
|
||||||
"network-interface",
|
"network-interface",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
"ratatui-explorer",
|
"ratatui-explorer",
|
||||||
|
"rcgen",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"rustix 1.0.8",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha256",
|
"sha256",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-rustls",
|
||||||
|
"toml 0.9.5",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
"tui-input",
|
"tui-input",
|
||||||
"tui-logger",
|
"tui-logger",
|
||||||
|
@ -1381,6 +1394,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
|
@ -1513,6 +1532,16 @@ dependencies = [
|
||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pem"
|
||||||
|
version = "3.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
@ -1561,6 +1590,12 @@ dependencies = [
|
||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
|
@ -1668,6 +1703,19 @@ dependencies = [
|
||||||
"ratatui",
|
"ratatui",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rcgen"
|
||||||
|
version = "0.14.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0068c5b3cab1d4e271e0bb6539c87563c43411cad90b057b15c79958fbeb41f7"
|
||||||
|
dependencies = [
|
||||||
|
"pem",
|
||||||
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"time",
|
||||||
|
"yasna",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.17"
|
version = "0.5.17"
|
||||||
|
@ -1809,6 +1857,7 @@ version = "0.23.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc"
|
checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-webpki",
|
"rustls-webpki",
|
||||||
|
@ -1937,6 +1986,15 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -2173,6 +2231,25 @@ dependencies = [
|
||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"num-conv",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinystr"
|
name = "tinystr"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
@ -2252,11 +2329,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned 0.6.9",
|
||||||
"toml_datetime",
|
"toml_datetime 0.6.11",
|
||||||
"toml_edit",
|
"toml_edit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned 1.0.0",
|
||||||
|
"toml_datetime 0.7.0",
|
||||||
|
"toml_parser",
|
||||||
|
"toml_writer",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.11"
|
version = "0.6.11"
|
||||||
|
@ -2266,6 +2358,15 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.27"
|
version = "0.22.27"
|
||||||
|
@ -2274,18 +2375,33 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned 0.6.9",
|
||||||
"toml_datetime",
|
"toml_datetime 0.6.11",
|
||||||
"toml_write",
|
"toml_write",
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_parser"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10"
|
||||||
|
dependencies = [
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_write"
|
name = "toml_write"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_writer"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
@ -2865,6 +2981,15 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yasna"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
|
||||||
|
dependencies = [
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
|
@ -19,12 +19,16 @@ mime_guess = "2"
|
||||||
network-interface = { version = "2", features = ["serde"] }
|
network-interface = { version = "2", features = ["serde"] }
|
||||||
ratatui = "0.29"
|
ratatui = "0.29"
|
||||||
ratatui-explorer = "0.2"
|
ratatui-explorer = "0.2"
|
||||||
|
rcgen = "0.14.3"
|
||||||
reqwest = { version = "0.12", features = ["json"] }
|
reqwest = { version = "0.12", features = ["json"] }
|
||||||
|
rustix = { version = "1.0.8", default-features = false, features = ["system"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
sha256 = "1.6"
|
sha256 = "1.6"
|
||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
tokio = { version = "1", default-features = false, features = ["time", "macros", "rt-multi-thread"] }
|
tokio = { version = "1", default-features = false, features = ["time", "macros", "rt-multi-thread"] }
|
||||||
|
tokio-rustls = { version = "0.26.2", default-features = false, features = ["tls12", "logging"] }
|
||||||
|
toml = "0.9.5"
|
||||||
tower-http = { version = "0.6", features = ["limit"] }
|
tower-http = { version = "0.6", features = ["limit"] }
|
||||||
tui-input = "0.14"
|
tui-input = "0.14"
|
||||||
tui-logger = { version = "0.17", features = ["crossterm"] }
|
tui-logger = { version = "0.17", features = ["crossterm"] }
|
||||||
|
|
|
@ -68,7 +68,7 @@ static CONTENT_SEND_FILE_MENU: LazyLock<Line> = LazyLock::new(|| {
|
||||||
"<UP>".blue().bold(),
|
"<UP>".blue().bold(),
|
||||||
" Select Next ".into(),
|
" Select Next ".into(),
|
||||||
"<DOWN>".blue().bold(),
|
"<DOWN>".blue().bold(),
|
||||||
" Select ".into(),
|
" Send File ".into(),
|
||||||
"<ENTER>".blue().bold(),
|
"<ENTER>".blue().bold(),
|
||||||
" Parent Dir ".into(),
|
" Parent Dir ".into(),
|
||||||
"<LEFT>".blue().bold(),
|
"<LEFT>".blue().bold(),
|
||||||
|
@ -91,7 +91,7 @@ static CONTENT_SEND_PEERS_MENU: LazyLock<Line> = LazyLock::new(|| {
|
||||||
"<UP>".blue().bold(),
|
"<UP>".blue().bold(),
|
||||||
" Select Next ".into(),
|
" Select Next ".into(),
|
||||||
"<DOWN>".blue().bold(),
|
"<DOWN>".blue().bold(),
|
||||||
" Select ".into(),
|
" Send to Peer ".into(),
|
||||||
"<ENTER>".blue().bold(),
|
"<ENTER>".blue().bold(),
|
||||||
" Enter Text ".into(),
|
" Enter Text ".into(),
|
||||||
"<T>".blue().bold(),
|
"<T>".blue().bold(),
|
||||||
|
|
101
src/config.rs
Normal file
101
src/config.rs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
use std::{
|
||||||
|
net::{IpAddr, Ipv4Addr, SocketAddrV4},
|
||||||
|
os::unix::fs::PermissionsExt,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use figment::{
|
||||||
|
Figment,
|
||||||
|
providers::{Format, Serialized, Toml},
|
||||||
|
};
|
||||||
|
use local_ip_address::local_ip;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
DEFAULT_PORT, MULTICAST_IP,
|
||||||
|
error::{LocalSendError, Result},
|
||||||
|
models::Device,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
pub multicast_addr: SocketAddrV4,
|
||||||
|
pub download_dir: PathBuf,
|
||||||
|
pub data_dir: PathBuf,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub local_ip_addr: Ipv4Addr,
|
||||||
|
pub device: Device,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
let dirs = directories::BaseDirs::new().ok_or(LocalSendError::NoHomeDir)?;
|
||||||
|
|
||||||
|
let download_dir = dirs.home_dir().join("jocalsend-downloads");
|
||||||
|
let config_file = dirs.config_dir().join("jocalsend.toml");
|
||||||
|
let data_dir = dirs.data_local_dir().join("jocalsend");
|
||||||
|
|
||||||
|
let IpAddr::V4(local_ip_addr) = local_ip()? else {
|
||||||
|
return Err(LocalSendError::IPv6Unsupported);
|
||||||
|
};
|
||||||
|
|
||||||
|
let key = data_dir.join("key.pem");
|
||||||
|
let cert = data_dir.join("cert.pem");
|
||||||
|
let fingerprint = if data_dir.exists() {
|
||||||
|
if !(key.exists() && cert.exists()) {
|
||||||
|
gen_ssl(&key, &cert)?
|
||||||
|
} else {
|
||||||
|
let key = std::fs::read(key)?;
|
||||||
|
sha256::digest(key)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::fs::create_dir_all(data_dir.as_path())?;
|
||||||
|
gen_ssl(&key, &cert)?
|
||||||
|
};
|
||||||
|
|
||||||
|
let config = Self {
|
||||||
|
multicast_addr: SocketAddrV4::new(MULTICAST_IP, DEFAULT_PORT),
|
||||||
|
download_dir,
|
||||||
|
local_ip_addr,
|
||||||
|
data_dir,
|
||||||
|
device: Device {
|
||||||
|
alias: rustix::system::uname()
|
||||||
|
.nodename()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
fingerprint,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let config = if !config_file.exists() {
|
||||||
|
log::info!("creating config file at {config_file:?}");
|
||||||
|
std::fs::write(&config_file, toml::to_string(&config)?)?;
|
||||||
|
config
|
||||||
|
} else {
|
||||||
|
log::info!("reading config from {config_file:?}");
|
||||||
|
Figment::from(Serialized::defaults(config))
|
||||||
|
.merge(Toml::file(config_file))
|
||||||
|
.extract()
|
||||||
|
.map_err(Box::new)? // boxed because the error size from figment is large
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ssl(&self) -> (PathBuf, PathBuf) {
|
||||||
|
let key = self.data_dir.join("jocalsend").join("key.pem");
|
||||||
|
let cert = self.data_dir.join("jocalsend").join("cert.pem");
|
||||||
|
(key, cert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_ssl(key: &Path, cert: &Path) -> Result<String> {
|
||||||
|
let cert_key = rcgen::generate_simple_self_signed(vec!["*".into()])?;
|
||||||
|
let cert_text = cert_key.cert.pem();
|
||||||
|
let key_text = cert_key.signing_key.serialize_pem();
|
||||||
|
std::fs::write(key, key_text.clone())?;
|
||||||
|
std::fs::set_permissions(key, std::fs::Permissions::from_mode(0o400u32))?;
|
||||||
|
std::fs::write(cert, cert_text)?;
|
||||||
|
Ok(sha256::digest(key_text))
|
||||||
|
}
|
12
src/error.rs
12
src/error.rs
|
@ -50,6 +50,18 @@ pub enum LocalSendError {
|
||||||
|
|
||||||
#[error("Error getting network interface")]
|
#[error("Error getting network interface")]
|
||||||
NetworkInterfaceError(#[from] network_interface::Error),
|
NetworkInterfaceError(#[from] network_interface::Error),
|
||||||
|
|
||||||
|
#[error("Error: could not get $HOME value")]
|
||||||
|
NoHomeDir,
|
||||||
|
|
||||||
|
#[error("Could not generate SSL certs")]
|
||||||
|
SslGenFail(#[from] rcgen::Error),
|
||||||
|
|
||||||
|
#[error("Could not serialize config")]
|
||||||
|
ConfigSerializationFail(#[from] toml::ser::Error),
|
||||||
|
|
||||||
|
#[error("Could not parse config file")]
|
||||||
|
ConfigParseError(#[from] Box<figment::Error>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, LocalSendError>;
|
pub type Result<T> = std::result::Result<T, LocalSendError>;
|
||||||
|
|
|
@ -18,7 +18,7 @@ impl JocalService {
|
||||||
pub async fn start_http_server(&self, stop_rx: mpsc::Receiver<()>) -> crate::error::Result<()> {
|
pub async fn start_http_server(&self, stop_rx: mpsc::Receiver<()>) -> crate::error::Result<()> {
|
||||||
let app = self.create_router();
|
let app = self.create_router();
|
||||||
// TODO: make addr config
|
// TODO: make addr config
|
||||||
let addr = SocketAddr::from(([0, 0, 0, 0], self.config.port));
|
let addr = SocketAddr::from(([0, 0, 0, 0], self.config.device.port));
|
||||||
let listener = TcpListener::bind(&addr).await?;
|
let listener = TcpListener::bind(&addr).await?;
|
||||||
|
|
||||||
axum::serve(
|
axum::serve(
|
||||||
|
|
32
src/lib.rs
32
src/lib.rs
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod config;
|
||||||
pub mod discovery;
|
pub mod discovery;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod http_server;
|
pub mod http_server;
|
||||||
|
@ -7,16 +8,14 @@ pub mod transfer;
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4},
|
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
|
||||||
sync::{Arc, OnceLock},
|
sync::{Arc, OnceLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use error::LocalSendError;
|
pub use config::Config;
|
||||||
use julid::Julid;
|
use julid::Julid;
|
||||||
use local_ip_address::local_ip;
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use models::{Device, FileMetadata};
|
use models::{Device, FileMetadata};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use tokio::{
|
use tokio::{
|
||||||
net::UdpSocket,
|
net::UdpSocket,
|
||||||
sync::{
|
sync::{
|
||||||
|
@ -191,28 +190,3 @@ impl Default for RunningState {
|
||||||
Self::Running
|
Self::Running
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct Config {
|
|
||||||
pub multicast_addr: SocketAddrV4,
|
|
||||||
pub port: u16,
|
|
||||||
pub download_dir: String,
|
|
||||||
pub local_ip_addr: Ipv4Addr,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
pub fn new() -> error::Result<Self> {
|
|
||||||
let home = std::env::home_dir().unwrap_or("/tmp".into());
|
|
||||||
let dd = home.join("jocalsend-downloads");
|
|
||||||
let IpAddr::V4(local_ip_addr) = local_ip()? else {
|
|
||||||
return Err(LocalSendError::IPv6Unsupported);
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
multicast_addr: SocketAddrV4::new(MULTICAST_IP, DEFAULT_PORT),
|
|
||||||
port: DEFAULT_PORT,
|
|
||||||
download_dir: dd.to_string_lossy().into(),
|
|
||||||
local_ip_addr,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ impl Default for Device {
|
||||||
device_model: None,
|
device_model: None,
|
||||||
device_type: Some(DeviceType::Headless),
|
device_type: Some(DeviceType::Headless),
|
||||||
fingerprint: Julid::new().to_string(),
|
fingerprint: Julid::new().to_string(),
|
||||||
port: 53317,
|
port: crate::DEFAULT_PORT,
|
||||||
protocol: "http".to_string(),
|
protocol: "http".to_string(),
|
||||||
download: false,
|
download: false,
|
||||||
announce: Some(true),
|
announce: Some(true),
|
||||||
|
|
|
@ -350,7 +350,7 @@ pub async fn receive_upload(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create file path
|
// Create file path
|
||||||
let file_path = format!("{}/{}", download_dir, file_metadata.file_name);
|
let file_path = service.config.download_dir.join(&file_metadata.file_name);
|
||||||
|
|
||||||
// Write file
|
// Write file
|
||||||
if let Err(e) = tokio::fs::write(&file_path, body).await {
|
if let Err(e) = tokio::fs::write(&file_path, body).await {
|
||||||
|
|
Loading…
Reference in a new issue