Add documentation about SCGI

This commit is contained in:
Emi Tatsuo 2020-12-05 10:30:13 -05:00
parent ae247312f7
commit 680c04abe4
Signed by: Emi
GPG key ID: 68FAB2E2E6DFC98B

View file

@ -2,7 +2,7 @@
//! and advanced Gemini applications on either SCGI or raw Gemini.
//!
//! Originally based on [northstar](https://crates.io/crates/northstar), though now far
//! divereged, kochab offers many features to help you build your application without any
//! 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
@ -22,7 +22,7 @@
//! users can access certain areas of an application. This is primarily configured using
//! the [`Server::ratelimit()`] method.
//!
//! * `servedir` - Adds in utilities for serving files & directories from the disk at
//! * `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.
@ -68,7 +68,114 @@
//! * `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`.
//!
//! ```toml
//! [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
//! mollybrown, which has very good SCGI support and is super easy to set up
//!
//! You can grab a copy of molly brown from [tildegit.org/solderpunk/molly-brown][1].
//!
//! Once you have it, you can find a super simple configuration file [here][2], and then
//! just run
//!
//! ```sh
//! molly-brown -c molly-brown.conf
//! ```
//!
//! 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()`].
//!
//! [1]: https://tildegit.org/solderpunk/molly-brown
//! [2]: https://gitlab.com/Alch_Emi/kochab/-/raw/244fd251/molly-brown.conf
//! [blobcat-pout]: https://the-apothecary.club/_matrix/media/r0/thumbnail/the-apothecary.club/10a406405a5bcd699a5328259133bfd9260320a6?height=99&width=20 ":blobcat-pout:"
//! <style>
//! img[alt=blobcat-pout] { width: 20px; vertical-align: top; }
//! </style>
#[macro_use] extern crate log;