Rewrite server and client using Hyper

This commit is contained in:
spikecodes
2021-03-17 15:30:33 -07:00
parent 4b1195f221
commit b14b4ff551
11 changed files with 623 additions and 410 deletions

View File

@@ -1,7 +1,12 @@
use std::collections::HashMap;
// CRATES
use crate::server::ResponseExt;
use crate::utils::{redirect, template, Preferences};
use askama::Template;
use tide::{http::Cookie, Request};
use cookie::Cookie;
use futures_lite::StreamExt;
use hyper::{Body, Request, Response};
use time::{Duration, OffsetDateTime};
// STRUCTS
@@ -11,7 +16,7 @@ struct SettingsTemplate {
prefs: Preferences,
}
#[derive(serde::Deserialize, Default)]
#[derive(serde::Deserialize, Default, Debug)]
#[serde(default)]
pub struct Form {
theme: Option<String>,
@@ -27,29 +32,49 @@ pub struct Form {
// FUNCTIONS
// Retrieve cookies from request "Cookie" header
pub async fn get(req: Request<()>) -> tide::Result {
pub async fn get(req: Request<Body>) -> Result<Response<Body>, String> {
template(SettingsTemplate { prefs: Preferences::new(req) })
}
// Set cookies using response "Set-Cookie" header
pub async fn set(mut req: Request<()>) -> tide::Result {
let form: Form = req.body_form().await.unwrap_or_default();
pub async fn set(req: Request<Body>) -> Result<Response<Body>, String> {
// Split the body into parts
let (parts, mut body) = req.into_parts();
// Grab existing cookies
let mut cookies = Vec::new();
for header in parts.headers.get_all("Cookie") {
if let Ok(cookie) = Cookie::parse(header.to_str().unwrap_or_default()) {
cookies.push(cookie);
}
}
// Aggregate the body...
// let whole_body = hyper::body::aggregate(req).await.map_err(|e| e.to_string())?;
let body_bytes = body
.try_fold(Vec::new(), |mut data, chunk| {
data.extend_from_slice(&chunk);
Ok(data)
})
.await
.map_err(|e| e.to_string())?;
let form = url::form_urlencoded::parse(&body_bytes).collect::<HashMap<_, _>>();
let mut res = redirect("/settings".to_string());
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "show_nsfw"];
let values = vec![form.theme, form.front_page, form.layout, form.wide, form.comment_sort, form.show_nsfw];
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "show_nsfw", "subscriptions"];
for (i, name) in names.iter().enumerate() {
match values.get(i) {
for name in names {
match form.get(name) {
Some(value) => res.insert_cookie(
Cookie::build(name.to_owned(), value.to_owned().unwrap_or_default())
Cookie::build(name.to_owned(), value.to_owned())
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.finish(),
),
None => res.remove_cookie(Cookie::named(name.to_owned())),
None => res.remove_cookie(name.to_string()),
};
}
@@ -57,29 +82,41 @@ pub async fn set(mut req: Request<()>) -> tide::Result {
}
// Set cookies using response "Set-Cookie" header
pub async fn restore(req: Request<()>) -> tide::Result {
let form: Form = req.query()?;
pub async fn restore(req: Request<Body>) -> Result<Response<Body>, String> {
// Split the body into parts
let (parts, _) = req.into_parts();
let path = match form.redirect {
// Grab existing cookies
let mut cookies = Vec::new();
for header in parts.headers.get_all("Cookie") {
if let Ok(cookie) = Cookie::parse(header.to_str().unwrap_or_default()) {
cookies.push(cookie);
}
}
let query = parts.uri.query().unwrap_or_default().as_bytes();
let form = url::form_urlencoded::parse(query).collect::<HashMap<_, _>>();
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "show_nsfw", "subscriptions"];
let path = match form.get("redirect") {
Some(value) => format!("/{}/", value),
None => "/".to_string(),
};
let mut res = redirect(path);
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "show_nsfw", "subscriptions"];
let values = vec![form.theme, form.front_page, form.layout, form.wide, form.comment_sort, form.show_nsfw, form.subscriptions];
for (i, name) in names.iter().enumerate() {
match values.get(i) {
for name in names {
match form.get(name) {
Some(value) => res.insert_cookie(
Cookie::build(name.to_owned(), value.to_owned().unwrap_or_default())
Cookie::build(name.to_owned(), value.to_owned())
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.finish(),
),
None => res.remove_cookie(Cookie::named(name.to_owned())),
None => res.remove_cookie(name.to_string()),
};
}