Skip to content

Commit

Permalink
feat: [#488] panic starting the app when tracker config is invalid
Browse files Browse the repository at this point in the history
For the time being, it only checks that private tracker don't use UDP.
  • Loading branch information
josecelano committed Feb 23, 2024
1 parent 36e46fe commit 9b7c5c8
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ pub async fn run(configuration: Configuration, api_version: &Version) -> Running

logging::setup(&log_level);

configuration.validate().await.expect("invalid configuration");

let configuration = Arc::new(configuration);

// Get configuration settings needed to build the app dependencies and
Expand Down
53 changes: 53 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
use thiserror::Error;
use tokio::sync::RwLock;
use torrust_index_located_error::{Located, LocatedError};
use url::{ParseError, Url};

/// Information required for loading config
#[derive(Debug, Default, Clone)]
Expand Down Expand Up @@ -99,6 +100,17 @@ pub enum Error {
Infallible,
}

/// Errors that can occur validating the configuration.
#[derive(Error, Debug)]
pub enum ValidationError {
/// Unable to load the configuration from the configuration file.
#[error("Invalid tracker URL: {source}")]
InvalidTrackerUrl { source: LocatedError<'static, ParseError> },

#[error("UDP private trackers are not supported. URL schemes for private tracker URLs must be HTTP ot HTTPS")]
UdpTrackersInPrivateModeNotSupported,
}

impl From<ConfigError> for Error {
#[track_caller]
fn from(err: ConfigError) -> Self {
Expand Down Expand Up @@ -149,6 +161,11 @@ impl TrackerMode {
pub fn is_open(&self) -> bool {
matches!(self, TrackerMode::Public | TrackerMode::Whitelisted)
}

#[must_use]
pub fn is_close(&self) -> bool {
!self.is_open()
}
}

/// Configuration for the associated tracker.
Expand Down Expand Up @@ -550,6 +567,42 @@ impl Configuration {

settings_lock.net.base_url.clone()
}

/// # Errors
///
/// Will return an error if the configuration is invalid.
pub async fn validate(&self) -> Result<(), ValidationError> {
self.validate_tracker_config().await
}

/// # Errors
///
/// Will return an error if the `tracker` configuration section is invalid.
pub async fn validate_tracker_config(&self) -> Result<(), ValidationError> {
let settings_lock = self.settings.read().await;

let tracker_mode = settings_lock.tracker.mode.clone();
let tracker_url = settings_lock.tracker.url.clone();

let tracker_url = match parse_url(&tracker_url) {
Ok(url) => url,
Err(err) => {
return Err(ValidationError::InvalidTrackerUrl {
source: Located(err).into(),
})
}
};

if tracker_mode.is_close() && (tracker_url.scheme() != "http" && tracker_url.scheme() != "https") {
return Err(ValidationError::UdpTrackersInPrivateModeNotSupported);
}

Ok(())
}
}

fn parse_url(url_str: &str) -> Result<Url, url::ParseError> {
Url::parse(url_str)
}

/// The public index configuration.
Expand Down

0 comments on commit 9b7c5c8

Please sign in to comment.