Как обслужить резервный файл с помощью статического файла Iron, если исходный файл не найден?

Я использую Iron для обслуживания сайта React. Я пытаюсь заставить его обслуживать index.html, если файл или каталог не существует.

fn staticHandler(req: &mut Request) -> IronResult<Response> {
    let url = Url::parse("http://localhost:1393").unwrap();
    let getFile_result = Static::handle(&Static::new(Path::new("../html")), req);

    match getFile_result {
        Ok(_) => getFile_result,
        Err(err) => {
            Static::handle(
                // returns 404 error - ../html/index.html returns 500
                &Static::new(Path::new("localhost:1393/index.html")),
                req,
            )
        }
    }
}

Если я перейду на localhost: 1393, я получу свою индексную страницу, если я перейду на localhost: 1393 / not-a-directory, я просто получу сообщение об ошибке.

Есть ли способ перенаправить (без изменения URL-адреса) или какое-то другое решение?

Это не дубликат Как изменить поведение 404 по умолчанию в Iron? потому что я пытаюсь обработать, когда статический актив, который запрашивает пользователь, не существует, а не когда маршрут не определен.


person FIL1994    schedule 27.09.2017    source источник
comment
Поскольку это не ответ, у Iron есть промежуточное ПО для статических файлов.   -  person squiguy    schedule 28.09.2017
comment
@squiguy Я думаю, что это откуда Static::new в этом вопросе, но OP не предоставил минимальный воспроизводимый пример, поэтому кто знает...   -  person Shepmaster    schedule 28.09.2017


Ответы (1)


Как обсуждалось в проблеме № 78 статического файла под названием «Статический с резервным», вы можете обернуть обработчик, проверьте наличие 404 и вместо этого предоставьте файл:

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
        }
    }
}
person Shepmaster    schedule 27.09.2017
comment
Большое спасибо за Вашу помощь! Это работает. Он просто используется как обычный текст. Как указать, что это HTML-файл? - person FIL1994; 28.09.2017
comment
Ничего. Я нашел его здесь: stackoverflow.com/questions/34979970/ - person FIL1994; 28.09.2017