Merge pull request 'Implement max_request_size config option' (#153) from media-size-config into master

Reviewed-on: https://git.koesters.xyz/timo/conduit/pulls/153
Reviewed-by: Timo Kösters <timo@koesters.xyz>
next
Timo Kösters 2020-07-27 18:08:50 +02:00
commit fdb7b8f0f1
4 changed files with 39 additions and 15 deletions

View File

@ -1,15 +1,29 @@
[global] [global]
# The name of this server
# Note: If server name != hostname, you need a .well-known file for federation
# to work
server_name = "your.server.name" server_name = "your.server.name"
port = 14004
# Max size for uploads
#max_request_size = 20_000_000 # in bytes, ~20 MB
# Disable registration. No new users will be able to register on this server
#registration_disabled = true #registration_disabled = true
# Disable encryption, so no new encrypted rooms can be created
# Note: existing rooms will continue to work
#encryption_disabled = true #encryption_disabled = true
# Default path is in this user's data # Default path is in this user's data
#database_path = "/home/timo/MyConduitServer" #database_path = "/home/timo/MyConduitServer"
port = 14004 # You should probably leave this at 0.0.0.0
address = "0.0.0.0" address = "0.0.0.0"
# Not necessary when using a reverse proxy # TLS support
# Note: Not necessary when using a reverse proxy:
#[global.tls] #[global.tls]
#certs = "/etc/letsencrypt/live/your.server.name/fullchain.pem" #certs = "/etc/letsencrypt/live/your.server.name/fullchain.pem"
#key = "/etc/letsencrypt/live/your.server.name/privkey.pem" #key = "/etc/letsencrypt/live/your.server.name/privkey.pem"

View File

@ -2977,9 +2977,11 @@ pub fn send_event_to_device_route(
} }
#[get("/_matrix/media/r0/config")] #[get("/_matrix/media/r0/config")]
pub fn get_media_config_route() -> ConduitResult<get_media_config::Response> { pub fn get_media_config_route(
db: State<'_, Database>,
) -> ConduitResult<get_media_config::Response> {
Ok(get_media_config::Response { Ok(get_media_config::Response {
upload_size: (20_u32 * 1024 * 1024).into(), // 20 MB upload_size: db.globals.max_request_size().into(),
} }
.into()) .into())
} }

View File

@ -1,7 +1,7 @@
use std::convert::TryInto;
use crate::{utils, Error, Result}; use crate::{utils, Error, Result};
use ruma::ServerName; use ruma::ServerName;
use std::convert::TryInto;
pub const COUNTER: &str = "c"; pub const COUNTER: &str = "c";
pub struct Globals { pub struct Globals {
@ -9,6 +9,7 @@ pub struct Globals {
keypair: ruma::signatures::Ed25519KeyPair, keypair: ruma::signatures::Ed25519KeyPair,
reqwest_client: reqwest::Client, reqwest_client: reqwest::Client,
server_name: Box<ServerName>, server_name: Box<ServerName>,
max_request_size: u32,
registration_disabled: bool, registration_disabled: bool,
encryption_disabled: bool, encryption_disabled: bool,
} }
@ -32,7 +33,12 @@ impl Globals {
.unwrap_or("localhost") .unwrap_or("localhost")
.to_string() .to_string()
.try_into() .try_into()
.map_err(|_| Error::BadConfig("Invalid server name found."))?, .map_err(|_| Error::BadConfig("Invalid server_name."))?,
max_request_size: config
.get_int("max_request_size")
.unwrap_or(20 * 1024 * 1024) // Default to 20 MB
.try_into()
.map_err(|_| Error::BadConfig("Invalid max_request_size."))?,
registration_disabled: config.get_bool("registration_disabled").unwrap_or(false), registration_disabled: config.get_bool("registration_disabled").unwrap_or(false),
encryption_disabled: config.get_bool("encryption_disabled").unwrap_or(false), encryption_disabled: config.get_bool("encryption_disabled").unwrap_or(false),
}) })
@ -69,6 +75,10 @@ impl Globals {
self.server_name.as_ref() self.server_name.as_ref()
} }
pub fn max_request_size(&self) -> u32 {
self.max_request_size
}
pub fn registration_disabled(&self) -> bool { pub fn registration_disabled(&self) -> bool {
self.registration_disabled self.registration_disabled
} }

View File

@ -11,8 +11,6 @@ use ruma::{api::Endpoint, DeviceId, UserId};
use std::{convert::TryInto, io::Cursor, ops::Deref}; use std::{convert::TryInto, io::Cursor, ops::Deref};
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
const MESSAGE_LIMIT: u64 = 20 * 1024 * 1024; // 20 MB
/// This struct converts rocket requests into ruma structs by converting them into http requests /// This struct converts rocket requests into ruma structs by converting them into http requests
/// first. /// first.
pub struct Ruma<T> { pub struct Ruma<T> {
@ -40,13 +38,12 @@ impl<'a, T: Endpoint> FromTransformedData<'a> for Ruma<T> {
) -> FromDataFuture<'a, Self, Self::Error> { ) -> FromDataFuture<'a, Self, Self::Error> {
Box::pin(async move { Box::pin(async move {
let data = rocket::try_outcome!(outcome.owned()); let data = rocket::try_outcome!(outcome.owned());
let (user_id, device_id) = if T::METADATA.requires_authentication {
let db = request let db = request
.guard::<State<'_, crate::Database>>() .guard::<State<'_, crate::Database>>()
.await .await
.expect("database was loaded"); .expect("database was loaded");
let (user_id, device_id) = if T::METADATA.requires_authentication {
// Get token from header or query value // Get token from header or query value
let token = match request let token = match request
.headers() .headers()
@ -76,7 +73,8 @@ impl<'a, T: Endpoint> FromTransformedData<'a> for Ruma<T> {
http_request = http_request.header(header.name.as_str(), &*header.value); http_request = http_request.header(header.name.as_str(), &*header.value);
} }
let mut handle = data.open().take(MESSAGE_LIMIT); let limit = db.globals.max_request_size();
let mut handle = data.open().take(limit.into());
let mut body = Vec::new(); let mut body = Vec::new();
handle.read_to_end(&mut body).await.unwrap(); handle.read_to_end(&mut body).await.unwrap();