An ergonomic and elegant framework for creating Gemini servers and SCGI apps without needless bloat
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

46 lines
1.8 KiB

use anyhow::Result;
use log::LevelFilter;
use kochab::{Request, Response, Server};
/// 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
.filter_module("kochab", LevelFilter::Debug)
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
/// 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<Response> {
if let Some(fingerprint) = request.fingerprint() {
let message = format!(
"You connected with a certificate with a fingerprint of:\n{}",
} else {
// The user didn't provide a certificate
Ok(Response::client_certificate_required("You didn't provide a client certificate"))