@@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
9
9
use thiserror:: Error ;
10
10
use tokio:: sync:: RwLock ;
11
11
use torrust_index_located_error:: { Located , LocatedError } ;
12
+ use url:: { ParseError , Url } ;
12
13
13
14
/// Information required for loading config
14
15
#[ derive( Debug , Default , Clone ) ]
@@ -99,6 +100,17 @@ pub enum Error {
99
100
Infallible ,
100
101
}
101
102
103
+ /// Errors that can occur validating the configuration.
104
+ #[ derive( Error , Debug ) ]
105
+ pub enum ValidationError {
106
+ /// Unable to load the configuration from the configuration file.
107
+ #[ error( "Invalid tracker URL: {source}" ) ]
108
+ InvalidTrackerUrl { source : LocatedError < ' static , ParseError > } ,
109
+
110
+ #[ error( "UDP private trackers are not supported. URL schemes for private tracker URLs must be HTTP ot HTTPS" ) ]
111
+ UdpTrackersInPrivateModeNotSupported ,
112
+ }
113
+
102
114
impl From < ConfigError > for Error {
103
115
#[ track_caller]
104
116
fn from ( err : ConfigError ) -> Self {
@@ -149,6 +161,11 @@ impl TrackerMode {
149
161
pub fn is_open ( & self ) -> bool {
150
162
matches ! ( self , TrackerMode :: Public | TrackerMode :: Whitelisted )
151
163
}
164
+
165
+ #[ must_use]
166
+ pub fn is_close ( & self ) -> bool {
167
+ !self . is_open ( )
168
+ }
152
169
}
153
170
154
171
/// Configuration for the associated tracker.
@@ -550,6 +567,42 @@ impl Configuration {
550
567
551
568
settings_lock. net . base_url . clone ( )
552
569
}
570
+
571
+ /// # Errors
572
+ ///
573
+ /// Will return an error if the configuration is invalid.
574
+ pub async fn validate ( & self ) -> Result < ( ) , ValidationError > {
575
+ self . validate_tracker_config ( ) . await
576
+ }
577
+
578
+ /// # Errors
579
+ ///
580
+ /// Will return an error if the `tracker` configuration section is invalid.
581
+ pub async fn validate_tracker_config ( & self ) -> Result < ( ) , ValidationError > {
582
+ let settings_lock = self . settings . read ( ) . await ;
583
+
584
+ let tracker_mode = settings_lock. tracker . mode . clone ( ) ;
585
+ let tracker_url = settings_lock. tracker . url . clone ( ) ;
586
+
587
+ let tracker_url = match parse_url ( & tracker_url) {
588
+ Ok ( url) => url,
589
+ Err ( err) => {
590
+ return Err ( ValidationError :: InvalidTrackerUrl {
591
+ source : Located ( err) . into ( ) ,
592
+ } )
593
+ }
594
+ } ;
595
+
596
+ if tracker_mode. is_close ( ) && ( tracker_url. scheme ( ) != "http" && tracker_url. scheme ( ) != "https" ) {
597
+ return Err ( ValidationError :: UdpTrackersInPrivateModeNotSupported ) ;
598
+ }
599
+
600
+ Ok ( ( ) )
601
+ }
602
+ }
603
+
604
+ fn parse_url ( url_str : & str ) -> Result < Url , url:: ParseError > {
605
+ Url :: parse ( url_str)
553
606
}
554
607
555
608
/// The public index configuration.
0 commit comments