This commit is contained in:
parent
5a63563982
commit
000598d95b
6 changed files with 27 additions and 54 deletions
27
Caddyfile
27
Caddyfile
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
auto_https off
|
|
||||||
|
|
||||||
admin unix//test
|
|
||||||
}
|
|
||||||
|
|
||||||
:80 {
|
|
||||||
handle_path /_sscdc/* {
|
|
||||||
reverse_proxy unix//some/socket
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
http://moritzruth.de {
|
|
||||||
handle_path /_sscdc/* {
|
|
||||||
reverse_proxy unix//some/socket
|
|
||||||
}
|
|
||||||
|
|
||||||
handle {
|
|
||||||
redir /kontakt /contact permanent
|
|
||||||
header /assets/* Cache-Control "public, max-age=604800, immutable"
|
|
||||||
root * /home/moritz/dev/moritzruth/sscdc/run/sites/moritzruth.de
|
|
||||||
try_files {path} {path}/index.html /index.html
|
|
||||||
file_server {
|
|
||||||
precompressed br gzip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::sites::SitesWorker;
|
use crate::sites::SitesWorker;
|
||||||
|
use async_std::task::JoinHandle;
|
||||||
|
use async_std::{fs, task};
|
||||||
use camino::Utf8Path;
|
use camino::Utf8Path;
|
||||||
use color_eyre::eyre::{WrapErr, eyre};
|
use color_eyre::eyre::{WrapErr, eyre};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use async_std::{fs, task};
|
|
||||||
use async_std::task::JoinHandle;
|
|
||||||
use tide::{Request, StatusCode};
|
use tide::{Request, StatusCode};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
use async_std::io::WriteExt;
|
||||||
use async_std::os::unix::net::UnixStream;
|
use async_std::os::unix::net::UnixStream;
|
||||||
|
use async_std::process::Command;
|
||||||
use camino::{Utf8Path, Utf8PathBuf};
|
use camino::{Utf8Path, Utf8PathBuf};
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use color_eyre::eyre::{OptionExt, eyre};
|
use color_eyre::eyre::{OptionExt, eyre};
|
||||||
|
@ -9,8 +11,6 @@ use serde_json::json;
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use async_std::io::WriteExt;
|
|
||||||
use async_std::process::Command;
|
|
||||||
|
|
||||||
pub struct CaddyController {
|
pub struct CaddyController {
|
||||||
api_socket_path: Utf8PathBuf,
|
api_socket_path: Utf8PathBuf,
|
||||||
|
@ -158,7 +158,7 @@ pub async fn start_caddy(api_socket_path: &Utf8Path, sockets_directory_path: &Ut
|
||||||
|
|
||||||
let caddy_path = option_env!("CADDY_PATH").unwrap_or("caddy");
|
let caddy_path = option_env!("CADDY_PATH").unwrap_or("caddy");
|
||||||
debug!("Caddy path: {}", caddy_path);
|
debug!("Caddy path: {}", caddy_path);
|
||||||
|
|
||||||
// Spawn a new proxy.
|
// Spawn a new proxy.
|
||||||
let process = Command::new(caddy_path).args(&["run", "--config", "-"]).stdin(Stdio::piped()).spawn()?;
|
let process = Command::new(caddy_path).args(&["run", "--config", "-"]).stdin(Stdio::piped()).spawn()?;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use color_eyre::Result;
|
|
||||||
use figment::providers::{Format, Toml};
|
|
||||||
use figment::Figment;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use async_std::task;
|
use async_std::task;
|
||||||
|
use color_eyre::Result;
|
||||||
use color_eyre::eyre::WrapErr;
|
use color_eyre::eyre::WrapErr;
|
||||||
|
use figment::Figment;
|
||||||
|
use figment::providers::{Format, Toml};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::collections::HashMap;
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Validate)]
|
#[derive(Deserialize, Debug, Validate)]
|
||||||
|
@ -15,7 +15,7 @@ pub struct Config {
|
||||||
pub sites_directory: String,
|
pub sites_directory: String,
|
||||||
pub sockets_directory: String,
|
pub sockets_directory: String,
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub scopes: HashMap<String, ConfigScope>
|
pub scopes: HashMap<String, ConfigScope>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static SECRET_PATTERN: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[a-zA-Z0-9]*$").unwrap());
|
static SECRET_PATTERN: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[a-zA-Z0-9]*$").unwrap());
|
||||||
|
@ -25,15 +25,18 @@ pub struct ConfigScope {
|
||||||
#[serde(with = "serde_regex")]
|
#[serde(with = "serde_regex")]
|
||||||
pub domain_pattern: Regex,
|
pub domain_pattern: Regex,
|
||||||
#[validate(length(equal = 100), regex(path = *SECRET_PATTERN))]
|
#[validate(length(equal = 100), regex(path = *SECRET_PATTERN))]
|
||||||
pub secret: String
|
pub secret: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn load_config() -> Result<Config> {
|
pub async fn load_config() -> Result<Config> {
|
||||||
let config: Config = task::spawn_blocking(|| Figment::new()
|
let config: Config = task::spawn_blocking(|| {
|
||||||
.merge(Toml::file("./config.toml"))
|
Figment::new()
|
||||||
.extract()
|
.merge(Toml::file("./config.toml"))
|
||||||
.wrap_err("Failed to load the configuration.")).await?;
|
.extract()
|
||||||
|
.wrap_err("Failed to load the configuration.")
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
config.validate().wrap_err("Failed to validate the configuration.")?;
|
config.validate().wrap_err("Failed to validate the configuration.")?;
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@ use crate::api::start_api_server;
|
||||||
use crate::caddy::start_caddy;
|
use crate::caddy::start_caddy;
|
||||||
use crate::config::load_config;
|
use crate::config::load_config;
|
||||||
use crate::sites::start_sites_worker;
|
use crate::sites::start_sites_worker;
|
||||||
|
use async_std::fs;
|
||||||
use camino::Utf8Path;
|
use camino::Utf8Path;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use color_eyre::eyre::WrapErr;
|
use color_eyre::eyre::WrapErr;
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use async_std::fs;
|
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
mod caddy;
|
mod caddy;
|
||||||
|
@ -27,7 +27,9 @@ async fn main() -> Result<()> {
|
||||||
let config = load_config().await?;
|
let config = load_config().await?;
|
||||||
|
|
||||||
let sockets_directory_path = Utf8Path::new(&config.sockets_directory);
|
let sockets_directory_path = Utf8Path::new(&config.sockets_directory);
|
||||||
fs::create_dir_all(sockets_directory_path.as_std_path()).await.wrap_err("Failed to access or create the sockets directory.")?;
|
fs::create_dir_all(sockets_directory_path.as_std_path())
|
||||||
|
.await
|
||||||
|
.wrap_err("Failed to access or create the sockets directory.")?;
|
||||||
let sockets_directory_path = sockets_directory_path.canonicalize_utf8().unwrap();
|
let sockets_directory_path = sockets_directory_path.canonicalize_utf8().unwrap();
|
||||||
let api_socket_path = sockets_directory_path.join("api.sock");
|
let api_socket_path = sockets_directory_path.join("api.sock");
|
||||||
|
|
||||||
|
|
11
src/sites.rs
11
src/sites.rs
|
@ -1,6 +1,5 @@
|
||||||
use crate::caddy::CaddyController;
|
use crate::caddy::CaddyController;
|
||||||
use async_std::io::{BufReader, BufWriter, WriteExt};
|
use async_std::io::WriteExt;
|
||||||
use async_std::net::TcpStream;
|
|
||||||
use async_std::stream::StreamExt;
|
use async_std::stream::StreamExt;
|
||||||
use async_std::sync::RwLock;
|
use async_std::sync::RwLock;
|
||||||
use async_std::task::JoinHandle;
|
use async_std::task::JoinHandle;
|
||||||
|
@ -157,7 +156,7 @@ async fn handle_download(ureq_agent: Arc<ureq::Agent>, sites: &Sites, caddy_cont
|
||||||
move || ureq_agent.get(url).call()
|
move || ureq_agent.get(url).call()
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
if !status.is_success() {
|
if !status.is_success() {
|
||||||
return Err(eyre!("Download request failed with status code {status}"));
|
return Err(eyre!("Download request failed with status code {status}"));
|
||||||
|
@ -221,11 +220,7 @@ async fn handle_download(ureq_agent: Arc<ureq::Agent>, sites: &Sites, caddy_cont
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn sites_worker(
|
async fn sites_worker(download_tasks_receiver: async_std::channel::Receiver<String>, sites: Arc<Sites>, mut caddy_controller: CaddyController) -> Result<!> {
|
||||||
mut download_tasks_receiver: async_std::channel::Receiver<String>,
|
|
||||||
sites: Arc<Sites>,
|
|
||||||
mut caddy_controller: CaddyController,
|
|
||||||
) -> Result<!> {
|
|
||||||
let ureq_agent = Arc::new(ureq::Agent::new_with_config(
|
let ureq_agent = Arc::new(ureq::Agent::new_with_config(
|
||||||
ureq::Agent::config_builder()
|
ureq::Agent::config_builder()
|
||||||
.timeout_resolve(Some(Duration::from_secs(10)))
|
.timeout_resolve(Some(Duration::from_secs(10)))
|
||||||
|
|
Loading…
Add table
Reference in a new issue