Simple Web Applications

Simple Web Applications (in Ada)

This repository contains a collection of simple independent web applications, based on AWS.

Append Server

The "Append Server" is one of the simple possible web applications: give an append-only access to local files through POST endpoints.

In more details, each active endpoint is associated with a local file, expected form-like POST request with a data field containing the data to add and a signature field, containing a HAMC-SHA256 signature of the data to authenticate it. Requests outside of known active endpoints are matched against a given static file hierarchy, that may or may not contain a file updated by an active endpoint.

Upload Server

One of the easiest ways to copy a file from one computer to another is to use a HTTP server as intermediary. Simple_Webapps.Upload_Servers provides an AWS dispatcher implementing such a server.

Basic Use

Once deployed (see below), the expected usage of the upload server is in two steps, first upload then download.

Upload step:

  1. Load the server root form page
  2. Select the local file to upload, expiration delay and comment
  3. Once upload is complete, you're redirected to a report page, whose URL is the base-64 encoding of the file hash digest

Download step:

  1. Use the base-64 encoding of the file digest and the server secret to compute the HMAC, whose base-64 encoding is the download address
  2. Append a slash (/) and any name you like to the HMAC
  3. Use a browser or any HTTP client to download the file


The main consideration behind the scheme explained above is to prevent abuse (an unrestricted open file sharing service is likely to end up massively used for illegal purposes) while still allowing anybody to easily send a file to the service owner or their trustees, and allowing the service owner to easily make a file available to anybody.

The HMAC is used to prevent anybody from guessing a valid download link, even after having seen several valid ones.

The file digest is HMAC'ed rather than the file itself, so that a link to a report page is enough for the service owner to deduce the download link.

To help manage server resources, all uploaded files have an expiration time, selected by the uploader. The expiration delay is bounded by a value inversely proportional to the file size, so that larger files expire sooner. The proportionality constant is a configurable server-wide value.

Note that it does not actually limit the disk usage of the upload server, since the number of uploaded files is still unbounded. For reliability reasons, nothing is done on application level to limit disk usage, the administrator should use filesystem tools instead.


Application configuration file

An example configuration file, demonstrating all available options, is provided in the repository as examples/ It is formatted as a S-expression.

The file is read as a list, whose atoms and lists not starting with an atom are ignored. The following configuration keywords are recognised as configurable variables:


In the index template, the following variables are available:

Moreover, in the index page, the following form fields are expected:

In the file report template, the following variables are available:

In the error page template, the following variables are available:

Nginx upload module

The upload server has been written to work seamless with any of AWS upload facilities or nginx upload module.

Here is an example of the latter:

server {
    listen 80;
    access_log /var/log/nginx/upload.log main;

    client_max_body_size 1000m;

    location /post {
        upload_pass /nginx-post;
        upload_store /upload/incoming;
        upload_set_form_field $ "$upload_file_name";
        upload_set_form_field $upload_field_name.content_type "$upload_content_type";
        upload_set_form_field $upload_field_name.path "$upload_tmp_path";
        upload_aggregate_form_field "$upload_field_name.sha1" "$upload_file_sha1";
        upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";
        upload_pass_form_field "^submit$|^comment$|^expire.*$";
        upload_store_access user:rw group:rw all:r;
        upload_cleanup 400 404 499 500-505;
    location /nginx-post {
    location / {