Skip to content
Tags give the ability to mark specific points in history as being important
  • v1.5.4
    30a4ebc7 · Release v1.5.4 ·
  • v1.5.3
    d929bdd9 · Release v1.5.3 ·
  • v1.5.2
    8ea34a6e · Release v1.5.2, take 2 ·
    - [x] Swift 5.9 seems to execute code (unit tests) noticeably faster. Test if the "CGI bug" listed in `known-issues.md` is still a problem. - it is still a problem
    - [x] Refactor all custom `Error`s to implement `errorDescription` instead of `localizedDescription` so you don't have to worry about downcasting them all.
    - [x] Figure out how to get code coverage reports without Xcode
      - swift test --enable-code-coverage --show-codecov-path
      - [x] Find ready-made tool that generates visual report from JSON file from above command
      - `llvm-cov`
      - [x] script the above command to generate report
      - [x] works: `llvm-cov report .build/aarch64-unknown-linux-gnu/debug/smolverPackageTests.xctest -instr-profile=.build/aarch64-unknown-linux-gnu/debug/codecov/default.profdata --ignore-filename-regex=.build`
      - [x] pair output lines with a custom line: "has test file? (Y/N)" to allow for easily finding tests that accidentally leak into testing other files
      - [x] Do this for SocketServer too
    - [x] Script new file creation
    - [x] Refactor unit tests to use more private helper methods, too much duplicated code
    - [x] Fix code coverage "leakage" by breaking ResponseTests.swift down into separate files like the prod code (suspected semi-false positive due to the way the coverage script determines leakage vs. how this file is structured)
    - [x] Remove all SwiftLint configurations, and references in any scripts
    - [x] Refactor EnvironmentVariables to not have a `dictionary` property, but to be subscriptable
    - [x] Backlog meta
      - [x] Restructure backlog/ contents, update documentation accordingly
      - [x] Add reminder within new `v2-x/` dir
    - [x] Refactor install.sh
      - [x] Recommend Swiftly
      - [x] Switch to `bash`
      - [x] Use Swift package manager to install smolver (simplifies script!)
      - [x] Simplify logic
  • v1.5.1
    d8deb817 · Release v1.5.1 ·
  • v1.5.0
    344d5ffa · Release v1.5.0 ·
    - [x] Enhance CGI support to allow arbitrary data (such as images, other non-"text/" mime types) to be returned. Update current note in `README` that says this is not yet supported. Update any comments as well.
    - [x] Fix (suspected) issue where if you return an unknown mime type, a CGI error will be returned instead (verify this behavior via a unit test first).
    - [x] Evaluate diff since last release for need of any new/modified logs
    - [x] Fix incorrect manpage display of list of CGI error scenarios
    - [x] Fix incorrect manpage display of list in auth whitelists section
    - [x] Expand contributing section with another item for unit tests for enhancements to existing files already covered by unit tests
  • v1.4.0
    47508779 · Release prep for v1.4.0 ·
  • v1.3.0
    - [x] Configuration of maintenance mode (response status code 41 SERVER UNAVAILABLE)
    - [x] Configurable support for the 52 gone response code
    - [x] Configurable support for both redirect response codes
    - [x] Audit for all remaining unreturned response codes, evaluate if it makes sense to allow configuration of them
      - Summary of findings: smolver returns every applicable status code, or allows it to be returned via CGI. No changes needed. Details below.
    
      - Currently returnable status codes, per smolver codebase:
        - 20
    
        - 30
        - 31
    
        - 40
        - 41
        - 42
        - 44
    
        - 50
        - 51
        - 52
        - 53
        - 59
    
        - 60
        - 61
        - 62
    
      - Status codes smolver never returns:
        - 10 INPUT - This only applies for dynamic queries, which is only supported via CGI. CGI scripts should be returning this, not smolver. Won't change.
        - 11 SENSITIVE INPUT - This only applies for dynamic queries, which is only supported via CGI. CGI scripts should be returning this, not smolver. Won't change.
    
        - 43 PROXY ERROR - smolver does not support proxying directly, unless you do it via CGI. CGI scripts should be returning this, not smolver. Won't change.
    - [x] Audit all configurable response codes, evaluate if any need configurability for meta
      - None needed at this time
    - [x] Response language(s) configuration
      - [x] Default language(s) in `config.json`
      - [x] File-by-file overrides via `.smol.json'
      - [x] Override entire directory via `.smol.json'
    - [x] Configuration of arbitrary mime types paired with file extension. Much easier to do this than to implement and maintain a list of every possible one.
      - [x] More common ones should all work out of the box.
      - [x] File-by-file overrides via `.smol.json'
      - [x] Override entire directory via `.smol.json'
      - [x] Add note to README (similar to language) about duplicating config for subdirectories
      - [x] Make sure this works with CGI output as well, add more CGI unit tests for a few newly supported text/ mime types
    - [x] Remove references within code, documentation, about planning to support non-utf8 charsets
    - [x] Re-review all changes for this release, make sure logs are adequately placed and of an appropriate level
    - [x] Reprioritize backlog so all new features come next, then internal changes
  • v1.2.1
    c3920383 · Bump version to v1.2.1 ·
    - [x] Disallow serving of .smol.json files
    - [x] Disallow serving of authentication files systematically configured via anonymous authentication
  • v1.2.0
    dda61d48 · Merge branch 'cgi' ·
  • v1.1.0
    - [x] Update local to latest Swift version
    - [x] Smoke test
    - [x] Address any and all warnings
    - [x] Fix invalid json in README and example json file
    - [x] Update production to latest Swift version
    - [x] Rip out static site generation TODOs, move into separate repo
    - [x] Make sure all TODOs are addressed
    - [x] Update README
    - [x] Audit code changes for loggable scenarios, including misconfigurations for new config file updates
    - [x] Merge and tag SocketServer
    
    - [x] Implement
    
    -  Short-lived client certificates are allowed
      - Generated on demand
      - Deleted immediately after use
      - Can be used as a "session identifier" to maintain server-side state for applications
      - Substitute for HTTP cookies, only generated voluntarily by the client, and once client deletes it, server cannot possible resurrect same value later
    - Long-lived client certificates can be used for authentication into multi-user applications without passwords
    - Self-hosted, single-user applications can be secured in manner familiar with OpenSSH, analogous to the `.authorized_keys` file for SSH
    - Gemini requests typically made without client certificate
    - Client certs created in response to a server request for one (via response code)
      - [x] Has its scope bound to the same hostname as the request URL and to all paths below the path of the request URL path
      - Interactive clients are strongly recommended to make deletion / temporary deactivation of certificates easy and to give users full control of client certificates
  • v1.0.0
  • v0.5.0
    32a9ee03 · Merge branch 'beta5' ·
    - [x] Normalize all logs so they line up in nice neat columns. Issue is that not all logged components, such as: IPv4 addresses, as a string; or the warning level (INFO vs. WARNING), have the same length.
    - [-] Logs with just a status code, no meta, have an extra trailing space # Changing this causes some clients, like amfora, to show a general error message instead of what the server actually returned
    - [-] Requesting a URL for a document with a trailing slash returns the correct document, but breaks relative links on the page. Fix by initially just redirecting back to the document itself, without the trailing slash # Unable to reproduce as of 2022-06-13 - Tried: Lagrange, amfora, and 2 web proxies
    - [-] Setting logs.level to none in `config.json` causes hang on program start. No errors. No output whatsoever. # This is working as expected - no logs means no logs, even the "smolver listening" message
    - [x] Logs that state "illegal logging configuration" have an extra whitespace
    - [x] Invalid to/from redirect file configuration causes a nonsensical logging message
    - [-] Unable to link to any file at capsule root besides index # On second thought, this is working as intended. Allowing this would be a potential security hole
    - [x] Fix log for "Invalid host" - it logs `Optional("HOST")`
    - [x] Fix log for "Invalid scheme" - it logs `Optional("SCHEME")`
    - [x] Only setting logs.level to none, with no other logging config, and the app won't start
  • v0.4.0
    30bc4d18 · Bump version number ·
  • v0.3.0
    - [x] Quickly analyze logs again to determine if any new ones have appeared (quick glance, there *is* at least one new one. check them all again
    - [x] Triage list of unique errors:
      - [-] SYSTEM: ERROR: Aborting due to unrecoverable error: Error code: 336151576(0x14094418), ERROR: SSL_accept, code: 336151576, reason: ssl3_read_bytes:tlsv1 alert unknown ca # intermediate certificate incorrect, try switching to self signed cert? This is so sporadic, I'm not sure it's worth the effort to research further at this point. will contine to monitor
      - [x] SYSTEM: ERROR: Error: Error code: 336130315(0x1408F10B), ERROR: SSL_accept, code: 336130315, reason: ssl3_get_record:wrong version number # caused by connecting with too low SSL version or no TLS at all
      - [-] SYSTEM: ERROR: Error: Error code: 336151570(0x14094412), ERROR: SSL_accept, code: 336151570, reason: ssl3_read_bytes:sslv3 alert bad certificate # server demands client authenticate with a certificate, but client did not; or could be serverside ssl cert issue; or cert not created correctly. could this be from when my cert expired? will contine to monitor
      - [-] SYSTEM: ERROR: Error: Error code: 336191759(0x1409E10F), ERROR: SSL_write, code: 336191759, reason: ssl3_write_bytes:bad length # all I could find on this was bad data can cause it, no specifics on what constitutes "bad data" in this context. hopefully mitigated in this release, will continue to monitor
      - [-] SYSTEM: ERROR: Error: Error code: 5(0x5), ERROR: SSL_accept, code: 5, reason: DH lib # one source (stack overflow) says this is improper error handling, but that is all in the dependency. will continue to monitor. update: code comments in SocketServer say that this can happen when trying to connect too many times in rapid succession
      - [-] SYSTEM: ERROR: Error: Error code: 5(0x5), ERROR: SSL_read, code: 5, reason: DH lib # caused by concurrent connections, wrong client ssl version, or cert claim invalid, keep an eye on this around when cert expires next. will continue to monitor
      - [x] SYSTEM: ERROR: Error: Error code: 5(0x5), ERROR: SSL_write, code: 5, reason: DH lib # Diffie-Helman cypher issues? defering to future state as this may already be planned to be covered there? was able to sporadically reproduce using gemini-diagnostics tool, and so fixed it in this release
      - [x] SYSTEM: ERROR: Error: Error code: 6(0x6), ERROR: SSL_write, code: 6, reason: EVP lib # one source says the connection may be torn down before ssl_shutdown is made. reproduced sporadically with the TLSVerified check in gemini-diagnostics
    - [-] After fixing these, the unexpected log files should no longer happen. Re-run the test scenario listed here: # After debugging, this appears related to Log.swift:124-129, where the logs get written to disk. Running the gemini server stress test against localhost while modifying the Log code to write the error in the `catch` statement in the lines listed above and to prefix a "CAUGHT ERROR" message, did not result in any logs with a "CAUGHT ERROR" message, but it did result in these unexpected file names. These files happened at the exact time that I was restarting the server due to the stress test forcing it to shut itself down, which smolver does intentionally (for now) in some error scenarios. Given this, and the fact that the logs are written to the file atomically, I can only assume that these files are tmp files created by the file writing API, and the log is happening right around the same time the server is shutting itself down, and so the file APIs never have a chance to remove the tmp file. Revisit this after fixing the intentional shutdowns to gracefully close the socket connection instead. They should be gone once all the SSL reboots are fixed. If not, will need to keep digging. As this release does not address *all* of the SSL reboots, just most of them, this problem is still happening, as expected.
    - [x] When deploying this, move existing server logs to new subdir so that you can monitor new logs for improvements. There should be fewer app restarts after this release.
  • v0.2.0
    701e288b · Bump version number ·
    Usability enhancements:
    
    - [-] Enhance redirects # Canceled
      - [-] Allow redirecting an entire directory at once # Fails cost / benefit analysis -- Gemini discourages redirects anyway, and it's not like I have dozens of files all being rearranged. At this time, not worth the time to develop and test. May possibly revisit in future.
      - [-] Allow redirecting a deleted directory # The current implementation makes more sense, keep the .smol.json where the old directory is
    - [-] Fix bug where directories named with a period and containing an index file will not redirect to / if requested without / # This is really no big deal, I'm reprioritizing for later
    - [x] After looking at the historical logs a few times, I have noticed that sometimes some things appear out of order. Research logs some more to confirm, and fix # Could not find actual occurrence of this, but some things did look odd in that 44 (slow down) responses did not log the request that triggered it, so I fixed that instead. Similar thing for requests for a directory, without an index.[gmi|gemini] in the request URL, but when that index file existed -- in that case, there were 2 request logs (due to an implementation detail, not 2 actual requests), so I bumped a debug log that would happen in between those 2 'requests' up to info so it's clearer what's happening
    - [-] Quick glance through the logs and it looks like the rate limiting only works if the subsequent request comes in on a new second. i.e., hh:mm:11.22 hh:mm:11.50 - won't get rate limited, but hh:mm:11.22 hh:mm:12.10 will. Research logs some more to confirm, and fix # Looked through the logs again, even around the time that I committed this note, and I see no evidence of this. What I do see is logs that could easily be misinterpreted due to the oddity noted and addressed in the point above this one. Writing it off as a misreading caused by the same.
    - [x] Seeing other errors in logs... get list of all errors (unrecoverable or otherwise) and triage
    - [-] Logs are creating unexpected file names. Not sure what's going on? Random thought: cross reference the first timestamp in each of these files with logs in other files indicating crashes or freezes. # After debugging, this appears related to Log.swift:124-129, where the logs get written to disk. Running the gemini server stress test against localhost while modifying the Log code to write the error in the `catch` statement in the lines listed above and to prefix a "CAUGHT ERROR" message, did not result in any logs with a "CAUGHT ERROR" message, but it did result in these unexpected file names. These files happened at the exact time that I was restarting the server due to the stress test forcing it to shut itself down, which smolver does intentionally (for now) in some error scenarios. Given this, and the fact that the logs are written to the file atomically, I can only assume that these files are tmp files created by the file writing API, and the log is happening right around the same time the server is shutting itself down, and so the file APIs never have a chance to remove the tmp file. Revisit this after fixing the intentional shutdowns to gracefully close the socket connection instead. They should be gone at that point. If not, will need to keep digging.
    - [x] Tweak log messages so it is easier to tell at a glance what is a request/response/error
    - [x] Double check and update copyright dates and years in all files. `main.swift` is wrong, not sure about others
    - [x] Cleanup
      - [x] Install script to only copy the final smolver binary to the required location, not all the other stuff that `swift build` outputs
      - [x] systemd service file
    - [x] Reword the first "Redirecting" in the following location to "Redirection"
      - [x] Sources/smolver/Spec/Router.swift: Log.debug("Redirecting configuration correct. Redirecting to new location", from: .remote(hostname: hostname))
    - [x] Cleanup the following error message: "unstandardized path relative path"
      - [x] Sources/smolver/Admin/GeneralConfigFileDecodingError.swift: unstandardized path relative path detected. All paths must be relative to ~\(GlobalConfiguration.smolverSubdirectory) and cannot contain `.` or `..`. Offending element: "\(key)": "\(path)
    - [x] Run the Gemini server stress test against this codebase, prioritize issues found
  • v0.1.0
    5ebe4f67 · Bump version ·
    Bug fixes:
    
    - [x] Too many connections too quickly logs an error and then the server is unresponsive, but doesn't crash - implemented a workaround: shutdown the server in this scenario and let systemd take care of the restarting ... should be ok for smolver, but not for the MUD, so I opened a ticket in SocketServer's repository to track this
    - [x] Too many connections too quickly and app crashes, same problem as in MUD
  • v0.0.19
    c7d5bde8 · New version ·
  • v0.0.18
  • v0.0.17
    - [x] Configurable redirects
    - [x] Update README.md
    
    - [x] Implement the following
    - [x] Update README.md
    
    Add a `.smol.json` file in the *old* directory of the file(s)
    ```json
    {
        "redirects": [
            {
                "oldFileName": "name-of-an-old-file-in-this-directory.gmi",
                "newFileName": "new-file-name-1.gmi",
                "newFilePath": "new/path/relative/to/config"
            },
            {
                "oldFileName": "name-of-another-old-file-in-this-directory.gmi",
                "newFileName": "new-file-name-2.gmi",
                "newFilePath": "new/path/relative/to/config"
            }
        ]
    }
    ```
    
    1. Install the [Swift](https://swift.org/download/#installation) language for your platform, if not already installed
    2. Run the following:
    
    ```zsh
    $ git clone git@gitlab.com:g2764/smolver.git
    $ ./install.sh
    ```
    
    This will:
    - Download dependencies via the [Swift Package Manager](https://github.com/apple/swift-package-manager)
    - Build dependencies and server
    - Install the binary in `/usr/local/bin`
    - Create a `~/.smolver/` directory, with all the necessary default configurable keys (see [`Usage`](#usage) for customization / required tweaks)
    
    If you want to make this run on boot, use your choice of `cron`, a `systemd` service, etc.
    
    2. Start the server
    ```zsh
    $ smolver run # any misconfigurations in `config.json` will cause the server not to `run` and will output appropriate human-readable error messages.
    ```
  • v0.0.16
    - [x] Visiting a directory without a trailing / causes any relative links in that directory to fail - works locally, but not in prod because prod url has .domain, local does not. Look at Request.swift where it sets the forceRedirect flag
    - [x] Move `requestInterval` property in the config file out of the "static" section; that section is intended for configuring static *content* only
    - [x] Rename `static` property in config file to `staticContent`
    - [x] Redesign the `ini` example below in `json`; `ini` would require implementing a custom parser
    - [x] Enhance `config.json` with support for:
    - [x] Update README.md
    
    ```json
    "shouldServeRobotsFile": true
    ```
    
    - Gemini's adaptation of the web's de facto standard robots.txt
    - For controlling access to content by bots
    - robots.txt states desired bot policy in machine readable format
    - Authors of bots are strongly encouraged to check for such policies and to comply with them when found
    - Server admins should understand that it is impossible to enforce a robots.txt policy and must be prepared to use firewall rules, etc. to block access by misbehaving bots
      - This is equally true of Gemini and the web
    
    - [x] Lives at root /
    - gemini://example.net/robots.txt
    - [x] Should be served with a MIME media type of text/plain
    - Format is as per the original web spec for robots.txt:
      - Lines beginning with # are comments
      - Lines beginning with "User-agent:" indicate a user agent to which subsequent lines apply
      - Lines beginning with "Disallow:" indicate URL path prefixes which bots should not request
      - All other lines are ignored
    - Only non-trivial difference between robots.txt on the web and Gemini is that, because Gemini admins cannot easily learn which bots are accessing their site and why (because Gemini clients do not send a user agent), Gemini bots are encouraged to obey directives for "virtual user agents" according to their purpose/function (described below)
    - Regardless, Gemini bots should still respect
      - robots.txt directives aimed at a User-agent of \* (less the \)
      - May also respect directives aimed at their own individual User-agent which they, e.g., prominently advertise at the Gemini page of any public services they provide
    
    - A common category of bot
    - Bots should respect directives aimed at any virtual user agent which matches their activity
    - If bot meets multiple virtual user agent definitions, it should obey the most restrictive set of directives arising from the combination of all applicable virtual user agents
    
    - Fetch content to build public long-term archives of Geminispace
    - Will serve old Gemini content even after the original has changed or disappeared (think "Wayback Machine"
    - Should respect robots.txt directives aimed at a User-agent of "archiver"
    
    - Fetch content to build searchable indices of Geminispace
    - Should respect robots.txt directives aimed at a User-agent of "indexer"
    
    - Fetch content to study large-scale statistical properties of Geminispace (page/domain counts, distribution of MIME media types, response sizes, TLS versions, frequency of broken links, etc.), without rehosting, linking to, or allowing search of any fetched content
    - Should respect robots.txt directives aimed at a User-agent of "researcher"
    
    - Fetch content to translate said content into HTML and publicly server the result over HTTP(s)
    - Should respect robots.txt directives aimed at a User-agent of "webproxy"