index : static-web-server.git

ascending towards madness

author Jose Quintana <joseluisquintana20@gmail.com> 2019-12-24 0:10:34.0 +00:00:00
committer Jose Quintana <joseluisquintana20@gmail.com> 2019-12-24 0:10:34.0 +00:00:00
commit
15379d66ec4330c93c0a82cb48b9a53add8ab4a8 [patch]
tree
36373a2caed392c2b00520f2f8fbb0ecf1fe0498
parent
1d2c1b3d3a12ed729a9d757f9a45298130d2ff98
download
15379d66ec4330c93c0a82cb48b9a53add8ab4a8.tar.gz

feat: add error page support completed



Diff

 src/error_page.rs  | 39 +++++++++++++++++++++++++++++++++-----
 src/main.rs        | 22 +++++++++++++++-------
 src/staticfiles.rs | 56 ++++++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 90 insertions(+), 27 deletions(-)

diff --git a/src/error_page.rs b/src/error_page.rs
index 234f8b0..7a9e41a 100644
--- a/src/error_page.rs
+++ b/src/error_page.rs
@@ -4,8 +4,26 @@ use iron::mime;
use iron::prelude::*;
use iron::status;
use iron::AfterMiddleware;
use std::fs;
use std::path::Path;

pub struct ErrorPage;
/// Custom Error pages middleware for Iron
pub struct ErrorPage {
    /// HTML file content for 50x errors.
    pub page50x: std::string::String,
    /// HTML file content for 404 errors.
    pub page404: std::string::String,
}

impl ErrorPage {
    /// Create a new instance of `ErrorPage` middleware with a given html pages.
    pub fn new<P: AsRef<Path>>(page_50x_path: P, page_404_path: P) -> ErrorPage {
        let page50x = fs::read_to_string(page_50x_path).unwrap();
        let page404 = fs::read_to_string(page_404_path).unwrap();

        ErrorPage { page50x, page404 }
    }
}

impl AfterMiddleware for ErrorPage {
    fn after(&self, _: &mut Request, res: Response) -> IronResult<Response> {
@@ -15,18 +33,29 @@ impl AfterMiddleware for ErrorPage {
            Some(status::NotFound) => Ok(Response::with((
                content_type,
                status::NotFound,
                "404 Not Found",
                self.page404.as_str(),
            ))),
            Some(status::InternalServerError) => Ok(Response::with((
                content_type,
                status::InternalServerError,
                "50x Internal Server Error",
                self.page50x.as_str(),
            ))),
            _ => Ok(Response::with((
            Some(status::BadGateway) => Ok(Response::with((
                content_type,
                status::BadGateway,
                self.page50x.as_str(),
            ))),
            Some(status::ServiceUnavailable) => Ok(Response::with((
                content_type,
                status::ServiceUnavailable,
                "503 Service Unavailable",
                self.page50x.as_str(),
            ))),
            Some(status::GatewayTimeout) => Ok(Response::with((
                content_type,
                status::GatewayTimeout,
                self.page50x.as_str(),
            ))),
            _ => Ok(res),
        }
    }
}
diff --git a/src/main.rs b/src/main.rs
index 6bc28d0..032caae 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,20 +8,21 @@ extern crate iron_staticfile_middleware;
extern crate log;
extern crate structopt;

mod config;
mod error_page;
mod gzip;
mod logger;
mod staticfiles;

use crate::config::Options;
use chrono::Local;
use env_logger::Builder;
use iron::prelude::*;
use log::LevelFilter;
use staticfiles::*;
use std::io::Write;
use structopt::StructOpt;

mod config;
mod error_page;
mod gzip;
mod logger;
mod staticfiles;

fn main() {
    Builder::new()
        .format(|buf, record| {
@@ -38,9 +39,16 @@ fn main() {

    let opts = Options::from_args();

    let files = StaticFiles::new(StaticFilesOptions {
        root_dir: opts.root,
        assets_dir: opts.assets,
        page_50x_path: opts.page50x,
        page_404_path: opts.page404,
    });

    let _address = &format!("{}{}{}", opts.host.to_string(), ":", opts.port.to_string());

    let _server = Iron::new(staticfiles::handler(opts.root, opts.assets))
    let _server = Iron::new(files.handle())
        .http(_address)
        .expect("Unable to start the HTTP Server");

diff --git a/src/staticfiles.rs b/src/staticfiles.rs
index 318974f..079faab 100644
--- a/src/staticfiles.rs
+++ b/src/staticfiles.rs
@@ -6,22 +6,48 @@ use iron::prelude::*;
use iron_staticfile_middleware::{Cache, GuessContentType, ModifyWith, Prefix, Staticfile};
use std::time::Duration;

pub fn handler(root_dir: String, assets_dir: String) -> Chain {
    let mut chain =
        Chain::new(Staticfile::new(root_dir).expect("Directory to serve files was not found"));
/// An Iron middleware for static files-serving.
pub struct StaticFiles {
    opts: StaticFilesOptions,
}

pub struct StaticFilesOptions {
    pub root_dir: String,
    pub assets_dir: String,
    pub page_50x_path: String,
    pub page_404_path: String,
}

    let one_day = Duration::new(60 * 60 * 24, 0);
    let one_year = Duration::new(60 * 60 * 24 * 365, 0);
    let default_content_type = "text/html"
        .parse()
        .expect("Unable to create a default content type header");
impl StaticFiles {
    /// Create a new instance of `StaticFiles` with given options.
    pub fn new(opts: StaticFilesOptions) -> StaticFiles {
        StaticFiles { opts }
    }

    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);
    /// Handle static files for current `StaticFiles` middleware.
    pub fn handle(&self) -> Chain {
        let mut chain = Chain::new(
            Staticfile::new(self.opts.root_dir.as_str())
                .expect("Directory to serve files was not found"),
        );
        let one_day = Duration::new(60 * 60 * 24, 0);
        let one_year = Duration::new(60 * 60 * 24 * 365, 0);
        let default_content_type = "text/html"
            .parse()
            .expect("Unable to create a default content type header");

    chain
        chain.link_after(ModifyWith::new(Cache::new(one_day)));
        chain.link_after(Prefix::new(
            &[self.opts.assets_dir.as_str()],
            Cache::new(one_year),
        ));
        chain.link_after(GuessContentType::new(default_content_type));
        chain.link_after(GzipMiddleware);
        chain.link_after(Logger);
        chain.link_after(ErrorPage::new(
            self.opts.page_50x_path.as_str(),
            self.opts.page_404_path.as_str(),
        ));
        chain
    }
}