Merge pull request #323 from onelson/actix-middleware-err-response

Custom 404 page
This commit is contained in:
Vincent Prouillet 2018-07-05 17:22:40 +02:00 committed by GitHub
commit 734beba0fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 4 deletions

View file

@ -25,7 +25,7 @@ term-painter = "0.2"
url = "1.5" url = "1.5"
# Below is for the serve cmd # Below is for the serve cmd
actix = "~0.5" actix = "~0.5"
actix-web = "0.6" actix-web = "~0.6"
notify = "4" notify = "4"
ws = "0.7" ws = "0.7"
ctrlc = "3" ctrlc = "3"

View file

@ -526,6 +526,7 @@ impl Site {
if self.config.generate_rss { if self.config.generate_rss {
self.render_rss_feed()?; self.render_rss_feed()?;
} }
self.render_404()?;
self.render_robots()?; self.render_robots()?;
// `render_categories` and `render_tags` will check whether the config allows // `render_categories` and `render_tags` will check whether the config allows
// them to render or not // them to render or not
@ -660,6 +661,15 @@ impl Site {
Ok(()) Ok(())
} }
/// Renders 404.html
pub fn render_404(&self) -> Result<()> {
ensure_directory_exists(&self.output_path)?;
create_file(
&self.output_path.join("404.html"),
&render_template("404.html", &self.tera, &Context::new(), &self.config.theme)?
)
}
/// Renders robots.txt /// Renders robots.txt
pub fn render_robots(&self) -> Result<()> { pub fn render_robots(&self) -> Result<()> {
ensure_directory_exists(&self.output_path)?; ensure_directory_exists(&self.output_path)?;

View file

@ -0,0 +1,10 @@
<!doctype html>
<html>
<head>
<title>File Not Found: 404.</title>
</head>
<body>
<h1>Oops!</h1>
<h2>File Not Found: 404.</h2>
</body>
</html>

View file

@ -24,6 +24,7 @@ lazy_static! {
pub static ref GUTENBERG_TERA: Tera = { pub static ref GUTENBERG_TERA: Tera = {
let mut tera = Tera::default(); let mut tera = Tera::default();
tera.add_raw_templates(vec![ tera.add_raw_templates(vec![
("404.html", include_str!("builtins/404.html")),
("rss.xml", include_str!("builtins/rss.xml")), ("rss.xml", include_str!("builtins/rss.xml")),
("sitemap.xml", include_str!("builtins/sitemap.xml")), ("sitemap.xml", include_str!("builtins/sitemap.xml")),
("robots.txt", include_str!("builtins/robots.txt")), ("robots.txt", include_str!("builtins/robots.txt")),

View file

@ -22,8 +22,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
use std::env; use std::env;
use std::fs::remove_dir_all; use std::fs::{remove_dir_all, File};
use std::io; use std::io::{self, Read};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::mpsc::channel; use std::sync::mpsc::channel;
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
@ -31,7 +31,8 @@ use std::thread;
use chrono::prelude::*; use chrono::prelude::*;
use actix; use actix;
use actix_web::{fs, server, App, HttpRequest, HttpResponse, Responder}; use actix_web::{self, fs, http, server, App, HttpRequest, HttpResponse, Responder};
use actix_web::middleware::{Middleware, Started, Response};
use notify::{Watcher, RecursiveMode, watcher}; use notify::{Watcher, RecursiveMode, watcher};
use ws::{WebSocket, Sender, Message}; use ws::{WebSocket, Sender, Message};
use ctrlc; use ctrlc;
@ -58,6 +59,33 @@ enum ChangeKind {
// errors // errors
const LIVE_RELOAD: &'static str = include_str!("livereload.js"); const LIVE_RELOAD: &'static str = include_str!("livereload.js");
struct NotFoundHandler {
rendered_template: PathBuf,
}
impl<S> Middleware<S> for NotFoundHandler {
fn start(&self, _req: &mut HttpRequest<S>) -> actix_web::Result<Started> {
Ok(Started::Done)
}
fn response(
&self,
_req: &mut HttpRequest<S>,
mut resp: HttpResponse,
) -> actix_web::Result<Response> {
if http::StatusCode::NOT_FOUND == resp.status() {
let mut fh = File::open(&self.rendered_template)?;
let mut buf: Vec<u8> = vec![];
let _ = fh.read_to_end(&mut buf)?;
resp.replace_body(buf);
resp.headers_mut().insert(
http::header::CONTENT_TYPE,
http::header::HeaderValue::from_static("text/html"),
);
}
Ok(Response::Done(resp))
}
}
fn livereload_handler(_: HttpRequest) -> &'static str { fn livereload_handler(_: HttpRequest) -> &'static str {
LIVE_RELOAD LIVE_RELOAD
@ -155,6 +183,7 @@ pub fn serve(interface: &str, port: &str, output_dir: &str, base_url: &str, conf
let sys = actix::System::new("http-server"); let sys = actix::System::new("http-server");
server::new(move || { server::new(move || {
App::new() App::new()
.middleware(NotFoundHandler { rendered_template: static_root.join("404.html") })
.resource(r"/livereload.js", |r| r.f(livereload_handler)) .resource(r"/livereload.js", |r| r.f(livereload_handler))
// Start a webserver that serves the `output_dir` directory // Start a webserver that serves the `output_dir` directory
.handler(r"/", fs::StaticFiles::new(&static_root) .handler(r"/", fs::StaticFiles::new(&static_root)