Git Product home page Git Product logo

Comments (5)

shepmaster avatar shepmaster commented on July 16, 2024 3

You can write a handler which tries two handlers and returns the first one that doesn't 404.

And here's another solution, a year later

struct Fallback;

impl AroundMiddleware for Fallback {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(FallbackHandler(handler))
    }
}

struct FallbackHandler(Box<Handler>);

impl Handler for FallbackHandler {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        let resp = self.0.handle(req);

        match resp {
            Err(err) => {
                match err.response.status {
                    Some(status::NotFound) => {
                        let file = File::open("/tmp/example").unwrap();
                        Ok(Response::with((status::Ok, file)))
                    }
                    _ => Err(err),
                }
            }
            other => other
        }
    }
}

from staticfile.

shepmaster avatar shepmaster commented on July 16, 2024 1

Something similar to this appears to work:

remap.rs

use std::collections::HashSet;

use iron::prelude::*;
use iron::{BeforeMiddleware, Url};

pub struct Remap {
    new_path: String,
    routes: HashSet<&'static str>,
}

impl Remap {
    pub fn new(path: &str) -> Remap {
        Remap {
            new_path: path.into(),
            routes: HashSet::new(),
        }
    }

    pub fn get(&mut self, path: &'static str) {
        self.routes.insert(path);
    }
}

impl BeforeMiddleware for Remap {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        // TODO: do we really need to clone?
        let original_url = req.url.clone().into_generic_url();

        if self.routes.contains(original_url.path()) {
            let mut changed_url = original_url;
            changed_url.set_path(&self.new_path);
            let changed_url = Url::from_generic_url(changed_url).expect("Unable to rebuild URL");
            req.url = changed_url;
        }

        Ok(())
    }
}

main.rs

mod remap;
use remap::Remap;

fn main() {
    let mut mount = Mount::new();
    mount.mount("/", Static::new(&root));

    // Routes that are handled client-side
    let mut remap = Remap::new("/");
    remap.get("/about");

    let mut remapped = Chain::new(mount);
    remapped.link_before(remap);

    info!("Starting the server on {}:{}", address, port);
    Iron::new(remapped).http((&*address, port)).expect("Unable to start server");
}

To be more complete, it should use the same underlying glob and route recognizer libraries as Iron to allow for the syntax to match.

from staticfile.

shepmaster avatar shepmaster commented on July 16, 2024

Yep, this seems like it will be a common pattern for frontend-heavy web applications. If a static file exists, serve it, otherwise serve the HTML & JS for the application, which will handle the routing.

One complication I see is that we may want Iron to be able to check the URL against a whitelist to know if it is a valid path. If it isn't, then Iron should return a 404. After sketching some pseudocode, I thought of this:

let static_files = Static::new("assets");

let remap = Remap::new("assets/index.html")
    .get("/users")
    .get("/users/:id")
    .get("/posts")
    .get("/posts/:id");

let fallback = Fallback::new(static_files, remap);

This seemingly allows the composition currently favored by the Iron project. Perhaps the Fallback may not even be needed, if Remap is a Modifier which can then simply allow Static to do the normal flow...

from staticfile.

untitaker avatar untitaker commented on July 16, 2024

You can write a handler which tries two handlers and returns the first one that doesn't 404.

from staticfile.

ernestas-poskus avatar ernestas-poskus commented on July 16, 2024

maybe it's worth to create middleware's or alike repository under /iron organization to stock these treasures?

from staticfile.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.