aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-07-04 12:02:20 +0200
committerMartin Fischer <martin@push-f.com>2021-07-04 12:02:20 +0200
commit4c824bad097118f95fa738468e5dd368b6c14ca8 (patch)
tree7f874ac01f65c69650c53e78240dcd727c73e740
parentc0b8d6a9876a95bc5d8fd8a30333e65949f5c9d1 (diff)
refactor: move Error rendering to error module
-rw-r--r--src/error.rs43
-rw-r--r--src/main.rs37
2 files changed, 44 insertions, 36 deletions
diff --git a/src/error.rs b/src/error.rs
index 0a36476..3cf6832 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,7 +1,12 @@
+use hyper::http::response::Builder;
+use hyper::StatusCode;
use sputnik::hyper_body::FormError;
use sputnik::request::QueryError;
+use sputnik::response::EmptyBuilder;
use std::str::Utf8Error;
+use crate::HyperResponse;
+
/// For convenience this enum also contains nonerroneous variants.
pub enum Error {
/// A 400 bad request error.
@@ -48,3 +53,41 @@ impl From<QueryError> for Error {
Self::BadRequest(e.to_string())
}
}
+
+impl From<Error> for HyperResponse {
+ fn from(err: Error) -> Self {
+ let (status, message) = match err {
+ Error::BadRequest(msg) => (400, msg),
+ Error::Unauthorized(msg) => (401, msg),
+ Error::Forbidden(msg) => (403, msg),
+ Error::NotFound(msg) => (404, msg),
+ Error::Internal(msg) => (500, msg),
+ Error::NotModified => {
+ return Builder::new()
+ .status(StatusCode::NOT_MODIFIED)
+ .empty()
+ .unwrap();
+ }
+ Error::MissingTrailingSlash(path) => {
+ return Builder::new()
+ .status(StatusCode::FOUND)
+ .header("location", format!("{}/", path))
+ .body("redirecting".into())
+ .unwrap();
+ }
+ Error::Redirect(target) => {
+ return Builder::new()
+ .status(StatusCode::FOUND)
+ .header("location", target)
+ .body("redirecting".into())
+ .unwrap();
+ }
+ };
+ // TODO: use Page
+ Builder::new()
+ .status(status)
+ .header("content-type", "text/html")
+ .body(message.into())
+ .unwrap()
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 513f59e..231a7af 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -21,7 +21,6 @@ use serde::Deserialize;
use sputnik::html_escape;
use sputnik::mime;
use sputnik::request::SputnikParts;
-use sputnik::response::EmptyBuilder;
use sputnik::response::SputnikBuilder;
use std::convert::Infallible;
use std::env;
@@ -252,41 +251,7 @@ async fn service<C: Controller>(
.unwrap()
}
})
- .unwrap_or_else(|err| {
- let (status, message) = match err {
- Error::BadRequest(msg) => (400, msg),
- Error::Unauthorized(msg) => (401, msg),
- Error::Forbidden(msg) => (403, msg),
- Error::NotFound(msg) => (404, msg),
- Error::Internal(msg) => (500, msg),
- Error::NotModified => {
- return Builder::new()
- .status(StatusCode::NOT_MODIFIED)
- .empty()
- .unwrap();
- }
- Error::MissingTrailingSlash(path) => {
- return Builder::new()
- .status(StatusCode::FOUND)
- .header("location", format!("{}/", path))
- .body("redirecting".into())
- .unwrap();
- }
- Error::Redirect(target) => {
- return Builder::new()
- .status(StatusCode::FOUND)
- .header("location", target)
- .body("redirecting".into())
- .unwrap();
- }
- };
- // TODO: use Page
- Builder::new()
- .status(status)
- .header("content-type", "text/html")
- .body(message.into())
- .unwrap()
- });
+ .unwrap_or_else(|err| err.into());
// we rely on CSP to thwart XSS attacks, all modern browsers support it
resp.headers_mut()