Crate kochab

Crate kochab 

Source
Expand description

Kochab is an ergonomic and intuitive library for quickly building highly functional and advanced Gemini applications on either SCGI or raw Gemini.

Originally based on northstar, though now far diverged, kochab offers many features to help you build your application without any of the boilerplate or counterintuitive shenanigans. Kochab centers around it’s many feature flags, which let you pick out exactly the features you need to build your library, while leaving out features you don’t need to keep your application bloat-free.

Another central feature of kochab is its multi-protocol abstraction. An application built using kochab can easily compile either as a gemini application or as a SCGI script using only a single feature flag.

§Features

Kochab offers a wide array of features, so don’t get overwhelmed. By default, you start off with only the gemini_srv feature, and you’re able to add on more features as you need them. All of kochab’s features are documented below.

  • ratelimiting - The ratelimiting feature adds in the ability to limit how often users can access certain areas of an application. This is primarily configured using the [Server::ratelimit()] method.

  • serve_dir - Adds in utilities for serving files & directories from the disk at runtime. The easiest way to use this is to pass a PathBuf to the Server::add_route() method, which will either serve a directory or a single file. Files and directories can also be served using the methods in the util module.

  • user_management - Adds in tools to manage users using a certificate authentication system. The user management suite is one of kocab’s biggest features. When active, kochab will maintain a database of registered users, linking each to a certificate. Users also have custom data associated with them, which can be retrieved and modified by the application.

  • user_management_advanced - Allows users to set a password and add additional certificates. Without this feature, one certificate can only have one linked account, unless you manually implement an authentication system. With this feature, kochab will use argon2 to hash and check user passwords, and store user passwords alongside the other user data

  • user_management_routes - The user management routes feature automates much of the hard work of connecting the tools provided with the other two features with endpoints that the user connects to. Kochab will manage all requests to the /account route, and create pages to allow users to create an account, link new certificates, or change/set their password. This also adds the ability to set an authenticated route, which will automatically prompt the user to sign in, and give your handler access to the user’s data with no added work. This can be used with either the user_management_advanced feature, or just the basic user_management feature

  • certgen - Enables automatically generating TLS certificates. Since only servers directly using the gemini protocol need TLS certificates, this implies gemini_srv, and should not be used with scgi_srv. By default, kochab will try to generate a certificate by prompting the user in stdin/stdout, but this behavior can be customized using Server::set_certificate_generation_mode().

  • dashmap - Enables some minor optimizations within the user_management_routes feature. Automatically enabled by ratelimiting.

  • ring - When using user_management_advanced with scgi_srv, salts are calculated based off of a simple PRNG and the system time. This should be plenty secure enough, especially since we’re using a good number argon2 rounds, but for bonus paranoia points, you can add ring as a dependency to source secure random. This is enabled automatically on gemini_srv, since ring is added as a dependency for certificate processing. When not using the user_management_advanced feature, this does nothing but increase your build time & size.

  • gemini_srv/scgi_srv - Switches between serving content using SCGI and serving content as a raw gemini server. One and only one of these features must be enabled, and compilation will fail if both are enabled. See below for more information.

§Gemini & SCGI Modes

It is highly recommended that you read this section, especially if you don’t know what SCGI is.

Central to kochab’s repertoire is the ability to serve either content either through raw Gemini or through a reverse proxy with SCGI. This can be accomplished easily using a single feature flag. But first:

§What’s SCGI and why should I be using it?

You’re probably familiar with the Gemini protocol, and how servers serve things on it. Gemini is easy to serve and simple to work with. You probably went into this project expecting to serve content directly through the Gemini protocol. So what’s this about SCGI, and why should you bother using it?

The problem that SCGI solves is that it is very difficult to have multiple servers on one domain with Gemini. For example, if you wanted to serve your blog on /blog.gmi, but wanted to have an app running on /app, you would most likely have to use SCGI.

SCGI has two parts: A main gemini server (called the SCGI client) that handles TLS for incoming connections and either serves some static content, runs some other handler, or passes it off to the SCGI server, which is what you’d be writing. The SCGI server doesn’t directly interact with the client, but gets plenty of information about the connection from the server, like what path the server is being served on (like “/app”), the end user’s IP, and the certificate fingerprint being used, if applicable.

Because SCGI servers don’t need to bother with TLS, compiling your app as SCGI will also be fairly faster, since kochab doesn’t need to bring in rustls or any TLS certificate generation libraries.

This doesn’t necessarily mean that SCGI is for every app, but if you suspect that a user might ever need to run your app on a path other than the main one, or may want to serve static files alongside your site, I encourage you to seriously consider it.

§But I don’t want to bother learning a new protocol blobcat-pout

You don’t have to! Kochab handles everything about it, thanks to the magic of abstraction! The only thing you have to change are the feature flags in your Config.toml. In fact, you could even expose the feature flag so that users can compile your crate as either a Gemini or SCGI server without needing to write any conditional compilation!

§Getting started

Updating your feature flags

By default, Kochab serves content over raw gemini, to make it easier for new users to jump right into using the library. This is done using the on-by-default gemini_srv feature flag. To switch to SCGI, we want to switch off gemini_srv and switch on scgi_srv.

[dependencies.kochab]
git = "https://gitlab.com/Alch_Emi/kochab.git"
branch = "stable"
default-features = false
features = ["scgi_srv"] # and any other features you might need

Testing with a minimal SCGI client

To give your code a run, you’ll need a server to handle Gemini requests and pass them off to your SCGI server. There’s a few Gemini servers out there with SCGI support, but if you’re just interested in giving your code a quick run, I’d recommend stargazer, which has very good SCGI support and is super easy to set up if you are already using cargo.

You can install stargazer by running.

cargo install stargazer

Once you have it, you can find a super simple configuration file here, and then just run

stargazer -C stargazer.ini

Now, when you run your code, you can connect to localhost, and molly brown will connect to your SCGI server and forward the response on to your Gemini client.

Rewriting Paths

One important difference about writing code for an SCGI server is that your app might be served on a path that’s not the base path. If this happens, you suddenly have a distinction between an absolute link for your app, and an absolute link for the gemini server.

For example, if an app that’s being served on /app has a link to /path, this could be either:

  • Meant to be handled by the app by the route at /path, which would be /app/path for the parent Gemini server, or
  • Meant to link to some content on the parent gemini server, at /path, which would mean linking to a url your app doesn’t control

Most of the time, you want to do the first one. Thankfully, Kochab makes rewriting links relative to the base of your app super easy. In most cases, all you need is to add a single line to your Server builder pattern.

For more information, see Server::set_autorewrite().

Modules§

document
Provides types for creating Gemini Documents.
routing
Utilities for routing requests
util
Utilities for serving a file or directory

Structs§

Document
Represents a Gemini document.
Request
A request from a Gemini client to the app
Response
A response to a client’s Request
Server
A builder for configuring a kochab server
URIReference
A URI reference as defined in [RFC3986, Section 4.1].

Enums§

Body
The body of a response
CertGenMode
The mode to use for determining the domains to use for a new certificate.
Handler
A struct representing something capable of handling a request.

Constants§

GEMINI_PORT
The default port for the gemini protocol
REQUEST_URI_MAX_LEN
The maximun length of a Request URI