feat(server): improve random_url config handling (#122)

* feat(server): improve random_url config handling

* log deprecation warnings after hot reload of config

* refactor(config): adjust config files

* tests(config): add test for deprecation codepath

* remove unnecessary to_string()

* style: delete empty line

* refactor(server): clean up random_url config handling

* refactor(config): update configs accordingly to deprecated random_url.enabled

---------

Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
This commit is contained in:
Helmut K. C. Tessarek 2023-08-20 14:32:41 -04:00 committed by GitHub
parent 679a26475a
commit d2d07ad345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 155 additions and 143 deletions

View File

@ -42,9 +42,9 @@ Command line tool is available at https://github.com/orhun/rustypaste-cli
content_type = "text/plain; charset=utf-8"
[paste]
random_url = { enabled = true, type = "petname", words = 2, separator = "-" }
#random_url = { enabled = true, type = "alphanumeric", length = 8 }
#random_url = { enabled = true, type = "alphanumeric", length = 6, suffix_mode = true }
random_url = { type = "petname", words = 2, separator = "-" }
#random_url = { type = "alphanumeric", length = 8 }
#random_url = { type = "alphanumeric", length = 6, suffix_mode = true }
default_extension = "txt"
mime_override = [
{ mime = "image/jpeg", regex = "^.*\\.jpg$" },

View File

@ -15,8 +15,8 @@ file = "landing_page.html"
content_type = "text/html; charset=utf-8"
[paste]
random_url = { enabled = true, type = "petname", words = 2, separator = "-" }
#random_url = { enabled = true, type = "alphanumeric", length = 8 }
random_url = { type = "petname", words = 2, separator = "-" }
#random_url = { type = "alphanumeric", length = 8 }
default_extension = "txt"
mime_override = [
{ mime = "image/jpeg", regex = "^.*\\.jpg$" },

View File

@ -1,9 +1,9 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = true, type = "petname", words = 2, separator = "-" }
random_url = { type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,9 +1,8 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,9 +1,8 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = true

View File

@ -6,6 +6,6 @@ auth_token = "rustypasteisawesome"
expose_list = true
[paste]
random_url = { enabled = true, type = "petname", words = 2, separator = "-" }
random_url = { type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = true

View File

@ -1,9 +1,8 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,9 +1,8 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,9 +1,8 @@
[server]
address="127.0.0.1:8000"
max_content_length="10kb"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10kb"
upload_path = "./upload"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -4,6 +4,6 @@ max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = true, type = "alphanumeric", length = "6", suffix_mode = true }
random_url = { type = "alphanumeric", length = "6", suffix_mode = true }
default_extension = "txt"
duplicate_files = true

View File

@ -1,9 +1,9 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = true, type = "alphanumeric", length = "8" }
random_url = { type = "alphanumeric", length = "8" }
default_extension = "txt"
duplicate_files = true

View File

@ -1,10 +1,9 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
timeout="60s"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
timeout = "60s"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,10 +1,9 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
auth_tokens=["token1", "token2", "rustypasteisawesome", "token4"]
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
auth_tokens = ["token1", "token2", "rustypasteisawesome", "token4"]
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,10 +1,9 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
auth_token="rustypasteisawesome"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
auth_token = "rustypasteisawesome"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,10 +1,10 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = true, type = "petname", words = 2, separator = "-" }
random_url = { type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = true
delete_expired_files = { enabled = true, interval = "2s" }

View File

@ -1,9 +1,8 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "bin"
duplicate_files = false

View File

@ -1,14 +1,13 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[landing_page]
text="awesome_landing"
file="page.txt"
text = "awesome_landing"
file = "page.txt"
content_type = "text/plain; charset=utf-8"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,13 +1,12 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[landing_page]
text="awesome_landing"
text = "awesome_landing"
content_type = "text/plain; charset=utf-8"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,13 +1,10 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = true, type = "petname", words = 2, separator = "-" }
random_url = { type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = true
mime_blacklist = [
"text/html",
"text/xml",
]
mime_blacklist = ["text/html", "text/xml"]

View File

@ -1,10 +1,10 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = true, type = "petname", words = 2, separator = "-" }
random_url = { type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = true
mime_override = [

View File

@ -1,9 +1,8 @@
[server]
address="127.0.0.1:8000"
max_content_length="10kb"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10kb"
upload_path = "./upload"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -1,9 +1,8 @@
[server]
address="127.0.0.1:8000"
max_content_length="10MB"
upload_path="./upload"
address = "127.0.0.1:8000"
max_content_length = "10MB"
upload_path = "./upload"
[paste]
random_url = { enabled = false, type = "petname", words = 2, separator = "-" }
default_extension = "txt"
duplicate_files = false

View File

@ -32,8 +32,8 @@ If you liked this, consider supporting me: https://donate.orhun.dev <3
landing_page_content_type = "text/plain; charset=utf-8"
[paste]
# random_url = { enabled = true, type = "petname", words = 2, separator = "-" }
random_url = { enabled = true, type = "alphanumeric", length = 6 }
# random_url = { type = "petname", words = 2, separator = "-" }
random_url = { type = "alphanumeric", length = 6 }
default_extension = "txt"
mime_override = [
{ mime = "image/jpeg", regex = "^.*\\.jpg$" },

View File

@ -77,7 +77,7 @@ pub struct LandingPageConfig {
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct PasteConfig {
/// Random URL configuration.
pub random_url: RandomURLConfig,
pub random_url: Option<RandomURLConfig>,
/// Default file extension.
pub default_extension: String,
/// Media type override options.
@ -142,6 +142,13 @@ impl Config {
"[server].landing_page_content_type is deprecated, please use [landing_page].content_type"
);
}
if let Some(random_url) = &self.paste.random_url {
if random_url.enabled.is_some() {
log::warn!(
"[paste].random_url.enabled is deprecated, disable it by commenting out [paste].random_url"
);
}
}
}
}
@ -158,4 +165,19 @@ mod tests {
assert_eq!("0.0.1.1", config.server.address);
Ok(())
}
#[test]
#[allow(deprecated)]
fn test_parse_deprecated_config() -> Result<(), ConfigError> {
let config_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("config.toml");
env::set_var("SERVER__ADDRESS", "0.0.1.1");
let mut config = Config::parse(&config_path)?;
config.paste.random_url = Some(RandomURLConfig {
enabled: Some(true),
..RandomURLConfig::default()
});
assert_eq!("0.0.1.1", config.server.address);
config.warn_deprecation();
Ok(())
}
}

View File

@ -84,6 +84,7 @@ fn setup(config_folder: &Path) -> IoResult<(Data<RwLock<Config>>, ServerConfig,
if let Err(e) = config_sender.send(config) {
log::error!("Failed to send config for the cleanup routine: {}", e)
}
cloned_config.warn_deprecation();
}
Err(e) => {
log::error!("Failed to acquire config: {}", e);

View File

@ -148,15 +148,17 @@ impl Paste {
.unwrap_or(&config.paste.default_extension)
.to_string()
};
if let Some(random_text) = config.paste.random_url.generate() {
if let Some(suffix_mode) = config.paste.random_url.suffix_mode {
if suffix_mode {
extension = format!("{}.{}", random_text, extension);
if let Some(random_url) = &config.paste.random_url {
if let Some(random_text) = random_url.generate() {
if let Some(suffix_mode) = random_url.suffix_mode {
if suffix_mode {
extension = format!("{}.{}", random_text, extension);
} else {
file_name = random_text;
}
} else {
file_name = random_text;
}
} else {
file_name = random_text;
}
}
path.set_file_name(file_name);
@ -240,15 +242,17 @@ impl Paste {
/// - If [`random_url.enabled`] is `true`, file name is set to a pet name or random string.
///
/// [`random_url.enabled`]: crate::random::RandomURLConfig::enabled
#[allow(deprecated)]
pub fn store_url(&self, expiry_date: Option<u128>, config: &Config) -> IoResult<String> {
let data = str::from_utf8(&self.data)
.map_err(|e| IoError::new(IoErrorKind::Other, e.to_string()))?;
let url = Url::parse(data).map_err(|e| IoError::new(IoErrorKind::Other, e.to_string()))?;
let file_name = config
.paste
.random_url
.generate()
.unwrap_or_else(|| self.type_.get_dir());
let mut file_name = self.type_.get_dir();
if let Some(random_url) = &config.paste.random_url {
if let Some(random_text) = random_url.generate() {
file_name = random_text;
}
}
let mut path = self
.type_
.get_path(&config.server.upload_path)
@ -273,16 +277,17 @@ mod tests {
use std::time::Duration;
#[actix_rt::test]
#[allow(deprecated)]
async fn test_paste_data() -> Result<(), Error> {
let mut config = Config::default();
config.server.upload_path = env::current_dir()?;
config.paste.random_url = RandomURLConfig {
enabled: true,
config.paste.random_url = Some(RandomURLConfig {
enabled: Some(true),
words: Some(3),
separator: Some(String::from("_")),
type_: RandomURLType::PetName,
..RandomURLConfig::default()
};
});
let paste = Paste {
data: vec![65, 66, 67],
type_: PasteType::File,
@ -297,13 +302,12 @@ mod tests {
);
fs::remove_file(file_name)?;
config.paste.random_url = RandomURLConfig {
enabled: true,
config.paste.random_url = Some(RandomURLConfig {
length: Some(4),
type_: RandomURLType::Alphanumeric,
suffix_mode: Some(true),
..RandomURLConfig::default()
};
});
let paste = Paste {
data: vec![116, 101, 115, 115, 117, 115],
type_: PasteType::File,
@ -314,13 +318,12 @@ mod tests {
assert!(file_name.starts_with("foo."));
fs::remove_file(file_name)?;
config.paste.random_url = RandomURLConfig {
enabled: true,
config.paste.random_url = Some(RandomURLConfig {
length: Some(4),
type_: RandomURLType::Alphanumeric,
suffix_mode: Some(true),
..RandomURLConfig::default()
};
});
let paste = Paste {
data: vec![116, 101, 115, 115, 117, 115],
type_: PasteType::File,
@ -331,13 +334,12 @@ mod tests {
assert!(file_name.starts_with(".foo."));
fs::remove_file(file_name)?;
config.paste.random_url = RandomURLConfig {
enabled: true,
config.paste.random_url = Some(RandomURLConfig {
length: Some(4),
type_: RandomURLType::Alphanumeric,
suffix_mode: Some(false),
..RandomURLConfig::default()
};
});
let paste = Paste {
data: vec![116, 101, 115, 115, 117, 115],
type_: PasteType::File,
@ -348,7 +350,7 @@ mod tests {
fs::remove_file(file_name)?;
config.paste.default_extension = String::from("txt");
config.paste.random_url.enabled = false;
config.paste.random_url = None;
let paste = Paste {
data: vec![120, 121, 122],
type_: PasteType::File,
@ -359,13 +361,11 @@ mod tests {
fs::remove_file(file_name)?;
config.paste.default_extension = String::from("bin");
config.paste.random_url.enabled = false;
config.paste.random_url = RandomURLConfig {
enabled: true,
config.paste.random_url = Some(RandomURLConfig {
length: Some(10),
type_: RandomURLType::Alphanumeric,
..RandomURLConfig::default()
};
});
let paste = Paste {
data: vec![120, 121, 122],
type_: PasteType::File,
@ -384,7 +384,7 @@ mod tests {
fs::create_dir_all(paste_type.get_path(&config.server.upload_path))?;
}
config.paste.random_url.enabled = false;
config.paste.random_url = None;
let paste = Paste {
data: vec![116, 101, 115, 116],
type_: PasteType::Oneshot,
@ -397,7 +397,10 @@ mod tests {
assert_eq!("test", fs::read_to_string(&file_path)?);
fs::remove_file(file_path)?;
config.paste.random_url.enabled = true;
config.paste.random_url = Some(RandomURLConfig {
enabled: Some(true),
..RandomURLConfig::default()
});
let url = String::from("https://orhun.dev/");
let paste = Paste {
data: url.as_bytes().to_vec(),

View File

@ -4,7 +4,8 @@ use rand::{distributions::Alphanumeric, Rng};
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct RandomURLConfig {
/// Use a random name instead of original file names.
pub enabled: bool,
#[deprecated(note = "disable by commenting out [paste].random_url")]
pub enabled: Option<bool>,
/// Count of words that pet name will include.
pub words: Option<u8>,
/// Separator between the words.
@ -18,24 +19,24 @@ pub struct RandomURLConfig {
pub suffix_mode: Option<bool>,
}
#[allow(deprecated)]
impl RandomURLConfig {
/// Generates and returns a random URL (if `enabled`).
pub fn generate(&self) -> Option<String> {
if self.enabled {
Some(match self.type_ {
RandomURLType::PetName => petname::petname(
self.words.unwrap_or(2),
self.separator.as_deref().unwrap_or("-"),
),
RandomURLType::Alphanumeric => rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(self.length.unwrap_or(8))
.map(char::from)
.collect::<String>(),
})
} else {
None
if !self.enabled.unwrap_or(true) {
return None;
}
Some(match self.type_ {
RandomURLType::PetName => petname::petname(
self.words.unwrap_or(2),
self.separator.as_deref().unwrap_or("-"),
),
RandomURLType::Alphanumeric => rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(self.length.unwrap_or(8))
.map(char::from)
.collect::<String>(),
})
}
}
@ -59,10 +60,11 @@ impl Default for RandomURLType {
mod tests {
use super::*;
#[allow(deprecated)]
#[test]
fn test_generate_url() {
let random_config = RandomURLConfig {
enabled: true,
enabled: Some(true),
words: Some(3),
separator: Some(String::from("~")),
type_: RandomURLType::PetName,
@ -74,7 +76,6 @@ mod tests {
assert_eq!(3, random_url.split('~').count());
let random_config = RandomURLConfig {
enabled: true,
length: Some(21),
type_: RandomURLType::Alphanumeric,
..RandomURLConfig::default()
@ -85,7 +86,7 @@ mod tests {
assert_eq!(21, random_url.len());
let random_config = RandomURLConfig {
enabled: false,
enabled: Some(false),
..RandomURLConfig::default()
};
assert!(random_config.generate().is_none());

View File

@ -763,6 +763,7 @@ mod tests {
}
#[actix_web::test]
#[allow(deprecated)]
async fn test_upload_duplicate_file() -> Result<(), Error> {
let test_upload_dir = "test_upload";
fs::create_dir(test_upload_dir)?;
@ -770,11 +771,11 @@ mod tests {
let mut config = Config::default();
config.server.upload_path = PathBuf::from(&test_upload_dir);
config.paste.duplicate_files = Some(false);
config.paste.random_url = RandomURLConfig {
enabled: true,
config.paste.random_url = Some(RandomURLConfig {
enabled: Some(true),
type_: RandomURLType::Alphanumeric,
..Default::default()
};
});
let app = test::init_service(
App::new()