Use unstable options
This commit is contained in:
parent
316e69851e
commit
6da2cba78a
4 changed files with 110 additions and 26 deletions
|
@ -1,6 +1,9 @@
|
|||
use std::num::{NonZeroU16, NonZeroU64};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::{fmt::Display, path::PathBuf};
|
||||
use std::{fmt::Formatter, sync::atomic::AtomicBool};
|
||||
use std::{
|
||||
num::{NonZeroU16, NonZeroU64},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use clap::{crate_authors, crate_description, crate_version, Clap};
|
||||
use url::Url;
|
||||
|
@ -43,7 +46,6 @@ pub struct CliArgs {
|
|||
short,
|
||||
long,
|
||||
conflicts_with("memory-quota"),
|
||||
conflicts_with("use-lfu"),
|
||||
env = "LOW_MEMORY_MODE",
|
||||
takes_value = false
|
||||
)]
|
||||
|
@ -57,16 +59,46 @@ pub struct CliArgs {
|
|||
/// respectively.
|
||||
#[clap(short, long, parse(from_occurrences), conflicts_with = "verbose")]
|
||||
pub quiet: usize,
|
||||
/// Overrides the upstream URL to fetch images from. Don't use this unless
|
||||
/// you know what you're dealing with.
|
||||
#[clap(short = 'Z', long)]
|
||||
pub unstable_options: Vec<UnstableOptions>,
|
||||
#[clap(long)]
|
||||
pub override_upstream: Option<Url>,
|
||||
/// Disables token validation. Don't use this unless you know the
|
||||
/// ramifications of this command.
|
||||
#[clap(long)]
|
||||
pub disable_token_validation: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum UnstableOptions {
|
||||
/// Overrides the upstream URL to fetch images from. Don't use this unless
|
||||
/// you know what you're dealing with.
|
||||
OverrideUpstream,
|
||||
|
||||
/// Use an LFU implementation for the in-memory cache instead of the default
|
||||
/// LRU implementation.
|
||||
#[clap(short = 'F', long)]
|
||||
pub use_lfu: bool,
|
||||
UseLfu,
|
||||
|
||||
/// Disables token validation. Don't use this unless you know the
|
||||
/// ramifications of this command.
|
||||
DisableTokenValidation,
|
||||
}
|
||||
|
||||
impl FromStr for UnstableOptions {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"override-upstream" => Ok(Self::OverrideUpstream),
|
||||
"use-lfu" => Ok(Self::UseLfu),
|
||||
"disable-token-validation" => Ok(Self::DisableTokenValidation),
|
||||
_ => Err("Unknown unstable option"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for UnstableOptions {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::OverrideUpstream => write!(f, "override-upstream"),
|
||||
Self::UseLfu => write!(f, "use-lfu"),
|
||||
Self::DisableTokenValidation => write!(f, "disable-token-validation"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
61
src/main.rs
61
src/main.rs
|
@ -2,13 +2,16 @@
|
|||
// We're end users, so these is ok
|
||||
#![allow(clippy::module_name_repetitions)]
|
||||
|
||||
use std::env::{self, VarError};
|
||||
use std::hint::unreachable_unchecked;
|
||||
use std::num::ParseIntError;
|
||||
use std::process;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
env::{self, VarError},
|
||||
fmt::Display,
|
||||
};
|
||||
use std::{error::Error, hint::unreachable_unchecked};
|
||||
|
||||
use actix_web::rt::{spawn, time, System};
|
||||
use actix_web::web::{self, Data};
|
||||
|
@ -24,8 +27,11 @@ use state::{RwLockServerState, ServerState};
|
|||
use stop::send_stop;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::cache::{MemoryLfuCache, MemoryLruCache};
|
||||
use crate::state::DynamicServerCert;
|
||||
use crate::{
|
||||
cache::{MemoryLfuCache, MemoryLruCache},
|
||||
config::UnstableOptions,
|
||||
};
|
||||
|
||||
mod cache;
|
||||
mod config;
|
||||
|
@ -50,7 +56,7 @@ enum ServerError {
|
|||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
// It's ok to fail early here, it would imply we have a invalid config.
|
||||
dotenv::dotenv().ok();
|
||||
let cli_args = CliArgs::parse();
|
||||
|
@ -60,7 +66,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let disk_quota = cli_args.disk_quota;
|
||||
let cache_path = cli_args.cache_path.clone();
|
||||
let low_mem_mode = cli_args.low_memory;
|
||||
let use_lfu = cli_args.use_lfu;
|
||||
let use_lfu = cli_args.unstable_options.contains(&UnstableOptions::UseLfu);
|
||||
|
||||
let log_level = match (cli_args.quiet, cli_args.verbose) {
|
||||
(n, _) if n > 2 => LevelFilter::Off,
|
||||
|
@ -74,7 +80,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
SimpleLogger::new().with_level(log_level).init()?;
|
||||
|
||||
print_preamble_and_warnings();
|
||||
if let Err(e) = print_preamble_and_warnings(&cli_args) {
|
||||
error!("{}", e);
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
let client_secret = if let Ok(v) = env::var("CLIENT_SECRET") {
|
||||
v
|
||||
|
@ -163,7 +172,28 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn print_preamble_and_warnings() {
|
||||
#[derive(Debug)]
|
||||
enum InvalidCombination {
|
||||
MissingUnstableOption(&'static str, UnstableOptions),
|
||||
}
|
||||
|
||||
impl Display for InvalidCombination {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
InvalidCombination::MissingUnstableOption(opt, arg) => {
|
||||
write!(
|
||||
f,
|
||||
"The option '{}' requires the unstable option '-Z {}'",
|
||||
opt, arg
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for InvalidCombination {}
|
||||
|
||||
fn print_preamble_and_warnings(args: &CliArgs) -> Result<(), Box<dyn Error>> {
|
||||
println!(concat!(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
" ",
|
||||
|
@ -186,4 +216,21 @@ fn print_preamble_and_warnings() {
|
|||
env!("CARGO_PKG_NAME"),
|
||||
". If not, see <https://www.gnu.org/licenses/>.\n"
|
||||
));
|
||||
|
||||
if !args.unstable_options.is_empty() {
|
||||
warn!("Unstable options are enabled. These options should not be used in production!");
|
||||
}
|
||||
|
||||
if args.override_upstream.is_some()
|
||||
&& !args
|
||||
.unstable_options
|
||||
.contains(&UnstableOptions::OverrideUpstream)
|
||||
{
|
||||
Err(Box::new(InvalidCombination::MissingUnstableOption(
|
||||
"override-upstream",
|
||||
UnstableOptions::OverrideUpstream,
|
||||
)))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ use serde::{Deserialize, Serialize};
|
|||
use sodiumoxide::crypto::box_::PrecomputedKey;
|
||||
use url::Url;
|
||||
|
||||
use crate::client_api_version;
|
||||
use crate::config::{CliArgs, VALIDATE_TOKENS};
|
||||
use crate::state::{
|
||||
RwLockServerState, PREVIOUSLY_COMPROMISED, PREVIOUSLY_PAUSED, TLS_CERTS,
|
||||
TLS_PREVIOUSLY_CREATED, TLS_SIGNING_KEY,
|
||||
};
|
||||
use crate::{client_api_version, config::UnstableOptions};
|
||||
|
||||
pub const CONTROL_CENTER_PING_URL: &str = "https://api.mangadex.network/ping";
|
||||
|
||||
|
@ -170,7 +170,9 @@ pub async fn update_server_state(secret: &str, cli: &CliArgs, data: &mut Arc<RwL
|
|||
}
|
||||
}
|
||||
|
||||
if !cli.disable_token_validation
|
||||
if !cli
|
||||
.unstable_options
|
||||
.contains(&UnstableOptions::DisableTokenValidation)
|
||||
&& VALIDATE_TOKENS.load(Ordering::Acquire) != resp.force_tokens
|
||||
{
|
||||
if resp.force_tokens {
|
||||
|
|
13
src/state.rs
13
src/state.rs
|
@ -1,6 +1,6 @@
|
|||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use crate::config::{CliArgs, SEND_SERVER_VERSION, VALIDATE_TOKENS};
|
||||
use crate::config::{CliArgs, UnstableOptions, SEND_SERVER_VERSION, VALIDATE_TOKENS};
|
||||
use crate::ping::{Request, Response, CONTROL_CENTER_PING_URL};
|
||||
use arc_swap::ArcSwap;
|
||||
use log::{error, info, warn};
|
||||
|
@ -90,7 +90,10 @@ impl ServerState {
|
|||
|
||||
info!("This client's URL has been set to {}", resp.url);
|
||||
|
||||
if config.disable_token_validation {
|
||||
if config
|
||||
.unstable_options
|
||||
.contains(&UnstableOptions::DisableTokenValidation)
|
||||
{
|
||||
warn!("Token validation is explicitly disabled!");
|
||||
} else {
|
||||
if resp.force_tokens {
|
||||
|
@ -116,17 +119,17 @@ impl ServerState {
|
|||
})
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Got malformed response: {}", e);
|
||||
error!("Got malformed response: {}. Is MangaDex@Home down?", e);
|
||||
Err(ServerInitError::MalformedResponse(e))
|
||||
}
|
||||
},
|
||||
Err(e) => match e {
|
||||
e if e.is_timeout() => {
|
||||
error!("Response timed out to control server. Is MangaDex down?");
|
||||
error!("Response timed out to control server. Is MangaDex@Home down?");
|
||||
Err(ServerInitError::Timeout(e))
|
||||
}
|
||||
e => {
|
||||
warn!("Failed to send request: {}", e);
|
||||
error!("Failed to send request: {}", e);
|
||||
Err(ServerInitError::SendFailure(e))
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue