I want to use the Zig programming language for quite some time now. Did some ziglings and read some documentation, but never program something useful. I want to change this on this december adventure by programming a gemini application.
=> Zig Programming language | ziglings
So, what's the plan? First thing will be refreshing the basics of the language by doing some ziglings. When I feel confident enough, I will start working on the basics of the gemini application, which might be reading through the Gemini specification and finding a suitable gemini server with CGI support. After that, I want to build some basic request/response and deliver a basic string. If that works, I can continue building the actual application.
The application should help maintain a simple "server log". Like a simple gemlog, it contain a list of entries, order by date, which describe some action, taken on the server. We maintain this for the økoyono server manually, but lost some interest in it. Adding new entries should be therefore simple and easy, straight from the gemini browser. Authentication should be done with a client certificate whitelist. The data should be stored directly into the file itself, so no separate database is needed.
It's not a complex application, but it has a real usecase and if I finish it ealy in december, I can always add more features or change plans.
=> Gemini Application Developer Guide | RFC: TinyLogs format | twins Gemini Server
I want to have something useful as soon as possible. So I've created a simple docker compose file which will spin up a twins server with a FastCGI configuration attached to a newly created zig project. This works as intended, so I can continue working on the actual server. For that, I've started reading through both of the following articles and the zig test file for http itself.
=> Building a HTTP server in zig | TCP server in zig | http.zig test file
With that, I've just copy/pated some code, so I have someting to test on. Tomorrow, I will go into the code and try to build some simple request. 30 minutes are not long, so I keep focusing on one part only, not worry about 1000 other little things, which need to be addressed along the way. One step at a time.
=> Git repository for my #decemberAdventure
Did not get any real programming done today. I've created a self signed SSL certificate, so I can test the gemini server and the FastCGI integration. Turns out, the FastCGI protocol is much more complicated as I initially thought. So I've searched the twins gemini server source code how to integrate my zig program more easily. There is a "command" type, which can be used to execure applications. This might be the simpler way to integrate a zig application into the gemini server. Next step will be write some simple bash script to test the command type.
=> serve_command.go from twins gemini server
Not much done today on the #decemberadventure, had a long work day and a lot of other stuff to do, which keept me busy the whole day. But I wanted to do a little test with a bash script to test the command type. Turns out, it's really simple and works as expected.
I've created a simple proof of concept in bash to check how to access user input. This works fine and provide a good template for Zig, so I have a clear goal. Next will be starting with the actual Zig program. Let the fun begin!
=> Simple proof of concept in bash
No time at all to get something meaningful done :(
Started building a simple application in Zig, which can read a file, and output it on STDOUT. Nothing complicated, but learned a lot on allocators, buffers and how Zig managed memory. Tried to add subcommands to the application, so I can do different things like listing the content of the file or append to it. Turns out, comparing strings in Zig is not an easy task, so I decided to go on an adventure and add a external lib to it (zig-clap). This lib should parse the commandline parameters and make work with it a little simpler. Sadly, this does not work out of the box and need some investigation tomorrow.
=> https://github.com/Hejsil/zig-clap
I removed the zig-clap dependency again, becaus the current release is lacking subcommands and the current HEAD is broken. So back to basic zig standard lib, which works quite nicely.
Today, I've implemented the second subcommand (create a new entry), which was straightforward with the standard library -- except formatting the current date and time. Not sure why, but the standard lib does not support such a simple task (or am I wrong?). So I had to build my own date formatting thingy.
I used a lot of "try" statements to make progress. But this ignores any possible errors and if an error occurs, the whole application crashes. Today, I replaced all "try" statements with actual error handling. This was not that easy, but some people on the #zig IRC channel helped me a lot. The following lines took me an hour, but learned a lot on the way.
while (inStream.readUntilDelimiterOrEof(&buf, '\n')) |line| { write(Target.Stdout, "{s}\n", .{ line orelse break }); } else |err| { write(Target.Stderr, "error while reading the file: {!}\n", .{err}); }
I worked my way to the code and made things a little neater. One thing is still missing: Not everyone should be able to create new entries. Some sort of identity management need to be set in place here. Gemini uses client certificated for that, so I will read through the specification of that today.
Some times, things change in life drastically. Life changes to death. I lost a person, who was very important for me. He died last week. So, priorities change, so as for this project. I will continue when the time is right.
text/gemini; charset=utf-8; size=6656
This content has been proxied by September (ba2dc).