use std::time::Duration; use anyhow::*; use log::LevelFilter; use kochab::{Server, Request, Response, Document}; #[tokio::main] /// An ultra-simple ratelimiting example /// /// We set up two pages: /// * `/*` which can be accessed as much as the user wants /// * /limit/*` which can only be accessed twice every 10 seconds /// /// Once we tell it what needs to be ratelimited, kochab will automatically handle keeping /// track of what users have and have not visited that page and how often. A very small /// concurrent background task is in charge of cleaning the in-memory database every so /// often so that a memory leak doesn't form. async fn main() -> Result<()> { // We set up logging so we can see what's happening. This isn't technically required, // and you can use a simpler solution (like env_logger::init()) during production env_logger::builder() .filter_module("kochab", LevelFilter::Debug) .init(); Server::new() // Create a server .add_route("/", handle_request) // Create a page, content doesn't matter .ratelimit("/limit", 2, Duration::from_secs(10)) // Set the ratelimit to 2 / 10s .serve_ip("localhost:1965") // Start the server .await } /// Render a simple page based on the current URL /// /// The actual content of the response, and really anything in this section, doesn't /// actually affect the ratelimit, but it's nice to have a usable demo, so we set up a /// couple nice pages async fn handle_request(request: Request) -> Result { let mut document = Document::new(); if let Some("limit") = request.trailing_segments().get(0).map(String::as_str) { document.add_text("You're on a rate limited page!") .add_text("You can only access this page twice every 10 seconds"); } else { document.add_text("You're on a normal page!") .add_text("You can access this page as much as you like."); } document.add_blank_line() .add_link("/limit", "Go to rate limited page") .add_link("/", "Go to a page that's not rate limited"); Ok(document.into()) }