From 4911f8f2d903eefeba134b66ff3f0a9b13ac345e Mon Sep 17 00:00:00 2001 From: Emi Tatsuo Date: Wed, 16 Dec 2020 11:38:29 -0500 Subject: [PATCH] Add a whole bunch of comments to the examples --- examples/certificates.rs | 21 ++++++++++++++++++--- examples/ratelimiting.rs | 25 +++++++++++++++++++++---- examples/routing.rs | 30 +++++++++++++++++++++++++----- examples/serve_dir.rs | 11 +++++++++++ 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/examples/certificates.rs b/examples/certificates.rs index 8bd785b..02ae1ea 100644 --- a/examples/certificates.rs +++ b/examples/certificates.rs @@ -4,17 +4,32 @@ use log::LevelFilter; use kochab::{Request, Response, Server}; #[tokio::main] +/// This is a super quick demonstration of how you can check user certificates with kochab +/// +/// The goal of this example is just to read the user's certificate and tell them their +/// certificate fingerprint, or if they aren't using a certificate, just tell them that +/// they didn't provide one. +/// +/// You can of course require a certificate by sending a [`Response::client_certificate_required()`]. +/// But, if you're interested in more advanced user management features, like letting +/// users create an account and persist data, you might want to check out the +/// user_management feature. 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() - .add_route("/", handle_request) - .serve_ip("localhost:1965") + Server::new() // Create a new server + .add_route("/", handle_request) // Bind our handling function to the root path + .serve_ip("localhost:1965") // Start serving content on the default gemini port .await } +/// This is the actual handler that does most of the actual work. +/// It'll be called by the server when we receive a request async fn handle_request(request: Request) -> Result { if let Some(fingerprint) = request.fingerprint() { diff --git a/examples/ratelimiting.rs b/examples/ratelimiting.rs index 6ccbaec..47ae9ad 100644 --- a/examples/ratelimiting.rs +++ b/examples/ratelimiting.rs @@ -5,18 +5,35 @@ 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() - .add_route("/", handle_request) - .ratelimit("/limit", 2, Duration::from_secs(10)) - .serve_ip("localhost:1965") + 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(); diff --git a/examples/routing.rs b/examples/routing.rs index fbd2b92..d276634 100644 --- a/examples/routing.rs +++ b/examples/routing.rs @@ -3,16 +3,32 @@ use log::LevelFilter; use kochab::{Document, document::HeadingLevel, Request, Response}; #[tokio::main] +/// A quick demo to show off how an app can have multiple handlers on diffrent routes +/// +/// We set up three different routes: +/// * `/route/long/*` +/// * `/route/*` +/// * `/*` which matches any other route +/// +/// Each route generates a slightly different page, although they all use the same layout +/// through the [`generate_doc()`] method. Each page states which route was matched, and +/// all the trailing path segments. +/// +/// For example, a request to `/route/trail` would be matched by the short route +/// (`/route/*`) with the trailing path segment `["trail"]` 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(); - kochab::Server::new() - .add_route("/", handle_base) - .add_route("/route", handle_short) - .add_route("/route/long", handle_long) - .serve_ip("localhost:1965") + kochab::Server::new() // Create a new server + .add_route("/", handle_base) // Register the base route (order irrelevant) + .add_route("/route", handle_short) // Reigster the short route + .add_route("/route/long", handle_long) // Register the long route + .serve_ip("localhost:1965") // Start the server .await } @@ -32,7 +48,11 @@ async fn handle_long(req: Request) -> Result { } fn generate_doc(route_name: &str, req: &Request) -> Document { + + // Trailing segments comes in as a Vec of segments, so we join them together for + // display purposes let trailing = req.trailing_segments().join("/"); + let mut doc = Document::new(); doc.add_heading(HeadingLevel::H1, "Routing Demo") .add_text(&format!("You're currently on the {} route", route_name)) diff --git a/examples/serve_dir.rs b/examples/serve_dir.rs index 732dae9..855c270 100644 --- a/examples/serve_dir.rs +++ b/examples/serve_dir.rs @@ -5,7 +5,18 @@ use log::LevelFilter; use kochab::Server; #[tokio::main] +/// Serving some static content from the filesystem is easy with Kochab +/// +/// This example serves from the `./public` directory on the base route, and adds a +/// special one-page bind to `/about` that always serves `README.md` +/// +/// Note, use this module with a little bit of caution. The directory serving feature is +/// currently unfinished, and the API is subject to change dramatically in future updates. +/// It should be secure, but you may need to do some refactoring in coming updates. 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();