-- Leo's gemini proxy

-- Connecting to ainent.xyz:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini; charset=utf-8; lang=en

smolver development log, part 4


Intro


This is the fourth in a planned series of posts (well, fifth if you count the announcement) where I'll share my experience writing smolver, my Gemini server software, written in Swift.


You can find the previous iterations below. This series has become long enough that I've added a dedicated page for it:


smolver Devlog


Tangent


I wrote this post and did some minor reorganization of this capsule on my shiny new Librem 5 USA (docked). After I get a few weeks of daily-driving it, I might write a review.


Alpha 6


What's changed?


As I'm reviewing the git diff, I remember that I've once again forgotten to add release notes into the tags since then.


These changes are not necessarily listed in the order in which they were implemented:

Enhanced socket server framework to allow retrieving the hostname of a connected socket. This is used for logging purposes, but only if configured to do so (as explained below).

Rethought the configuration plans from an ini file to basic json. As the ini support wasn't even implemented yet, this was just a change to the README

Implement json configuration - no more hardcoding paths! Example config file:


{
    "static": {
        "allowedFileDownloadPaths: [
            "gemlog/",
            "tags/",
            "anySubdirectory/"
        ],
        "requestInterval": 3
    },
    "encryption": {
        "certificateAuthorityPath": "location/of/certificateAuthority.pem",
        "certificateFile": "location/of/certificate.pem",
        "privateKeyFile": "location/of/private.pem"
    },
    "logs": {
        "ipAddresses": false,
        "level": "[none|error|warn|info|verbose]",
        "logPath": "logs/"
    }
}

Swift has out-of-the-box support for json encoding and decoding, so this was a big time saver. I think, as a sever administrator, an ini file might be a bit easier to read, so maybe I'll refactor to support that one day? We'll see.


Refuse to start the server if the configuration file is incorrect, and log the reason to the console. Some of the reasons are still generic Swift error mesages just saying that the json is wrong, but the others were more along the lines of being something that would only mean anything to someone writing and debugging the code, and even then wouldn't really mean much to you unless you had experience with Swift's Codable protocol. This seemed like an unnecessary burden for server administrators, so for those, I customized them into something more administrator-friendly. I'd like to do the others, too, at some point. That said, if you do have Swift experience or would like to learn, and you'd like to lend a hand on the implementation and/or maintenance of smolver once I open it up for public merge requests, I'll welcome any help! I just didn't want to force any arcane incantations or Swift-specific knowledge requirements onto server admins (looking at you, Nextcloud and your requirement to tinker with php and even the raw database at times!).

Minor code cleanup / reorganization

Implemented various configurable logging levels (including completely disabling logs) that will either just go straight to stdout, or additionally to a log directory that will have a new file starting at midnight each day.

Implemented rate limiting (also configurable)

Incorrectly concluded that I fixed auto-redirection to a URL containing a trailing /, if the request is missing said slash AND if that URL points to a directory visible to smolver AND it contains an index.[gmi|gemini] file, only to find out when I double checked it in production that it is still broken. It did work locally, but I think I have an idea of what's going on now so that's on the list to fix for the next alpha build.

Explicitly disallow requesting content unless it is opted into via the configuration file. I forget the exact behavior before, but now, if content is requested, and its directory is not listed in the "allowedFileDownloadPaths" array in the config file, it won't allow access.

More minor backlog tweaks


NB: Only subdirectories nested within the same directory as the configuration file are allowed to be configured. This is checked as soon as the application starts, and won't run if you try to allow access anywhere else on the system. I figured it is a bit more secure this way.


Thoughts


Overall, the total lines of code grew, relative to what it was before, quite a bit. Running cloc on v0.0.14 returns:


cloc Sources
       6 text files.
       6 unique files.
       0 files ignored.

github.com/AlDanial/cloc v 1.86  T=0.09 s (69.8 files/s, 8998.8 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Swift                            6             89            148            537
-------------------------------------------------------------------------------
SUM:                             6             89            148            537
-------------------------------------------------------------------------------

Running cloc on v0.0.15 returns:


cloc Sources
       9 text files.
       9 unique files.
       0 files ignored.

github.com/AlDanial/cloc v 1.86  T=0.11 s (83.0 files/s, 12206.3 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Swift                            9            163            240            921
-------------------------------------------------------------------------------
SUM:                             9            163            240            921
-------------------------------------------------------------------------------

These numbers do not include dependencies.


That is a growth of 384 lines.


I think it speaks a lot to Gemini's simplicity that such a significant percentage of the server code is dedicated to app administration and not compliance with the protocol itself.

-- Response ended

-- Page fetched on Tue May 21 19:15:13 2024