From 26b4b20c1d3dc12e6ba49f858d3078fda5c3d5ba Mon Sep 17 00:00:00 2001 From: Emi Simpson Date: Tue, 2 Nov 2021 17:19:53 -0400 Subject: [PATCH] [web] [WIP] Re-enable url generation --- web/src/main.rs | 88 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/web/src/main.rs b/web/src/main.rs index ac5d451..7a8e4ea 100644 --- a/web/src/main.rs +++ b/web/src/main.rs @@ -3,6 +3,7 @@ pub mod contrast; pub mod statics; pub mod configuration; +use std::collections::HashMap; use crate::configuration::Conf; use std::io::IoSlice; use crate::statics::StaticAsset; @@ -29,29 +30,6 @@ use image::{DynamicImage, ImageOutputFormat}; #[cfg(feature = "ogp_images")] use ogp_images::render_today; -/* Ill deal with this later -async fn create_link( - settings: &InstanceSettings, - form: HashMap, -) -> String { - let mut weights = vec![0; settings.pronoun_list.len()]; - for (k, v) in form.iter() { - if let Ok(i) = k.parse::() { - let w = v.parse::().map_err(|_| Error::InvlaidPrefString)?; - if i < weights.len() - 1 { - weights[i] = w; - } - } - } - let prefs = InstanceSettings::create_preferences(&weights); - let pref_string = prefs.as_prefstring(); - let url = match form.get("name") { - Some(name) if !name.is_empty() => format!("/{}/{}", name, pref_string), - _ => format!("/{}", pref_string), - }; - url -}*/ - const NOT_FOUND: &[u8] = include_bytes!("../templates/404.html"); /// Handles initialization, and runs top-level routing based on cli args @@ -189,7 +167,7 @@ fn route_request(req: &ScgiRequest) -> Route { "GET" => (), // All POST requests are met with link generation - "POST" => return Route::GenerateLink, + "POST" => return Route::GenerateLink(String::from_utf8_lossy(&req.body).into_owned()), // No other methods are supported _ => return Route::BadRequest(BadRequest::MethodNotAllowed), @@ -289,7 +267,7 @@ enum Route { SendThumbnail(Option, Option), /// Generate a link to the appropriate pronoun page based on the user's inputs. - GenerateLink, //TODO + GenerateLink(String), /// There was a problem with the user's request, and an error page should be sent BadRequest(BadRequest), @@ -306,6 +284,9 @@ enum BadRequest { /// Happens when [`ParseError::PrefstringExceedsPronounCount`] is raised PrefsExceedPronounCount, + /// The data sent in a form was malformed. The string is the part that failed to parse + BadFormData(String), + /// Happens when the user's preferences specify that no pronouns should be used /// /// Triggered by a [`ParseError::EmptyWeightedTable`] @@ -324,8 +305,8 @@ impl Route { Route::send_pronoun_page(name, prefs, url, conf), Route::SendThumbnail(name, prefs) => Route::send_thumbnail(name, prefs, settings), - Route::GenerateLink => - Route::generate_link(settings), + Route::GenerateLink(body) => + Route::generate_link(body, settings), Route::BadRequest(error) => Ok(Route::bad_request(error, settings)), }; @@ -388,9 +369,42 @@ impl Route { /// The method for the [`Route::GenerateLink`] route fn generate_link( - _settings: &InstanceSettings, + body: String, + settings: &InstanceSettings, ) -> Result { - todo!() + let form = body.split('&') + .filter_map(|entry| { + let mut split = entry.split('='); + split.next().map(|key| ( + key, + split.next().unwrap_or("") + )) + }) + .collect::>(); + + let mut weights = vec![0; settings.pronoun_list.len()]; + for (k, v) in form.iter() { + if let Ok(i) = k.parse::() { + let w = v.parse::().map_err(|_| BadRequest::BadFormData((*v).into()))?; + if i < weights.len() - 1 { + weights[i] = w; + } + } + } + let prefs = InstanceSettings::create_preferences(&weights); + let pref_string = prefs.as_prefstring(); + let url = match form.get("name") { + Some(name) if !name.is_empty() => format!("/{}/{}", name, pref_string), + _ => format!("/{}", pref_string), + }; + + Ok(Response { + status: b"303 See Other", + headers: Cow::Owned(vec![ + (&b"Location"[..], url.into_bytes().into()) + ]), + body: Cow::Borrowed(b""), + }) } /// The method for the [`Route::BadRequest`] route @@ -419,6 +433,22 @@ impl Route { body: NOT_FOUND.into(), } }, + BadRequest::BadFormData(yuckers) => { + let body = ErrorPage::from_msg( + &format!( + "yeah that's some stinky form data you got there: {}", + yuckers, + ) + ); + + Response { + status: b"400", + headers: Cow::Borrowed(&[ + (b"Pretty-Gross", Cow::Borrowed(b"imo")), + ]), + body: body.into(), + } + }, BadRequest::PrefsExceedPronounCount => { let body = ErrorPage::from_msg( "Yoinkers Kersploinkers!! You know about more pronouns than \