2
6
Fork
You've already forked snurl
0
smolnet client and library
  • Zig 100%
Anna Liberty 6584056a83
Extract hostname encoding into utils
These were not a part of the original library and were written by me,
as such I can release them under the same license as the rest of the
library.
2026年06月30日 13:02:33 -07:00
src Extract hostname encoding into utils 2026年06月30日 13:02:33 -07:00
.gitignore Add zig-pkg to .gitignore 2026年06月27日 11:50:15 -07:00
build.zig cli: add flags 2026年06月19日 08:45:21 -07:00
build.zig.zon cli: add flags 2026年06月19日 08:45:21 -07:00
LICENSE Add initial version 2026年05月30日 10:49:34 -07:00
README.md README: fix library example 2026年06月26日 06:17:38 -07:00

snurl

Comprehensive yet simple smolnet client and library.

You should be able to use this as a well-tested foundation for any smolnet client.

Goals:

  • Be reusable across languages, operating systems, and TLS implementations
  • Be thorougly tested and fuzzed across platforms
  • Include both transactional and streaming APIs
  • Full specification support for a variety of smolnet protocols

In short, be the cURL of the smolnet.

snurl has not yet reached these goals.

snurl is a labor of love and has been written without the use of LLMs in any capacity. Contributors are held to the same expectation.

Installation & Usage

Dependencies

The latest release of Zig is targeted that is also supported by all other dependencies. anyzig is recommended.

snurl will export a C library that can be linked from other projects. For this, the only dependency will be a supported TLS implementation.

CLI

$ git clone https://codeberg.org/liberty/snurl
$ cd snurl
$ zig build

You can then copy or execute the snurl binary found in zig-out/bin/.

$ snurl gemini://geminiprotocol.net/
$ snurl spartan://spartan.mozz.us/
$ snurl gopher://gopher.floodgap.com/
$ snurl finger://tilde.team/

Use snurl --help for more information on using the CLI.

Library

$ zig fetch --save git+https://codeberg.org/liberty/snurl

Then add this to your build.zig:

constsnurl=b.dependency("snurl",.{});exe.root_module.addImport("snurl",snurl.module("snurl"));

Then from your code you can make requests:

conststd=@import("std");constsnurl=@import("snurl");fnmain(init:std.process.Init)!void{constio=init.io;// Prepare stdout for writingvarstdout_buffer:[1024]u8=undefined;varstdout_writer=Io.File.stdout().writer(io,&stdout_buffer);conststdout=&stdout_writer.interface;// Stores the status returned from the servervarstatus_buffer:[1027]u8=undefined;// Configure the snurl clientconstoptions=snurl.Client.RequestOptions{.input=null,.timeout=.none,.status_buffer=status_buffer,};consturi=trystd.Uri.parse("spartan://example.com");trysnurl.Client.request(uri,stdout,io,options);}

Status

Support for following protocols is planned:

  • Spartan
    • Fetch pages
    • Uploads (via --input flag)
  • Gemini
    • Fetch pages
    • Input data
    • Certificate validation
    • Client Certificates
  • Gopher
  • Gophers
  • Finger

Existence and maintainability are the criteria for inclusion in snurl. As long as a protocol is used in the smolnet and is simple enough to be maintainable, it can be added to the roadmap. If a specification doesn't exist or is permanently offline, it is unlikely to be implemented.

TLS Implementations

Gemini and Gophers require TLS. To support a variety of TLS implementations on various platforms, snurl abstracts them and interacts with them similarly.

snurl targets:

  • OpenSSL
  • BoringSSL^
  • LibreSSL^
  • Zig's std TLS
  • GnuTLS
  • WolfSSL (partial)
  • RustTLS
  • Mbed TLS

Use the -Dtls build flag to choose which TLS implemenation to use. For example, run zig build -Dtls=wolfssl to build with WolfSSL. The default is openssl.

snurl will never support any TLS version older than 1.2.

Testing

snurl will be extensively tested to ensure the code is of an acceptable quality. Because of this, will make extensive use of unit tests, integration tests, and fuzzing.

Run zig build test to run all tests.

Note: These are currently goals, not realities. Currently most easily testable functions are tested but integration tests and fuzzing are not.

Unit Tests

  • Every function is tested. The goal is 100% code coverage with every line of code tested to ensure proper behavior.

Integration Tests

Each protocol implementation is tested against example servers for proper support.

  • Spartan
  • Gemini
  • Gopher
  • Gophers
  • Finger

Fuzzing

The entire codebase will be attached to Zig's builtin fuzzing system to ensure proper behavior for all possible inputs. snurl should never crash or trigger undefined behavior. Secondarily, all errors should be caught and converted into friendly error messages.

License

This software is licensed under the MIT (Expat) license. More information see the LICENSE.