add option to not ignore query params
This commit is contained in:
@@ -5,5 +5,7 @@ services:
|
|||||||
target: final
|
target: final
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
|
environment:
|
||||||
|
URLS_TXT_IGNORE_QUERY_PARAMS: true # change to `false` to include query params
|
||||||
volumes:
|
volumes:
|
||||||
- "./urls.txt:/urls.txt"
|
- "./urls.txt:/urls.txt"
|
||||||
|
|||||||
@@ -63,9 +63,11 @@ for example, for the link <http://pls.cx/🤬> the following line is in my urls.
|
|||||||
|
|
||||||
trailing slashes are ignored.
|
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?
|
## why?
|
||||||
|
|
||||||
|
|||||||
+31
-10
@@ -13,13 +13,32 @@ enum ResponseCode {
|
|||||||
NotFound,
|
NotFound,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove query parameters and trailing slashes.
|
#[derive(Clone, Copy)]
|
||||||
/// Makes all paths lowercase.
|
struct Config {
|
||||||
fn normalise_path(path: &str) -> String {
|
ignore_query_params: bool,
|
||||||
let mut path = path
|
}
|
||||||
|
|
||||||
|
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('?')
|
.split('?')
|
||||||
.next()
|
.next()
|
||||||
.expect("split operation returns at least one substring");
|
.expect("split operation returns at least one substring");
|
||||||
|
}
|
||||||
|
|
||||||
while path.len() > 1
|
while path.len() > 1
|
||||||
&& let Some('/') = path.chars().next_back()
|
&& let Some('/') = path.chars().next_back()
|
||||||
{
|
{
|
||||||
@@ -49,7 +68,7 @@ async fn simple_response(mut socket: BufStream<TcpStream>, rc: ResponseCode) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_socket(mut socket: BufStream<TcpStream>, urlmap: Arc<HashMap<String, String>>) {
|
async fn process_socket(mut socket: BufStream<TcpStream>, urlmap: Arc<HashMap<String, String>>, config: &Config) {
|
||||||
let mut request_line = String::default();
|
let mut request_line = String::default();
|
||||||
if let Err(e) = socket.read_line(&mut request_line).await {
|
if let Err(e) = socket.read_line(&mut request_line).await {
|
||||||
println!("process_request: failed to read line: {e}");
|
println!("process_request: failed to read line: {e}");
|
||||||
@@ -63,7 +82,7 @@ async fn process_socket(mut socket: BufStream<TcpStream>, urlmap: Arc<HashMap<St
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = normalise_path(path);
|
let path = normalise_path(path, config);
|
||||||
|
|
||||||
if http_method != "GET" {
|
if http_method != "GET" {
|
||||||
println!("process_request: forbidden method: http_method={http_method}");
|
println!("process_request: forbidden method: http_method={http_method}");
|
||||||
@@ -110,9 +129,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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();
|
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() {
|
if url_pair.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -132,7 +153,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Err(format!("Unable to parse line: '{}'", url_pair))?
|
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);
|
let urlmap = Arc::new(urlmap);
|
||||||
@@ -143,7 +164,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let (socket, _addr) = listener.accept().await?;
|
let (socket, _addr) = listener.accept().await?;
|
||||||
let urlmap = urlmap.clone();
|
let urlmap = urlmap.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
process_socket(BufStream::new(socket), urlmap).await;
|
process_socket(BufStream::new(socket), urlmap, &config).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user