Config loader

This commit is contained in:
LittleSheep 2024-01-13 14:46:26 +08:00
parent bf7004c89c
commit 5de1d13907
9 changed files with 182 additions and 27 deletions

55
Cargo.lock generated
View File

@ -216,7 +216,7 @@ dependencies = [
"rust-ini",
"serde",
"serde_json",
"toml",
"toml 0.5.11",
"yaml-rust",
]
@ -1128,12 +1128,11 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro-crate"
version = "2.0.1"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a"
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
dependencies = [
"toml_datetime",
"toml_edit",
"toml_edit 0.20.2",
]
[[package]]
@ -1246,11 +1245,14 @@ name = "roadsign"
version = "0.1.0"
dependencies = [
"config",
"lazy_static",
"poem",
"poem-openapi",
"serde",
"serde_json",
"tokio",
"toml 0.8.8",
"tracing",
"tracing-subscriber",
]
@ -1352,6 +1354,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -1629,10 +1640,25 @@ dependencies = [
]
[[package]]
name = "toml_datetime"
version = "0.6.3"
name = "toml"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.21.0",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
@ -1645,6 +1671,19 @@ dependencies = [
"winnow",
]
[[package]]
name = "toml_edit"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "tracing"
version = "0.1.40"

View File

@ -7,9 +7,12 @@ edition = "2021"
[dependencies]
config = { version = "0.13.4", features = ["toml"] }
lazy_static = "1.4.0"
poem = { version = "2.0.0", features = ["tokio-metrics"] }
poem-openapi = "4.0.0"
serde = "1.0.195"
serde_json = "1.0.111"
tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros", "time"] }
toml = "0.8.8"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"

View File

@ -1,3 +1,5 @@
regions = "./regions"
[listen]
proxies = "0.0.0.0:80"
proxies_tls = "0.0.0.0:443"

9
regions/index.toml Normal file
View File

@ -0,0 +1,9 @@
id = "index"
[[locations]]
id = "root"
hosts = ["localhost"]
paths = ["/"]
[[locations.destinations]]
id = "example"
uri = "https://example.com"

View File

@ -1 +1,12 @@
use std::sync::RwLock;
use config::Config;
use lazy_static::lazy_static;
use crate::config::loader::load_settings;
pub mod loader;
lazy_static! {
pub static ref C: RwLock<Config> = RwLock::new(load_settings());
}

View File

@ -4,21 +4,35 @@ mod sideload;
use poem::{listener::TcpListener, Route, Server};
use poem_openapi::OpenApiService;
use tracing::{error, info, Level};
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
// Load settings
let settings = config::loader::load_settings();
println!(
"Will listen at {:?}",
settings.get_array("listen.proxies").unwrap()
);
// Setting up logging
if std::env::var_os("RUST_LOG").is_none() {
std::env::set_var("RUST_LOG", "poem=debug");
}
tracing_subscriber::fmt::init();
tracing_subscriber::fmt()
.with_max_level(Level::DEBUG)
.init();
// Prepare all the stuff
let mut instance = proxies::Instance::new();
info!("Loading proxy regions...");
match proxies::loader::scan_regions(
config::C
.read()
.unwrap()
.get_string("regions")
.unwrap_or("./regions".to_string()),
) {
Err(_) => error!("Loading proxy regions... failed"),
Ok((regions, count)) => {
instance.regions = regions;
info!(count, "Loading proxy regions... done")
}
};
// Proxies
@ -27,7 +41,9 @@ async fn main() -> Result<(), std::io::Error> {
.server("http://localhost:3000/cgi");
let sideload_server = Server::new(TcpListener::bind(
settings
config::C
.read()
.unwrap()
.get_string("listen.sideload")
.unwrap_or("0.0.0.0:81".to_string()),
))
@ -37,3 +53,5 @@ async fn main() -> Result<(), std::io::Error> {
Ok(())
}

View File

@ -1,22 +1,26 @@
use std::{collections::HashMap, time::Duration};
use std::collections::HashMap;
#[derive(Debug, Clone)]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Region {
id: String,
locations: Vec<Location>,
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Location {
id: String,
hosts: Vec<String>,
paths: Vec<String>,
headers: Vec<HashMap<String, String>>,
query_strings: Vec<HashMap<String, String>>,
destination: Vec<Destination>,
headers: Option<Vec<HashMap<String, String>>>,
query_strings: Option<Vec<HashMap<String, String>>>,
destinations: Vec<Destination>,
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Destination {
uri: Vec<String>,
timeout: Duration,
id: String,
uri: String,
timeout: Option<u32>,
}

53
src/proxies/loader.rs Normal file
View File

@ -0,0 +1,53 @@
use std::ffi::OsStr;
use std::fs::{self, DirEntry};
use std::io;
use tracing::warn;
use crate::proxies::config;
pub fn scan_regions(basepath: String) -> io::Result<(Vec<config::Region>, u32)> {
let mut count: u32 = 0;
let mut result = vec![];
for entry in fs::read_dir(basepath)? {
if let Ok(val) = load_region(entry.unwrap()) {
result.push(val);
count += 1;
};
}
Ok((result, count))
}
pub fn load_region(file: DirEntry) -> Result<config::Region, String> {
if file.path().extension().and_then(OsStr::to_str).unwrap() != "toml" {
return Err("File entry wasn't toml file".to_string());
}
let fp = file.path();
let content = match fs::read_to_string(fp.clone()) {
Ok(val) => val,
Err(err) => {
warn!(
err = format!("{:?}", err),
filepath = fp.clone().to_str(),
"An error occurred when loading region, skipped."
);
return Err("Failed to load file".to_string());
}
};
let data: config::Region = match toml::from_str(&content) {
Ok(val) => val,
Err(err) => {
warn!(
err = format!("{:?}", err),
filepath = fp.clone().to_str(),
"An error occurred when parsing region, skipped."
);
return Err("Failed to parse file".to_string());
}
};
Ok(data)
}

View File

@ -1 +1,17 @@
use serde::{Deserialize, Serialize};
use self::config::Region;
pub mod config;
pub mod loader;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Instance {
pub regions: Vec<Region>,
}
impl Instance {
pub fn new() -> Instance {
Instance { regions: vec![] }
}
}