feat(server): support handling spaces in filenames (#107)
* feat(server): add url encoding - Introduced an option to enable encoding for filenames in the returned URL. - Modified the encoding approach to specifically target whitespaces, replacing them with `%20`. - Included unit tests to validate this encoding approach. - Added fixture tests for broader functional verification. - Removed the `urlencoding` dependency from `Cargo.toml`. * Refactor code and fixtures for better compliance and consistency - Fixed errors in the fixture configuration to ensure tests run as expected. - Reformatted line endings for consistency across the codebase. - Made necessary adjustments to adhere to Clippy's recommendations. * Enhance whitespace handling options for filenames - Implemented a configuration choice for space handling in filenames: encode, replace with underscores or none. - Added corresponding unit and fixture tests. * Remove redundant function call Fixed misplaced line as per @tessus's review feedback, preventing duplicate handling of spaces in filenames. * Delete test file with spaces.txt * Refactor filename space handling - Introduced `SpaceHandling` enum to manage filename spaces. - Updated server.rs and paste.rs to utilize the new method. - Added unit tests for the new filename handling method. - Adjusted fixture tests to reflect these changes. * Move filename processing into `SpaceHandling` enum - Relocated filename processing logic to reside within the `SpaceHandling` enum, enhancing encapsulation. - Updated calls in `server.rs` and `paste.rs` to use the new method structure. - Adjusted unit tests to align with the refactored function location and call pattern. * Refactor based on review suggestions - Incorporated the inline suggestions made by @tessus, removing the unnecessary one-line assignments. - Ensured the code adheres to Rust guidelines by running clippy and fmt. * chore(deps): revert changes in Cargo.lock * chore(config): replace spaces as default * refactor(config): move SpaceHandling to config module --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
This commit is contained in:
parent
38d76fcb0f
commit
95379c9f66
|
@ -14,6 +14,7 @@ expose_list = false
|
|||
# "super_secret_token1",
|
||||
# "super_secret_token2",
|
||||
#]
|
||||
handle_spaces = "replace" # or "replace"
|
||||
|
||||
[landing_page]
|
||||
text = """
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
[server]
|
||||
address="127.0.0.1:8000"
|
||||
max_content_length="10MB"
|
||||
upload_path="./upload"
|
||||
handle_spaces = "replace"
|
||||
|
||||
[paste]
|
||||
#random_url = { enabled = false, type = "alphanumeric", length = 6, suffix_mode = true }
|
||||
default_extension = "txt"
|
||||
duplicate_files = true
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
content="test data for space replacement"
|
||||
|
||||
setup() {
|
||||
echo "$content" > "test file with spaces.txt"
|
||||
}
|
||||
|
||||
run_test() {
|
||||
# Upload the file and get the URL.
|
||||
replaced_url=$(curl -s -F "file=@test file with spaces.txt" localhost:8000)
|
||||
|
||||
# Ensure the URL contains underscores instead of spaces.
|
||||
expected_url="http://localhost:8000/test_file_with_spaces.txt"
|
||||
test "$replaced_url" = "$expected_url"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm "test file with spaces.txt"
|
||||
rm -r upload
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
[server]
|
||||
address="127.0.0.1:8000"
|
||||
max_content_length="10MB"
|
||||
upload_path="./upload"
|
||||
handle_spaces = "encode"
|
||||
|
||||
[paste]
|
||||
#random_url = { enabled = false, type = "alphanumeric", length = 6, suffix_mode = true }
|
||||
default_extension = "txt"
|
||||
duplicate_files = true
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
content="test data for URL encoding"
|
||||
|
||||
setup() {
|
||||
echo "$content" > "test file with spaces.txt"
|
||||
}
|
||||
|
||||
run_test() {
|
||||
# Upload the file and get the URL.
|
||||
encoded_url=$(curl -s -F "file=@test file with spaces.txt" localhost:8000)
|
||||
|
||||
# Ensure the URL is encoded correctly.
|
||||
expected_url="http://localhost:8000/test%20file%20with%20spaces.txt"
|
||||
test "$encoded_url" = "$expected_url"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm "test file with spaces.txt"
|
||||
rm -r upload
|
||||
}
|
|
@ -58,10 +58,32 @@ pub struct ServerConfig {
|
|||
/// Landing page content-type.
|
||||
#[deprecated(note = "use the [landing_page] table")]
|
||||
pub landing_page_content_type: Option<String>,
|
||||
/// Handle spaces either via encoding or replacing.
|
||||
pub handle_spaces: Option<SpaceHandlingConfig>,
|
||||
/// Path of the JSON index.
|
||||
pub expose_list: Option<bool>,
|
||||
}
|
||||
|
||||
/// Enum representing different strategies for handling spaces in filenames.
|
||||
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum SpaceHandlingConfig {
|
||||
/// Represents encoding spaces (e.g., using "%20").
|
||||
Encode,
|
||||
/// Represents replacing spaces with underscores.
|
||||
Replace,
|
||||
}
|
||||
|
||||
impl SpaceHandlingConfig {
|
||||
/// Processes the given filename based on the specified space handling strategy.
|
||||
pub fn process_filename(&self, file_name: &str) -> String {
|
||||
match self {
|
||||
Self::Encode => file_name.replace(' ', "%20"),
|
||||
Self::Replace => file_name.replace(' ', "_"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Landing page configuration.
|
||||
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LandingPageConfig {
|
||||
|
@ -180,4 +202,13 @@ mod tests {
|
|||
config.warn_deprecation();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_space_handling() {
|
||||
let processed_filename =
|
||||
SpaceHandlingConfig::Replace.process_filename("file with spaces.txt");
|
||||
assert_eq!("file_with_spaces.txt", processed_filename);
|
||||
let encoded_filename = SpaceHandlingConfig::Encode.process_filename("file with spaces.txt");
|
||||
assert_eq!("file%20with%20spaces.txt", encoded_filename);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ impl Paste {
|
|||
}
|
||||
}
|
||||
}
|
||||
let file_name = match PathBuf::from(file_name)
|
||||
let mut file_name = match PathBuf::from(file_name)
|
||||
.file_name()
|
||||
.and_then(|v| v.to_str())
|
||||
{
|
||||
|
@ -117,6 +117,9 @@ impl Paste {
|
|||
Some(v) => v.to_string(),
|
||||
None => String::from("file"),
|
||||
};
|
||||
if let Some(handle_spaces_config) = config.server.handle_spaces {
|
||||
file_name = handle_spaces_config.process_filename(&file_name);
|
||||
}
|
||||
let mut path = self
|
||||
.type_
|
||||
.get_path(&config.server.upload_path)
|
||||
|
|
|
@ -252,7 +252,7 @@ async fn upload(
|
|||
data: bytes.to_vec(),
|
||||
type_: paste_type,
|
||||
};
|
||||
let file_name = match paste.type_ {
|
||||
let mut file_name = match paste.type_ {
|
||||
PasteType::File | PasteType::Oneshot => {
|
||||
let config = config
|
||||
.read()
|
||||
|
@ -277,6 +277,12 @@ async fn upload(
|
|||
Byte::from_bytes(paste.data.len() as u128).get_appropriate_unit(false),
|
||||
host
|
||||
);
|
||||
let config = config
|
||||
.read()
|
||||
.map_err(|_| error::ErrorInternalServerError("cannot acquire config"))?;
|
||||
if let Some(handle_spaces_config) = config.server.handle_spaces {
|
||||
file_name = handle_spaces_config.process_filename(&file_name);
|
||||
}
|
||||
urls.push(format!("{}/{}\n", server_url, file_name));
|
||||
} else {
|
||||
log::warn!("{} sent an invalid form field", host);
|
||||
|
|
Loading…
Reference in New Issue