This Document is meant to outline the concepts of Saljut, a tool providing access to websites transported via Secure Scuttlebutt.

Motivation

As we use SSB for a variety of things, from microblogging over chess or git-hosting, I haven’t found a tool to publish and retrieve websites that fits my needs.
I want to be able to publish a static webroot under a human-readable domain as well as update this webroot easily. On the other side, I want to access ssb-websites in a regular browser without much user-interaction.

Note
Most of the code-snippets in this document will be written in clojure-syntax. Json-snippets might appear in places where actual json is needed.

Concepts

The Application

The Application will consist of two main components. A web-proxy will transparently pass-through all regular web-traffic and can be permanently configured in the browser. It intercepts requests to .ssb toplevel-domains and try to receive and serve websites from SSB.
The other component will be the publishing-part that let’s you publish a webroot on SSB on a subdomain of your choice.
Since Saljut is a stand-alone application, it can run permanently to allow regular web-traffic when ssb-server is not running. Also it eliminates the current javascript situation.

Domains

The user can freely choose the subdomain of her website. The hostname will be the SSB-pubkey and the toplevel-domain will be fixed to .ssb.
Aliases for the pubkey may also be used to retrieve a users website. The proxy will then perform a key-lookup and, if the alias is locally unique, substitute it with the proper pubkey. In case of a alias-collision, the user will be prompted to choose which pubkey is meant.

Interfaces

As mentioned above, there will be a web-proxy as interface to the browser. All communication with the ssb-server will be performed via it’s local REST-Api. This let’s Saljut work independently of ssb-server implementations and browsers.

Data Flow

The basic data-model for a webroot in ssb will be as follows:

{path-1 blob-id-1,
 path-2 blob-id-2,
 ...    ...      }

Every file in the webroot gets published as SSB-blob. A maping from it’s path to the blob’s id will be saved in a manifest.

Publishing a Website

To publish, the only input needed is the subdomain and the webroot’s directory. From there on, things happen as described in this diagram:

            0======0
            I path I
            0==#===0
               |
               |
               V
     /--------------------\      /-------------------------------------\
     |   get file tree    |      |       upload files as blobs         |
     +--------------------+      |         and save blob-ids           |
     | ["index.html"      +----->+-------------------------------------+
     |  "files/foo.html"  |      | {"index.html" "%niuqniuzpm...",     |
     |  "images/cat.png"] |      |  "files/foo.html" "%jiup3930ca...", |
     \--------------------/      |  "images/cat.png" "%mdu490d4..."}   |
                                 \------------------+------------------/
                                                   /
                           +----------------------+
                          /
                         V
     0===========================================0
     I       generate SSB-Message (json)         I
     #===========================================#
     I { ....                                    I
     I   "content": {                            I     0=====================0
     I     "domain": "foo",                      I     I        url          I
     I     "manifest": {                         I<----#=====================#
     I       "index.html": "%niuqniuzpm...",     I     I "foo.@%jio39...ssb" I
     I       "files/foo.html": "%jiup3930ca...", I     0=====================0
     I       "images/cat.png": "%mdu490d4..."    I
     I     }                                     I
     I   }                                       I
     I }                                         I
     0===========================================0

Retrieving a Website

The retrieving part is a bit more complex but all the parts have already been solved somewhere else. No need to reinvent the wheel here either.

For a better understanding, let’s split this part into two sections. First we’ll assume that we don’t care about aliases, caching etc. and just look at the act of retrieving a website.

 0===================================0      /-----------------------------------\
 I                url                I      | get message-stream of @%niomc90.. |
 #===================================#----->+-----------------------------------+
 I "foo.@%niomc90....ssb/index.html" I      |    <A sequence of objects>        |
 0===================================0      \------------------+----------------/
                                                              /
                    +----------------------------------------+
                   /
                  V
 /-----------------------------------\      /---------------------------------------\
 | filter by message type "webroot"  |      |   take the message with the highest   |
 |         and domain "foo"          |      |        sequence number                |
 +-----------------------------------+----->+---------------------------------------+
 | <a sequence of objects containing |      | <an object containing the most recent |
 |  manifests for the same domain>   |      |      manifest for this domain>        |
 \-----------------------------------/      \-------------------+-------------------/
                                                               /
                    +-----------------------------------------+
                   /
                  V
   /--------------------------------\      0============================0
   | download all files in manifest +----->I serve cache dir and return I
   |         to cache dir           |      I        index.html          I
   \--------------------------------/      0============================0

Now that we have a procedure to retrieve a website from SSB, we’ll have a look at how an actual http-request from a browser would be handled.

      0=============0
      I     url     I
      #=============#
      I foo.@vi.ssb I
      0=============0
             |
             |
             V
    /-----------------\  no   /--------------------\    /------------------\
    | host is pubkey? +------>| perform key-lookup |--->| is alias unique? |
    \--------+--------/       \--------------------/    \----+--+----------/
         yes |                                               |  |
             |                 /------------------\    yes   |  | no
             |  +--------------+ substitute alias |<---------+  |
             |  |              \------------------/             |
             |  |                       ^                       |
             |  |                       |                       V
             |  |                       |           /-----------------------\
             |  |                       +-----------+ prompt user to choose |
             |  |                                   |        pubkey         |
             |  |                                   \-----------------------/
             |  |
             V  V
    /-------------------\   yes    /--------------------\   no
    | is site in cache? +--------->| is timestamp older +--------+
    \--------+----------/          |   than n minutes   |        |
             |                     \---------------+----/        |
          no |                                     |             |
             |               /-------------\   yes |             V
             |               | get latest  |       |    0===============0
             |               | site-mesage |<------+    I serve website I
             |               |  from ssb   |            I  from cache   I
             |               \------+------/            0===============0
             |                      |                        ^   ^
             |                      |                        |   |
             |                      V                        |   |
             |              /-----------------\              |   |
             |         yes  | sequence number |  no          |   |
             |    +---------+ higher than in  +--------------+   |
             |    |         |     cache?      |                  |
             |    |         \-----------------/                  |
             |    |                                              |
             |    |         /------------------\                 |
             |    +-------->| download website |                 |
             |              |  from ssb into   +-----------------+
             +------------->|      cache       |
                            \------------------/

TBD…​