✨ Config loader
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
38
src/main.rs
38
src/main.rs
@@ -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(())
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
53
src/proxies/loader.rs
Normal 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)
|
||||
}
|
@@ -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![] }
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user