From 42aceb2a01e9a265768798299faafb388d5c99a0 Mon Sep 17 00:00:00 2001 From: Jade Date: Fri, 10 Mar 2023 08:18:11 +0100 Subject: [PATCH] Fix error codes, handle bad requests for creation Fix that invalid UTF-8 or continuing the read mid-character crashes server thread. --- src/endpoints/create.rs | 18 +++++++++++++++--- src/endpoints/edit.rs | 15 +++++++++++---- src/endpoints/errors.rs | 10 +++++++--- src/endpoints/pasta.rs | 22 ++++++++++++++++------ src/endpoints/qr.rs | 8 ++++++-- src/endpoints/remove.rs | 8 ++++++-- templates/error.html | 6 +++--- templates/header.html | 2 +- 8 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/endpoints/create.rs b/src/endpoints/create.rs index d3b618f..a725984 100644 --- a/src/endpoints/create.rs +++ b/src/endpoints/create.rs @@ -5,6 +5,8 @@ use crate::util::misc::is_valid_url; use crate::util::pasta_id_converter::CONVERTER; use crate::{AppState, Pasta, ARGS}; use actix_multipart::Multipart; +use actix_web::http::StatusCode; +use actix_web::web::{Bytes, BytesMut, BufMut}; use actix_web::{get, web, Error, HttpResponse, Responder}; use askama::Template; use bytesize::ByteSize; @@ -14,6 +16,8 @@ use rand::Rng; use std::io::Write; use std::time::{SystemTime, UNIX_EPOCH}; +use super::errors::ErrorTemplate; + #[derive(Template)] #[template(path = "index.html")] struct IndexTemplate<'a> { @@ -115,12 +119,20 @@ pub async fn create( } } "content" => { - let mut content = String::from(""); + let mut content = BytesMut::new(); while let Some(chunk) = field.try_next().await? { - content.push_str(std::str::from_utf8(&chunk).unwrap().to_string().as_str()); + content.put(chunk); } if !content.is_empty() { - new_pasta.content = content; + new_pasta.content = match String::from_utf8(content.to_vec()) { + Ok(v) => v, + Err(e) => return Ok(HttpResponse::BadRequest() + .content_type("text/html") + .body(ErrorTemplate { + status_code: StatusCode::BAD_REQUEST, + args: &ARGS + }.render().unwrap())), + }; new_pasta.pasta_type = if is_valid_url(new_pasta.content.as_str()) { String::from("url") diff --git a/src/endpoints/edit.rs b/src/endpoints/edit.rs index bebf25c..bfa4dba 100644 --- a/src/endpoints/edit.rs +++ b/src/endpoints/edit.rs @@ -6,6 +6,7 @@ use crate::util::misc::remove_expired; use crate::util::pasta_id_converter::CONVERTER; use crate::{AppState, Pasta, ARGS}; use actix_multipart::Multipart; +use actix_web::http::StatusCode; use actix_web::{get, post, web, Error, HttpResponse}; use askama::Template; use futures::TryStreamExt; @@ -42,9 +43,12 @@ pub async fn get_edit(data: web::Data, id: web::Path) -> HttpR } } - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } #[post("/edit/{id}")] @@ -97,7 +101,10 @@ pub async fn post_edit( } } - Ok(HttpResponse::Ok() + Ok(HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap())) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap())) } diff --git a/src/endpoints/errors.rs b/src/endpoints/errors.rs index 04626b4..744ede5 100644 --- a/src/endpoints/errors.rs +++ b/src/endpoints/errors.rs @@ -1,4 +1,4 @@ -use actix_web::{Error, HttpResponse}; +use actix_web::{Error, HttpResponse, http::StatusCode}; use askama::Template; use crate::args::{Args, ARGS}; @@ -6,11 +6,15 @@ use crate::args::{Args, ARGS}; #[derive(Template)] #[template(path = "error.html")] pub struct ErrorTemplate<'a> { + pub status_code: StatusCode, pub args: &'a Args, } pub async fn not_found() -> Result { - Ok(HttpResponse::Ok() + Ok(HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap())) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap())) } diff --git a/src/endpoints/pasta.rs b/src/endpoints/pasta.rs index 1017f3b..39ba5a6 100644 --- a/src/endpoints/pasta.rs +++ b/src/endpoints/pasta.rs @@ -7,6 +7,7 @@ use crate::util::misc::remove_expired; use crate::AppState; use crate::util::pasta_id_converter::CONVERTER; +use actix_web::http::StatusCode; use actix_web::{web, HttpResponse}; use askama::Template; use std::time::{SystemTime, UNIX_EPOCH}; @@ -77,9 +78,12 @@ pub async fn getpasta(data: web::Data, id: web::Path) -> HttpR // otherwise // send pasta not found error - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } /// Endpoint for redirection. @@ -136,17 +140,23 @@ pub async fn redirecturl(data: web::Data, id: web::Path) -> Ht return response; // send error if we're trying to open a non-url pasta as a redirect } else { - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()); + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()); } } // otherwise // send pasta not found error - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } /// Endpoint to request pasta as raw file. diff --git a/src/endpoints/qr.rs b/src/endpoints/qr.rs index 6639470..73dcb9b 100644 --- a/src/endpoints/qr.rs +++ b/src/endpoints/qr.rs @@ -5,6 +5,7 @@ use crate::util::hashids::to_u64 as hashid_to_u64; use crate::util::misc::{self, remove_expired}; use crate::AppState; use crate::util::pasta_id_converter::CONVERTER; +use actix_web::http::StatusCode; use actix_web::{get, web, HttpResponse}; use askama::Template; @@ -63,7 +64,10 @@ pub async fn getqr(data: web::Data, id: web::Path) -> HttpResp // otherwise // send pasta not found error - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } diff --git a/src/endpoints/remove.rs b/src/endpoints/remove.rs index ce0c407..1dbe997 100644 --- a/src/endpoints/remove.rs +++ b/src/endpoints/remove.rs @@ -1,3 +1,4 @@ +use actix_web::http::StatusCode; use actix_web::{get, web, HttpResponse}; use crate::args::ARGS; @@ -58,7 +59,10 @@ pub async fn remove(data: web::Data, id: web::Path) -> HttpRes remove_expired(&mut pastas); - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } diff --git a/templates/error.html b/templates/error.html index 806229e..a0c007c 100644 --- a/templates/error.html +++ b/templates/error.html @@ -1,10 +1,10 @@ {% include "header.html" %}
-

404

-Not Found +

{{ status_code.as_u16() }}

+{{ status_code.canonical_reason().unwrap_or("Unknown error") }}

Go Home

-{% include "footer.html" %} \ No newline at end of file +{% include "footer.html" %} diff --git a/templates/header.html b/templates/header.html index 8f49088..7154bdf 100644 --- a/templates/header.html +++ b/templates/header.html @@ -2,7 +2,7 @@ - MicroBin + {{ args.title }}