From 6143633a45f3fc1c69d124270d4c4d9dc1ec9c37 Mon Sep 17 00:00:00 2001 From: Akbar Rahman Date: Fri, 30 Oct 2026 22:43:13 +0000 Subject: [PATCH] add option to not ignore query params --- compose.yaml | 2 ++ readme.md | 6 ++++-- src/main.rs | 41 +++++++++++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/compose.yaml b/compose.yaml index 3764a0c..dcfc3b6 100644 --- a/compose.yaml +++ b/compose.yaml @@ -5,5 +5,7 @@ services: target: final ports: - 3000:3000 + environment: + URLS_TXT_IGNORE_QUERY_PARAMS: true # change to `false` to include query params volumes: - "./urls.txt:/urls.txt" diff --git a/readme.md b/readme.md index f84905a..da87bda 100644 --- a/readme.md +++ b/readme.md @@ -63,9 +63,11 @@ for example, for the link the following line is in my urls. trailing slashes are ignored. -### query parameters are ignored +### query parameters are ignored by default -anything after a question mark character (`?`) are ignored. +anything after a question mark character (`?`) are ignored by default. + +to disable this, set the environment variable `URLS_TXT_IGNORE_QUERY_PARAMS` to `false`. ## why? diff --git a/src/main.rs b/src/main.rs index 830ac34..b12d598 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,13 +13,32 @@ enum ResponseCode { NotFound, } -/// Remove query parameters and trailing slashes. -/// Makes all paths lowercase. -fn normalise_path(path: &str) -> String { - let mut path = path +#[derive(Clone, Copy)] +struct Config { + ignore_query_params: bool, +} + +impl Default for Config { + fn default() -> Self { + Self { + ignore_query_params: match env::var("URLS_TXT_IGNORE_QUERY_PARAMS") { + Ok(val) => val != "false", + _ => true, + } + } + } +} + +fn normalise_path(path: &str, config: &Config) -> String { + let mut path = path; + + if config.ignore_query_params { + path = path .split('?') .next() .expect("split operation returns at least one substring"); + } + while path.len() > 1 && let Some('/') = path.chars().next_back() { @@ -49,7 +68,7 @@ async fn simple_response(mut socket: BufStream, rc: ResponseCode) { }; } -async fn process_socket(mut socket: BufStream, urlmap: Arc>) { +async fn process_socket(mut socket: BufStream, urlmap: Arc>, config: &Config) { let mut request_line = String::default(); if let Err(e) = socket.read_line(&mut request_line).await { println!("process_request: failed to read line: {e}"); @@ -63,7 +82,7 @@ async fn process_socket(mut socket: BufStream, urlmap: Arc Result<(), Box> { } }; - let config = spawn_blocking(move || std::fs::read_to_string(urls_filename)).await??; + let config = Config::default(); + + let urls_file = spawn_blocking(move || std::fs::read_to_string(urls_filename)).await??; let mut urlmap = HashMap::new(); - for url_pair in config.split('\n') { + for url_pair in urls_file.split('\n') { if url_pair.is_empty() { continue; } @@ -132,7 +153,7 @@ async fn main() -> Result<(), Box> { Err(format!("Unable to parse line: '{}'", url_pair))? }; - urlmap.insert(normalise_path(slug), redirect.to_string()); + urlmap.insert(normalise_path(slug, &config), redirect.to_string()); } let urlmap = Arc::new(urlmap); @@ -143,7 +164,7 @@ async fn main() -> Result<(), Box> { let (socket, _addr) = listener.accept().await?; let urlmap = urlmap.clone(); tokio::spawn(async move { - process_socket(BufStream::new(socket), urlmap).await; + process_socket(BufStream::new(socket), urlmap, &config).await; }); } }