aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorDennis Eriksen <d@ennis.no>2023-07-01 12:19:44 +0200
committerDennis Eriksen <d@ennis.no>2023-07-01 12:19:44 +0200
commit1caa728cb46db4d334204b652a46c27f2fc68ac4 (patch)
treeda2131f06cab3f4d2973c938fcb48079b89fdca3 /src/main.rs
parentthis now actually works, and can be used. TODO: cleanup and make it pretty (diff)
downloadpurl-rs-1caa728cb46db4d334204b652a46c27f2fc68ac4.tar.gz
Cleaning up. Starting with response-function.
Diffstat (limited to '')
-rw-r--r--src/main.rs93
1 files changed, 62 insertions, 31 deletions
diff --git a/src/main.rs b/src/main.rs
index 439f8fd..28e5cd7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,4 @@
-//use std::io::Write;
+use std::io::Write;
use dumb_cgi::{Request, EmptyResponse, Query};
use postgres::{Client, NoTls};
use std::process::exit;
@@ -9,6 +9,7 @@ use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
+
// Get URL from database
fn get_url(dburl:&str, short:&str, update:bool) -> Result<String, postgres::Error> {
// Connect to db
@@ -33,28 +34,56 @@ fn insert_short(dburl:String, url: &str, short: &str, user: &str) -> Result<u64,
client.close()?;
Ok(n)
}
-// Do the redirect
-// return std::io::Result<()> so we can use ? -
-// https://doc.rust-lang.org/std/result/#the-question-mark-operator-
-fn redirect(code:u16, url:&str) {
- EmptyResponse::new(code)
- .with_header("Location", url)
- .with_content_type("text/plain")
- .with_body(
- format!("Redirecting to {}\n", url))
- .respond().unwrap();
- exit(0);
+
+fn status<'a>(code:u16) -> &'a str {
+ // I've only implemented statuscodes I *might* use
+ return match code {
+ 200 => "OK",
+ 201 => "Created",
+ 202 => "Accepted",
+ 204 => "No Content",
+ 301 => "Moved Permanently",
+ 302 => "Found",
+ 304 => "Not Modified",
+ 307 => "Temporary Redirect",
+ 308 => "Permanent Redirect",
+ 400 => "Bad Request",
+ 401 => "Unauthorized",
+ 402 => "Payment Required",
+ 403 => "Forbidden",
+ 404 => "Not Found",
+ 405 => "Method Not Allowed",
+ 406 => "Not Acceptableo",
+ 410 => "Gone",
+ 414 => "URI Too Long",
+ 500 => "Internal Server Error",
+ 501 => "Not Implemented",
+ 503 => "Service Unavailable",
+ 508 => "Loop Detected",
+ _ => "Not Found",
+ };
}
-fn error(code:u16, msg:&str) {
- EmptyResponse::new(code)
- .with_content_type("text/plain")
- .with_body(
- format!("{} {}\n", code, msg))
- .respond().unwrap();
+// Do the redirect
+fn respond(code:u16, body:&str) {
+ let mut r = EmptyResponse::new(code)
+ .with_content_type("text/plain");
+
+ if code >= 300 {
+ write!(&mut r, "{} {}\n\n", code, status(code)).unwrap();
+ }
+
+ if (300..399).contains(&code) && Url::parse(body).is_ok() {
+ r.add_header("Location", body);
+ }
+
+ write!(&mut r, "{}\n", body).unwrap();
+
+ r.respond().unwrap();
exit(0);
}
+
// Print form
fn print_form() {
let html = r#"<html>
@@ -96,6 +125,8 @@ fn gen_short() -> String {
// Do the dirty
+// return std::io::Result<()> so we can use ? -
+// https://doc.rust-lang.org/std/result/#the-question-mark-operator-
fn main() -> std::io::Result<()> {
// short = ID for shortened url
@@ -128,26 +159,26 @@ fn main() -> std::io::Result<()> {
// Make SURE docuri is a valid short
let shortregex = Regex::new(r"^[a-zA-Z0-9_-]+$").unwrap();
if !shortregex.is_match(docuri) {
- error(400, "Bad Request");
+ respond(400, "Bad Request");
}
// Fetch URL from postgres, and redirect or return 404
match get_url(&dburl, docuri, true) {
- Ok(url) => redirect(301, &url),
- Err(_e) => error(404, "Not Found"),
+ Ok(url) => respond(301, &url),
+ Err(_e) => respond(404, "Not Found"),
};
},
"create" => {
match req.query() {
- Query::None => redirect(303, "/purl.cgi"),
+ Query::None => respond(303, "/purl.cgi"),
Query::Some(map) => {
if map.iter().count() != 1 {
- error(400, "Bad Request\n\nIncorrect number of query items");
+ respond(400, "Bad Request\n\nIncorrect number of query items");
}
let url:&str = &map["url"];
if !Url::parse(url).is_ok() {
- error(400, "Bad Request\n\nInvalid url");
+ respond(400, "Bad Request\n\nInvalid url");
}
let user:&str = req.var("REMOTE_USER").unwrap_or("none");
@@ -162,26 +193,26 @@ fn main() -> std::io::Result<()> {
}
// Throw error if we couldn't create a unique short in fire tries
- if i == 5 { error(500, "Could not find unique short"); }
+ if i == 5 { respond(500, "Could not find unique short"); }
}
match insert_short(dburl, url, &short, user) {
- Ok(_v) => error(200, &format!("{}{}", shortprefix, short)),
- Err(_e) => error(400, "looool"),
+ Ok(_v) => respond(200, &format!("{}{}", shortprefix, short)),
+ Err(_e) => respond(400, "looool"),
};
//if n == 1 {
- // error(200, &res);
+ // respond(200, &res);
//} else {
- // error(400, "Bad Request\n\nDunno wtf happened");
+ // respond(400, "Bad Request\n\nDunno wtf happened");
//}
exit(0);
},
- Query::Err(_e) => error(400,"Bad Request\n\nError reading query string"),
+ Query::Err(_e) => respond(400,"Bad Request\n\nError reading query string"),
}
},
- _ => error(400, "Bad Request"),
+ _ => respond(400, "Bad Request"),
}