Immortal

Example usage:

```rust use immortal_http::Immortal;

fn main() { let mut immortal = Immortal::new();

immortal.add_middleware(|ctx| {
    ctx.response.headers.insert("X-Frame-Options", "deny".to_string());
    ctx.response.headers.insert("X-Content-Type-Options", "nosniff".to_string());
    ctx.response.headers.insert("Referrer-Policy", "no-referrer".to_string());
});

immortal.fallback(|ctx| {
    ctx.response.code = "404";
});

immortal.register("GET", "/", |ctx| {
    match ctx.read_session(&ctx.request.session_id, "username") {
        None=> {
            ctx.response.body.append(&mut b"<h1>Welcome to the website!</h1>".to_vec());
            ctx.response.body.append(&mut b"<p>Click <a href=\"/login\">HERE</a> to go to the login page</p>".to_vec());
        },
        Some(username) => {
            let username = ctx.html_escape(&username);
            ctx.response.body.append(&mut format!("<h1>Welcome to the website, {username}!</h1>").as_bytes().to_vec());
            ctx.response.body.append(&mut b"<p>Click <a href=\"/logout\">HERE</a> to log out</p>".to_vec());
        },
    };
});

immortal.register("GET", "/login", |ctx| {
    if ctx.read_session(&ctx.request.session_id, "username").is_some() {
        ctx.response.code = "302";
        ctx.response.headers.insert("Location", String::from("/"));
        return;
    }

    ctx.response.body.append(&mut b"


".to_vec() );

    match ctx.read_session(&ctx.request.session_id, "message") {
        None => {},
        Some(message) => {
            ctx.response.body.append(
                &mut format!("<br><p>{}</p>", ctx.html_escape(&message)).as_bytes().to_vec()
            );
            ctx.write_session(&ctx.request.session_id, "message", "");
        },
    };
});

immortal.register("POST", "/login", |ctx| {
    ctx.response.code = "302";
    if ctx.read_session(&ctx.request.session_id, "username").is_some() {
        ctx.response.headers.insert("Location", "/".to_string());
        return;
    }

    if ctx.request.post("username").is_some() && ctx.request.post("password").is_some() {
        let username = ctx.request.post("username").unwrap();
        let password = ctx.request.post("password").unwrap();
        if /*username == "admin" &&*/ password == "lemon42" { // could do a DB lookup here
            ctx.write_session(&ctx.request.session_id, "username", username);
            ctx.response.headers.insert("Location", "/".to_string());
            return;
        }
    }

    ctx.write_session(&ctx.request.session_id, "message", "Failed to log in");
    ctx.response.headers.insert("Location", "/login".to_string());
});

immortal.register("GET", "/logout", |ctx| {
    ctx.response.code = "302";
    ctx.response.headers.insert("Location", "/login".to_string());

    if ctx.read_session(&ctx.request.session_id, "username").is_some() {
        ctx.write_session(&ctx.request.session_id, "username", "");
        ctx.write_session(&ctx.request.session_id, "message", "Logged out");
    } else {
        ctx.write_session(&ctx.request.session_id, "message", "Not logged in");
    }
});

if let Err(e) = immortal.listen("127.0.0.1:7777") {
    panic!("{}", e);
}

} ```