feat: error page support (closes #3)
Diff
Makefile | 2 +-
public/404.html | 16 ++++++++++++++++
public/50x.html | 16 ++++++++++++++++
src/error_page.rs | 32 ++++++++++++++++++++++++++++++++
src/main.rs | 1 +
src/staticfiles.rs | 16 +++++++++-------
6 files changed, 75 insertions(+), 8 deletions(-)
@@ -40,7 +40,7 @@ test:
.PHONY: test
fmt:
@cargo fix --edition
@cargo fix
@cargo fmt --all
.PHONY: fmt
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>404 Not Found</title>
</head>
<body>
<h1>404</h1>
<p>Content was not found.</p>
</body>
</html>
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>50x Service Unavailable</title>
</head>
<body>
<h1>50x</h1>
<p>Service is temporarily unavailable.</p>
</body>
</html>
@@ -0,0 +1,32 @@
extern crate iron;
use iron::mime;
use iron::prelude::*;
use iron::status;
use iron::AfterMiddleware;
pub struct ErrorPage;
impl AfterMiddleware for ErrorPage {
fn after(&self, _: &mut Request, res: Response) -> IronResult<Response> {
let content_type = "text/html".parse::<mime::Mime>().unwrap();
match res.status {
Some(status::NotFound) => Ok(Response::with((
content_type,
status::NotFound,
"404 Not Found",
))),
Some(status::InternalServerError) => Ok(Response::with((
content_type,
status::InternalServerError,
"50x Internal Server Error",
))),
_ => Ok(Response::with((
content_type,
status::ServiceUnavailable,
"503 Service Unavailable",
))),
}
}
}
@@ -17,6 +17,7 @@ use std::io::Write;
use structopt::StructOpt;
mod config;
mod error_page;
mod gzip;
mod logger;
mod staticfiles;
@@ -1,3 +1,4 @@
use crate::error_page::ErrorPage;
use crate::gzip::GzipMiddleware;
use crate::logger::Logger;
@@ -6,7 +7,7 @@ use iron_staticfile_middleware::{Cache, GuessContentType, ModifyWith, Prefix, St
use std::time::Duration;
pub fn handler(root_dir: String, assets_dir: String) -> Chain {
let mut files =
let mut chain =
Chain::new(Staticfile::new(root_dir).expect("Directory to serve files was not found"));
let one_day = Duration::new(60 * 60 * 24, 0);
@@ -15,11 +16,12 @@ pub fn handler(root_dir: String, assets_dir: String) -> Chain {
.parse()
.expect("Unable to create a default content type header");
files.link_after(ModifyWith::new(Cache::new(one_day)));
files.link_after(Prefix::new(&[assets_dir], Cache::new(one_year)));
files.link_after(GuessContentType::new(default_content_type));
files.link_after(GzipMiddleware);
files.link_after(Logger);
chain.link_after(ModifyWith::new(Cache::new(one_day)));
chain.link_after(Prefix::new(&[assets_dir], Cache::new(one_year)));
chain.link_after(GuessContentType::new(default_content_type));
chain.link_after(GzipMiddleware);
chain.link_after(Logger);
chain.link_after(ErrorPage);
files
chain
}