Security Features Home Extensions Ecosystem

To extend the core functionality of Kvarn, you’ll use extensions. They are ran in an async context, so you can call async APIs to fetch data. They provide options for attaching to all parts of the request pipeline, with virtually no overhead compared to editing Kvarn’s source.

Contents
1 Details
2 Building an API
3 The five *P*s
3.1 Prime
3.2 Prepare
3.2.1 Single
3.2.2 fn
3.3 Present
3.3.1 Internal
3.3.2 File
3.4 Package
3.5 Post
4 Writing an extension
5 Example

Details

The following pages are details on implementation useful to read if you’re working with Kvarn, even just as the web server to host your files.

Building an API

In Kvarn, you can attach to single URLs or provide a function which takes the request and determines whether or not your code should override the deafult.

In the immediate future, you should be able to say “I want to capture /api/{string}/{0..=100}

You then get request, a reference to the target host, an optional path, and the IP and port the request came from. You provide a response, which can be asynchronous, and Kvarn will handle all comression, content-length, delivery, HTTP protocols, caching (according to your preference, returned as part of the reponse), other extension, and encryption.

This is in contrast to Node.js where you have to handle all cases, resulting in large if else statements (if you don’t use a library, in which case Kvarn is a lot faster and just as convenient).

The five Ps

Kvarn is very extensible. Therefore, several pluggable interfaces (called extensions) exist to make integration fast and seamless.

Here are the five Ps chronologically ordered from the request’s perspective.

Prime

This is where you can add cache redirects. If you for example want to load the login page on all privileged pages (when the user is not logged in), you can check for the authentication HTTP header and from there decide to intercept the request.

It is also here where all HTTP requests are upgraded to HTTPS, by redirecting the request to a special page where a 307 redirect is responded with.

Prepare

You provide either a URI or a function of when to activate your code. Will still get all other extensions applied.

The path variable you get here will be None if the fs feature of a Host isn’t enabled or percent decoding failed. Be sure to handle percent encoding when taking the request.uri().path(). Using the path handles this for you.

You have to handle all HTTP methods, as Kvarn passes all, except for HEAD, which it handles by simply omitting the body. If your response-type is something other than HTML, you must set the header.

It’s very useful for APIs (both REST and GraphQL!)

Here, you could, for example, implement reading from the file system, like Kvarn does by default.

Single

These bind to a single page.

fn

You provide a predicate which returns whether or not to run this extension.

Present

Here, files can opt in to extensions to manipulate data, such as the template system and hide extension.

This type can modify most data in response and will be executed in series.

Extensions can also attach to filetypes.

Internal

These are declared on the first line in a file, acording to the following syntax:

!> extension arg1 arg2 &> second-extension-name with these four arguments &>
and-so-on

My blog...

There can be arbitrarily many extensions. The are separated by &>.

The first word (space-separated) is the extension name. The others are arguments. Extensions might not look for arguments, or error if any invalid input is given, just like applications.

You can naturally also give just one extension:

!> nonce

My vlog...

When Kvarn serves the file, this line is removed.

Extensi