When I said I’d try serving Gemini using Dart, I figured it was at least a half-day project. It turned out to be more like five minutes.
The reason, of course, was that someone has done it already:
And so a minimal Dart server is just this:
import 'dart:convert'; import 'dart:io'; import 'package:gemini_server/gemini_server.dart'; Future<Response> handler(Request request) async => // TODO: canonicalize and check request path before serving! Response( statusCode: StatusCode.success, meta: 'text/gemini', body: utf8.encode(File('root${request.uri.path}').readAsStringSync()), ); void main() async { final context = SecurityContext() ..useCertificateChain('<pem file>') ..usePrivateKey('<pem file>'); await GeminiServer.bind( address: InternetAddress.anyIPv4, port: 1965, context: context, callback: handler, ); }
Of course a bit more code than this is needed to handle different mime types, serving only from under the desired root and missing files; but, you get the idea.
The biggest difficult I had in switching from `agate`, which I had been using, to Dart, was simply converting the certificates that `agate` had auto-generated. After some head scratching the magic invocations turned out to be:
openssl x509 -inform der -in cert.der -out cert.pem openssl pkey -in key.der -out key.pem
The one feature I wanted from my custom server was a way to offer a “one click feedback” mechanism; a way to approximately measure how many people read and liked a post.
Not having seen something like this in gemspace so far, I simply rolled my own:
I experimented with the “UI” added at the end of gemlog entries, settling on something that I hope is as simple as possible but no simpler.
Of course, gemlogs are supposed to be low pressure places away from the bustle of “likes” and other monstrosities of the web; having just created a monster, I hope I then hobbled it sufficiently by not publishing “like” counts at all, anywhere. They are just something I can check for a little guidance on what to write or post next.
We’ll see. I like having a custom server; I also made it apply my
directly when serving `gmi` files so I don’t have to remember to batch update them; and will likely do the same with the index and feed. Coding is fun!
So far today, 2024-11-25, feedback has been received 2 times. Of these, 0 were likely from bots, and 2 might have been from real people. Thank you, maybe-real people!
——— / \ i a | C a \ D n | irc \ / ———