2022-01-20 11:51:31 +01:00
use std ::{
2025-04-16 13:15:01 +01:00
collections ::{ BTreeMap , HashMap , HashSet } ,
2022-02-06 20:23:22 +01:00
fmt ,
2022-01-20 11:51:31 +01:00
net ::{ IpAddr , Ipv4Addr } ,
2025-03-23 17:23:57 +00:00
num ::NonZeroU8 ,
2025-03-16 17:40:55 +00:00
path ::PathBuf ,
2025-04-16 13:15:01 +01:00
time ::Duration ,
2022-01-20 11:51:31 +01:00
} ;
2022-02-03 13:30:04 +01:00
2025-04-16 13:15:01 +01:00
use bytesize ::ByteSize ;
2022-10-09 17:26:53 +02:00
use ruma ::{ OwnedServerName , RoomVersionId } ;
2022-02-03 13:30:04 +01:00
use serde ::{ de ::IgnoredAny , Deserialize } ;
2025-04-16 13:15:01 +01:00
use tokio ::time ::{ interval , Interval } ;
2022-02-03 13:30:04 +01:00
use tracing ::warn ;
2024-05-02 09:26:43 +01:00
use url ::Url ;
2022-02-03 13:30:04 +01:00
2025-03-23 17:23:57 +00:00
use crate ::Error ;
2022-02-03 13:30:04 +01:00
2025-03-23 17:23:57 +00:00
mod proxy ;
2022-02-03 13:30:04 +01:00
use self ::proxy ::ProxyConfig ;
2025-03-23 17:23:57 +00:00
const SHA256_HEX_LENGTH : u8 = 64 ;
2025-03-23 12:26:28 +00:00
#[ derive(Deserialize) ]
pub struct IncompleteConfig {
2022-01-20 11:51:31 +01:00
#[ serde(default = " default_address " ) ]
pub address : IpAddr ,
#[ serde(default = " default_port " ) ]
pub port : u16 ,
2022-01-22 18:38:39 +01:00
pub tls : Option < TlsConfig > ,
2022-10-09 17:25:06 +02:00
pub server_name : OwnedServerName ,
2022-02-03 13:30:04 +01:00
pub database_backend : String ,
pub database_path : String ,
#[ serde(default = " default_db_cache_capacity_mb " ) ]
pub db_cache_capacity_mb : f64 ,
2022-06-23 06:58:34 +00:00
#[ serde(default = " true_fn " ) ]
pub enable_lightning_bolt : bool ,
2023-07-29 20:01:38 +02:00
#[ serde(default = " true_fn " ) ]
pub allow_check_for_updates : bool ,
2022-02-03 13:30:04 +01:00
#[ serde(default = " default_conduit_cache_capacity_modifier " ) ]
pub conduit_cache_capacity_modifier : f64 ,
#[ serde(default = " default_rocksdb_max_open_files " ) ]
pub rocksdb_max_open_files : i32 ,
#[ serde(default = " default_pdu_cache_capacity " ) ]
pub pdu_cache_capacity : u32 ,
#[ serde(default = " default_cleanup_second_interval " ) ]
pub cleanup_second_interval : u32 ,
#[ serde(default = " default_max_request_size " ) ]
pub max_request_size : u32 ,
#[ serde(default = " default_max_concurrent_requests " ) ]
pub max_concurrent_requests : u16 ,
2022-09-09 19:17:29 +02:00
#[ serde(default = " default_max_fetch_prev_events " ) ]
pub max_fetch_prev_events : u16 ,
2022-02-03 13:30:04 +01:00
#[ serde(default = " false_fn " ) ]
pub allow_registration : bool ,
2023-08-09 18:27:30 +02:00
pub registration_token : Option < String > ,
2024-05-28 00:22:11 +02:00
#[ serde(default = " default_openid_token_ttl " ) ]
pub openid_token_ttl : u64 ,
2022-02-03 13:30:04 +01:00
#[ serde(default = " true_fn " ) ]
pub allow_encryption : bool ,
#[ serde(default = " false_fn " ) ]
pub allow_federation : bool ,
#[ serde(default = " true_fn " ) ]
pub allow_room_creation : bool ,
2021-11-01 01:58:26 +00:00
#[ serde(default = " true_fn " ) ]
pub allow_unstable_room_versions : bool ,
#[ serde(default = " default_default_room_version " ) ]
pub default_room_version : RoomVersionId ,
2024-10-10 16:02:39 +01:00
#[ serde(default) ]
2025-03-23 12:26:28 +00:00
pub well_known : IncompleteWellKnownConfig ,
2022-02-03 13:30:04 +01:00
#[ serde(default = " false_fn " ) ]
pub allow_jaeger : bool ,
#[ serde(default = " false_fn " ) ]
pub tracing_flame : bool ,
#[ serde(default) ]
pub proxy : ProxyConfig ,
pub jwt_secret : Option < String > ,
2023-08-10 17:45:58 +02:00
#[ serde(default = " default_trusted_servers " ) ]
2022-10-09 17:25:06 +02:00
pub trusted_servers : Vec < OwnedServerName > ,
2022-02-03 13:30:04 +01:00
#[ serde(default = " default_log " ) ]
pub log : String ,
2024-05-28 14:30:46 +01:00
pub turn_username : Option < String > ,
pub turn_password : Option < String > ,
pub turn_uris : Option < Vec < String > > ,
pub turn_secret : Option < String > ,
2022-02-03 13:30:04 +01:00
#[ serde(default = " default_turn_ttl " ) ]
pub turn_ttl : u64 ,
2024-05-28 14:30:46 +01:00
pub turn : Option < TurnConfig > ,
2025-03-16 17:40:55 +00:00
#[ serde(default) ]
pub media : IncompleteMediaConfig ,
2022-04-07 12:11:55 +00:00
pub emergency_password : Option < String > ,
2022-02-03 13:30:04 +01:00
#[ serde(flatten) ]
pub catchall : BTreeMap < String , IgnoredAny > ,
}
2025-03-23 12:26:28 +00:00
#[ derive(Deserialize, Clone, Debug) ]
#[ serde(from = " IncompleteConfig " ) ]
pub struct Config {
pub address : IpAddr ,
pub port : u16 ,
pub tls : Option < TlsConfig > ,
pub server_name : OwnedServerName ,
pub database_backend : String ,
pub database_path : String ,
pub db_cache_capacity_mb : f64 ,
pub enable_lightning_bolt : bool ,
pub allow_check_for_updates : bool ,
pub conduit_cache_capacity_modifier : f64 ,
pub rocksdb_max_open_files : i32 ,
pub pdu_cache_capacity : u32 ,
pub cleanup_second_interval : u32 ,
pub max_request_size : u32 ,
pub max_concurrent_requests : u16 ,
pub max_fetch_prev_events : u16 ,
pub allow_registration : bool ,
pub registration_token : Option < String > ,
pub openid_token_ttl : u64 ,
pub allow_encryption : bool ,
pub allow_federation : bool ,
pub allow_room_creation : bool ,
pub allow_unstable_room_versions : bool ,
pub default_room_version : RoomVersionId ,
pub well_known : WellKnownConfig ,
pub allow_jaeger : bool ,
pub tracing_flame : bool ,
pub proxy : ProxyConfig ,
pub jwt_secret : Option < String > ,
pub trusted_servers : Vec < OwnedServerName > ,
pub log : String ,
pub turn : Option < TurnConfig > ,
2025-03-16 17:40:55 +00:00
pub media : MediaConfig ,
2025-03-23 12:26:28 +00:00
pub emergency_password : Option < String > ,
pub catchall : BTreeMap < String , IgnoredAny > ,
}
impl From < IncompleteConfig > for Config {
fn from ( val : IncompleteConfig ) -> Self {
let IncompleteConfig {
address ,
port ,
tls ,
server_name ,
database_backend ,
database_path ,
db_cache_capacity_mb ,
enable_lightning_bolt ,
allow_check_for_updates ,
conduit_cache_capacity_modifier ,
rocksdb_max_open_files ,
pdu_cache_capacity ,
cleanup_second_interval ,
max_request_size ,
max_concurrent_requests ,
max_fetch_prev_events ,
allow_registration ,
registration_token ,
openid_token_ttl ,
allow_encryption ,
allow_federation ,
allow_room_creation ,
allow_unstable_room_versions ,
default_room_version ,
well_known ,
allow_jaeger ,
tracing_flame ,
proxy ,
jwt_secret ,
trusted_servers ,
log ,
turn_username ,
turn_password ,
turn_uris ,
turn_secret ,
turn_ttl ,
turn ,
2025-03-16 17:40:55 +00:00
media ,
2025-03-23 12:26:28 +00:00
emergency_password ,
catchall ,
} = val ;
let turn = turn . or_else ( | | {
let auth = if let Some ( secret ) = turn_secret {
TurnAuth ::Secret { secret }
} else if let ( Some ( username ) , Some ( password ) ) = ( turn_username , turn_password ) {
TurnAuth ::UserPass { username , password }
} else {
return None ;
} ;
if let ( Some ( uris ) , ttl ) = ( turn_uris , turn_ttl ) {
Some ( TurnConfig { uris , ttl , auth } )
} else {
None
}
} ) ;
let well_known_client = well_known
. client
. map ( String ::from )
. unwrap_or_else ( | | format! ( " https:// {server_name} " ) ) ;
let well_known_server = well_known . server . unwrap_or_else ( | | {
if server_name . port ( ) . is_some ( ) {
server_name . clone ( )
} else {
format! ( " {} :443 " , server_name . host ( ) )
. try_into ( )
. expect ( " Host from valid hostname + :443 must be valid " )
}
} ) ;
let well_known = WellKnownConfig {
client : well_known_client ,
server : well_known_server ,
} ;
2025-04-16 13:15:01 +01:00
let media = MediaConfig {
backend : match media . backend {
IncompleteMediaBackendConfig ::FileSystem {
path ,
directory_structure ,
} = > MediaBackendConfig ::FileSystem {
path : path . unwrap_or_else ( | | {
// We do this as we don't know if the path has a trailing slash, or even if the
// path separator is a forward or backward slash
[ & database_path , " media " ]
. iter ( )
. collect ::< PathBuf > ( )
. into_os_string ( )
. into_string ( )
. expect ( " Both inputs are valid UTF-8 " )
} ) ,
directory_structure ,
} ,
2025-06-06 08:56:19 +03:00
IncompleteMediaBackendConfig ::S3 {
endpoint ,
bucket ,
region ,
key ,
secret ,
duration ,
bucket_use_path ,
} = > {
let path_style = if bucket_use_path {
rusty_s3 ::UrlStyle ::Path
} else {
rusty_s3 ::UrlStyle ::VirtualHost
} ;
let bucket = rusty_s3 ::Bucket ::new ( endpoint , path_style , bucket , region )
. expect ( " Invalid S3 config " ) ;
let credentials = rusty_s3 ::Credentials ::new ( key , secret ) ;
MediaBackendConfig ::S3 {
bucket : bucket ,
credentials : credentials ,
duration : Duration ::from_secs ( duration ) ,
}
}
2025-03-16 17:40:55 +00:00
} ,
2025-04-16 13:15:01 +01:00
retention : media . retention . into ( ) ,
2025-03-16 17:40:55 +00:00
} ;
2025-03-23 12:26:28 +00:00
Config {
address ,
port ,
tls ,
server_name ,
database_backend ,
database_path ,
db_cache_capacity_mb ,
enable_lightning_bolt ,
allow_check_for_updates ,
conduit_cache_capacity_modifier ,
rocksdb_max_open_files ,
pdu_cache_capacity ,
cleanup_second_interval ,
max_request_size ,
max_concurrent_requests ,
max_fetch_prev_events ,
allow_registration ,
registration_token ,
openid_token_ttl ,
allow_encryption ,
allow_federation ,
allow_room_creation ,
allow_unstable_room_versions ,
default_room_version ,
well_known ,
allow_jaeger ,
tracing_flame ,
proxy ,
jwt_secret ,
trusted_servers ,
log ,
turn ,
2025-03-16 17:40:55 +00:00
media ,
2025-03-23 12:26:28 +00:00
emergency_password ,
catchall ,
}
}
}
2022-01-22 18:38:39 +01:00
#[ derive(Clone, Debug, Deserialize) ]
pub struct TlsConfig {
pub certs : String ,
pub key : String ,
}
2024-05-28 14:30:46 +01:00
#[ derive(Clone, Debug, Deserialize) ]
pub struct TurnConfig {
pub uris : Vec < String > ,
#[ serde(default = " default_turn_ttl " ) ]
pub ttl : u64 ,
#[ serde(flatten) ]
pub auth : TurnAuth ,
}
#[ derive(Clone, Debug, Deserialize) ]
#[ serde(untagged) ]
pub enum TurnAuth {
UserPass { username : String , password : String } ,
Secret { secret : String } ,
}
2024-05-02 09:26:43 +01:00
#[ derive(Clone, Debug, Deserialize, Default) ]
2025-03-23 12:26:28 +00:00
pub struct IncompleteWellKnownConfig {
// We use URL here so that the user gets an error if the config isn't a valid url
2024-05-02 09:26:43 +01:00
pub client : Option < Url > ,
pub server : Option < OwnedServerName > ,
}
2025-03-23 12:26:28 +00:00
#[ derive(Clone, Debug) ]
pub struct WellKnownConfig {
// We use String here as there is no point converting our manually constructed String into a
// URL, just for it to be converted back into a &str
pub client : String ,
pub server : OwnedServerName ,
}
2025-04-16 13:15:01 +01:00
#[ derive(Deserialize, Default) ]
pub struct IncompleteMediaConfig {
#[ serde(flatten, default) ]
pub backend : IncompleteMediaBackendConfig ,
pub retention : IncompleteMediaRetentionConfig ,
}
#[ derive(Clone, Debug) ]
pub struct MediaConfig {
pub backend : MediaBackendConfig ,
pub retention : MediaRetentionConfig ,
}
type IncompleteMediaRetentionConfig = Option < HashSet < IncompleteScopedMediaRetentionConfig > > ;
#[ derive(Clone, Debug) ]
pub struct MediaRetentionConfig {
pub scoped : HashMap < MediaRetentionScope , ScopedMediaRetentionConfig > ,
pub global_space : Option < ByteSize > ,
}
impl MediaRetentionConfig {
/// Interval for the duration-based retention policies to be checked & enforced
pub fn cleanup_interval ( & self ) -> Option < Interval > {
self . scoped
. values ( )
. filter_map ( | scoped | match ( scoped . created , scoped . accessed ) {
( None , accessed ) = > accessed ,
( created , None ) = > created ,
( created , accessed ) = > created . min ( accessed ) ,
} )
. map ( | dur | {
dur . mul_f32 ( 0.1 )
. max ( Duration ::from_secs ( 60 ) . min ( Duration ::from_secs ( 60 * 60 * 24 ) ) )
} )
. min ( )
. map ( interval )
}
}
#[ derive(Deserialize) ]
pub struct IncompleteScopedMediaRetentionConfig {
pub scope : Option < MediaRetentionScope > ,
#[ serde(default, with = " humantime_serde::option " ) ]
pub accessed : Option < Duration > ,
#[ serde(default, with = " humantime_serde::option " ) ]
pub created : Option < Duration > ,
pub space : Option < ByteSize > ,
}
impl From < IncompleteMediaRetentionConfig > for MediaRetentionConfig {
fn from ( value : IncompleteMediaRetentionConfig ) -> Self {
{
let mut scoped = HashMap ::from ( [
(
MediaRetentionScope ::Remote ,
ScopedMediaRetentionConfig ::default ( ) ,
) ,
(
MediaRetentionScope ::Thumbnail ,
ScopedMediaRetentionConfig ::default ( ) ,
) ,
] ) ;
let mut fallback = None ;
if let Some ( retention ) = value {
for IncompleteScopedMediaRetentionConfig {
scope ,
accessed ,
space ,
created ,
} in retention
{
if let Some ( scope ) = scope {
scoped . insert (
scope ,
ScopedMediaRetentionConfig {
accessed ,
space ,
created ,
} ,
) ;
} else {
fallback = Some ( ScopedMediaRetentionConfig {
accessed ,
space ,
created ,
} )
}
}
}
if let Some ( fallback ) = fallback . clone ( ) {
for scope in [
MediaRetentionScope ::Remote ,
MediaRetentionScope ::Local ,
MediaRetentionScope ::Thumbnail ,
] {
scoped . entry ( scope ) . or_insert_with ( | | fallback . clone ( ) ) ;
}
}
Self {
global_space : fallback . and_then ( | global | global . space ) ,
scoped ,
}
}
}
}
impl std ::hash ::Hash for IncompleteScopedMediaRetentionConfig {
fn hash < H : std ::hash ::Hasher > ( & self , state : & mut H ) {
self . scope . hash ( state ) ;
}
}
impl PartialEq for IncompleteScopedMediaRetentionConfig {
fn eq ( & self , other : & Self ) -> bool {
self . scope = = other . scope
}
}
impl Eq for IncompleteScopedMediaRetentionConfig { }
#[ derive(Debug, Clone) ]
pub struct ScopedMediaRetentionConfig {
pub accessed : Option < Duration > ,
pub created : Option < Duration > ,
pub space : Option < ByteSize > ,
}
impl Default for ScopedMediaRetentionConfig {
fn default ( ) -> Self {
Self {
// 30 days
accessed : Some ( Duration ::from_secs ( 60 * 60 * 24 * 30 ) ) ,
created : None ,
space : None ,
}
}
}
#[ derive(Deserialize, Clone, Debug, Hash, PartialEq, Eq) ]
#[ serde(rename_all = " lowercase " ) ]
pub enum MediaRetentionScope {
Remote ,
Local ,
Thumbnail ,
}
2025-03-23 17:23:57 +00:00
#[ derive(Deserialize) ]
2025-03-16 17:40:55 +00:00
#[ serde(tag = " backend " , rename_all = " lowercase " ) ]
2025-04-16 13:15:01 +01:00
pub enum IncompleteMediaBackendConfig {
2025-03-23 17:23:57 +00:00
FileSystem {
path : Option < String > ,
#[ serde(default) ]
directory_structure : DirectoryStructure ,
} ,
2025-06-06 08:56:19 +03:00
S3 {
endpoint : Url ,
bucket : String ,
region : String ,
key : String ,
secret : String ,
#[ serde(default = " default_s3_duration " ) ]
duration : u64 ,
#[ serde(default = " false_fn " ) ]
bucket_use_path : bool ,
} ,
2025-03-16 17:40:55 +00:00
}
2025-04-16 13:15:01 +01:00
impl Default for IncompleteMediaBackendConfig {
2025-03-16 17:40:55 +00:00
fn default ( ) -> Self {
2025-03-23 17:23:57 +00:00
Self ::FileSystem {
path : None ,
directory_structure : DirectoryStructure ::default ( ) ,
}
2025-03-16 17:40:55 +00:00
}
}
#[ derive(Debug, Clone) ]
2025-04-16 13:15:01 +01:00
pub enum MediaBackendConfig {
2025-03-23 17:23:57 +00:00
FileSystem {
path : String ,
directory_structure : DirectoryStructure ,
} ,
2025-06-06 08:56:19 +03:00
S3 {
bucket : rusty_s3 ::Bucket ,
credentials : rusty_s3 ::Credentials ,
duration : Duration ,
} ,
2025-03-23 17:23:57 +00:00
}
#[ derive(Debug, Clone, Deserialize) ]
// See https://github.com/serde-rs/serde/issues/642#issuecomment-525432907
#[ serde(try_from = " ShadowDirectoryStructure " , untagged) ]
pub enum DirectoryStructure {
// We do this enum instead of Option<DirectoryStructure>, so that we can have the structure be
// deep by default, while still providing a away for it to be flat (by creating an empty table)
//
// e.g.:
// ```toml
// [global.media.directory_structure]
// ```
Flat ,
Deep { length : NonZeroU8 , depth : NonZeroU8 } ,
}
impl Default for DirectoryStructure {
fn default ( ) -> Self {
Self ::Deep {
length : NonZeroU8 ::new ( 2 ) . expect ( " 2 is not 0 " ) ,
depth : NonZeroU8 ::new ( 2 ) . expect ( " 2 is not 0 " ) ,
}
}
}
#[ derive(Deserialize) ]
#[ serde(untagged) ]
enum ShadowDirectoryStructure {
Deep { length : NonZeroU8 , depth : NonZeroU8 } ,
2025-05-09 17:33:06 +01:00
Flat { } ,
2025-03-23 17:23:57 +00:00
}
impl TryFrom < ShadowDirectoryStructure > for DirectoryStructure {
type Error = Error ;
fn try_from ( value : ShadowDirectoryStructure ) -> Result < Self , Self ::Error > {
match value {
ShadowDirectoryStructure ::Flat { } = > Ok ( Self ::Flat ) ,
ShadowDirectoryStructure ::Deep { length , depth } = > {
if length
. get ( )
. checked_mul ( depth . get ( ) )
. map ( | product | product < SHA256_HEX_LENGTH )
// If an overflow occurs, it definitely isn't less than SHA256_HEX_LENGTH
. unwrap_or ( false )
{
Ok ( Self ::Deep { length , depth } )
} else {
Err ( Error ::bad_config ( " The media directory structure depth multiplied by the depth is equal to or greater than a sha256 hex hash, please reduce at least one of the two so that their product is less than 64 " ) )
}
}
}
}
2025-03-16 17:40:55 +00:00
}
2024-05-28 14:30:46 +01:00
const DEPRECATED_KEYS : & [ & str ] = & [
" cache_capacity " ,
" turn_username " ,
" turn_password " ,
" turn_uris " ,
" turn_secret " ,
" turn_ttl " ,
] ;
2022-02-03 13:30:04 +01:00
impl Config {
pub fn warn_deprecated ( & self ) {
let mut was_deprecated = false ;
for key in self
. catchall
. keys ( )
. filter ( | key | DEPRECATED_KEYS . iter ( ) . any ( | s | s = = key ) )
{
warn! ( " Config parameter {} is deprecated " , key ) ;
was_deprecated = true ;
}
if was_deprecated {
warn! ( " Read conduit documentation and check your configuration if any new configuration parameters should be adjusted " ) ;
}
}
}
2022-02-06 20:23:22 +01:00
impl fmt ::Display for Config {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
// Prepare a list of config values to show
let lines = [
( " Server name " , self . server_name . host ( ) ) ,
( " Database backend " , & self . database_backend ) ,
( " Database path " , & self . database_path ) ,
(
" Database cache capacity (MB) " ,
& self . db_cache_capacity_mb . to_string ( ) ,
) ,
(
" Cache capacity modifier " ,
& self . conduit_cache_capacity_modifier . to_string ( ) ,
) ,
#[ cfg(feature = " rocksdb " ) ]
(
" Maximum open files for RocksDB " ,
& self . rocksdb_max_open_files . to_string ( ) ,
) ,
( " PDU cache capacity " , & self . pdu_cache_capacity . to_string ( ) ) ,
(
" Cleanup interval in seconds " ,
& self . cleanup_second_interval . to_string ( ) ,
) ,
( " Maximum request size " , & self . max_request_size . to_string ( ) ) ,
(
" Maximum concurrent requests " ,
& self . max_concurrent_requests . to_string ( ) ,
) ,
( " Allow registration " , & self . allow_registration . to_string ( ) ) ,
2022-06-23 06:58:34 +00:00
(
" Enabled lightning bolt " ,
& self . enable_lightning_bolt . to_string ( ) ,
) ,
2022-02-06 20:23:22 +01:00
( " Allow encryption " , & self . allow_encryption . to_string ( ) ) ,
( " Allow federation " , & self . allow_federation . to_string ( ) ) ,
( " Allow room creation " , & self . allow_room_creation . to_string ( ) ) ,
(
" JWT secret " ,
match self . jwt_secret {
Some ( _ ) = > " set " ,
None = > " not set " ,
} ,
) ,
( " Trusted servers " , {
let mut lst = vec! [ ] ;
for server in & self . trusted_servers {
lst . push ( server . host ( ) ) ;
}
& lst . join ( " , " )
} ) ,
2024-05-28 14:30:46 +01:00
( " TURN URIs " , {
2025-03-23 12:26:28 +00:00
if let Some ( turn ) = & self . turn {
2024-05-28 14:30:46 +01:00
let mut lst = vec! [ ] ;
for item in turn . uris . iter ( ) . cloned ( ) . enumerate ( ) {
let ( _ , uri ) : ( usize , String ) = item ;
lst . push ( uri ) ;
}
& lst . join ( " , " )
2022-02-06 20:23:22 +01:00
} else {
2024-05-28 14:30:46 +01:00
" unset "
2022-02-06 20:23:22 +01:00
}
} ) ,
2025-03-23 12:26:28 +00:00
( " Well-known server name " , self . well_known . server . as_str ( ) ) ,
( " Well-known client URL " , & self . well_known . client ) ,
2022-02-06 20:23:22 +01:00
] ;
2022-11-21 09:51:39 +01:00
let mut msg : String = " Active config values: \n \n " . to_owned ( ) ;
2022-02-06 20:23:22 +01:00
for line in lines . into_iter ( ) . enumerate ( ) {
msg + = & format! ( " {} : {} \n " , line . 1 . 0 , line . 1 . 1 ) ;
}
2022-12-21 10:42:12 +01:00
write! ( f , " {msg} " )
2022-02-06 20:23:22 +01:00
}
}
2022-02-03 13:30:04 +01:00
fn false_fn ( ) -> bool {
false
}
fn true_fn ( ) -> bool {
true
}
2022-01-20 11:51:31 +01:00
fn default_address ( ) -> IpAddr {
Ipv4Addr ::LOCALHOST . into ( )
}
fn default_port ( ) -> u16 {
8000
}
2022-02-03 13:30:04 +01:00
fn default_db_cache_capacity_mb ( ) -> f64 {
2023-07-03 19:37:54 +02:00
300.0
2022-02-03 13:30:04 +01:00
}
fn default_conduit_cache_capacity_modifier ( ) -> f64 {
1.0
}
fn default_rocksdb_max_open_files ( ) -> i32 {
2022-12-21 09:56:07 +01:00
1000
2022-02-03 13:30:04 +01:00
}
fn default_pdu_cache_capacity ( ) -> u32 {
150_000
}
fn default_cleanup_second_interval ( ) -> u32 {
2022-10-10 14:09:11 +02:00
60 // every minute
2022-02-03 13:30:04 +01:00
}
fn default_max_request_size ( ) -> u32 {
20 * 1024 * 1024 // Default to 20 MB
}
fn default_max_concurrent_requests ( ) -> u16 {
100
}
2022-09-09 19:17:29 +02:00
fn default_max_fetch_prev_events ( ) -> u16 {
100_ u16
}
2023-08-10 17:45:58 +02:00
fn default_trusted_servers ( ) -> Vec < OwnedServerName > {
vec! [ OwnedServerName ::try_from ( " matrix.org " ) . unwrap ( ) ]
}
2022-02-03 13:30:04 +01:00
fn default_log ( ) -> String {
2024-03-10 22:37:22 -07:00
" warn,state_res=warn,_=off " . to_owned ( )
2022-02-03 13:30:04 +01:00
}
fn default_turn_ttl ( ) -> u64 {
60 * 60 * 24
}
2021-11-01 01:58:26 +00:00
2024-05-28 00:22:11 +02:00
fn default_openid_token_ttl ( ) -> u64 {
60 * 60
}
2021-11-01 01:58:26 +00:00
// I know, it's a great name
2022-10-15 10:42:14 +02:00
pub fn default_default_room_version ( ) -> RoomVersionId {
2024-04-11 22:55:18 +01:00
RoomVersionId ::V10
2021-11-01 01:58:26 +00:00
}
2025-06-06 08:56:19 +03:00
fn default_s3_duration ( ) -> u64 {
30
}