Gemini related stuff
NOTE(2021.10.27): The server is down for unknown reason. I'm not planning to put it back up because I'm already done with Project Gemini. If you don't know, Project Gemini is an attempt of creating a network that uses something "heavier than gopher and lighter than web". While this is impressive and all, I don't think this will be the "right" answer to the question "why does the bloat of modern web exist and how can we deal with it" (even though I'm not saying Gemini is trying to be that). People created the bloat because they need more functionalities but Java Applets and Flash have died for good, so these functionalities ended up being stuffed into the web stack. I'm currently organizing my thought on this particular topic. For example, imagine a parallel world where REBOL had won, or Flash had become open-source; what would the web become at that point?
Three projects have spawned since 2020.11.1:
- An NPM package; didn't know how scoped package works in the NPMJS.org registry, ended up taking this name.
- Syntax highlighting for VSCode.
- A tiny Gemini server.
The 0th day, 2020.11.1
I have all these gemini related side project idea sitting in my side project to-do list. To be honest, it is exactly this kind of side projects that really bugs me nowadays - not so hard so you can figure out how to finish it in under 5 minutes, not so easy so you'll probably spend more than 5 nights to finish it, involves a bit of parsing so that a good part of it will be *very* boring, and does not look exactly impressive as a part of a portofolio. If you don't give up on the idea, it'll stay forever. In some ways very annoying. Better finish it early so I can move on with other things.
Wrote the gemini-to-html package gemtext, release 0.0.2.
The 1st night, 2020.11.4
Wrote a half-baked prototype client just to test things out. Fused the client with an http server so it (almost) works as a gemini-to-http proxy.
Found bug in gemtext (the package I wrote earlier). Fixed it locally, didn't publish because it was already 3 o'clock in the morning and I had work the next day.
Actually wanted to do a proper TUI client, but:
- Can't trust any `curses` wrapper library on npmjs.
- Making TUI yourself (either by wrapping `curses` or manually churning out ANSI escape sequence(!)) is in itself an ordeal. Let's not get Donald Knuth Syndrome here.
A proxy is good enough for me for now. I did have imagined a "client" that works by starting a local gemini-to-http proxy though.
Decided to write down what happened and what I have thought during the coding process. I tend to work till late night (around 2 or 3 o'clock in the morning) so I very probably will write down gibberish or strange, wrong stuff because I'm like half-sleepy. Yet I decided not to edit or tidying up anything.
The 2nd night, 2020.11.5
Published the fix for gemtext.
Last night I was stuck on status code `1x`; I thought I have to send the query data **after** sending the request header. Turns out I'm stupid. Gemini does not work like that. Not even HTTP works like that.
Someone in the mailing list mentioned the "multi-line meta". Well that only means "you very probably shouldn't just do a quick regex match" to me. Actually you shouldn't have to. Parsing headers are simple, you can assume a lot of stuff like "3rd char must be space or it's an error".
Did a bit clean up for the prototype code. The proxy runs on nodejs, so I should be able to use all the fancy ES2015 constructs.
Now there's another thing that keeps annoying me in the last few years: in a lot of scenarios I can do things in this way or in that way; either way, it's same amount of work, none fullfilment whatsoever. It's more painful to realize "software engineering" are things that you can only be like "it's all trade-offs" than "it depends", especially when it comes to the situation where every approach has the same outcome and the same cost.
Recovery after crashing, very important part which beginners might ignore. Don't ignore that.
Who needs expressjs for a project like this? I did the thing just for kicks anyway. I'll handle every single http request on my own. Should definitely have some helper functions (mostly for routing), but to achieve expressjs-like that involves a little bit of parsing.
The 3rd night, 2020.11.6
Had a bad day at work. I'm starting to doubt if I'm really competent for the job.
Guess I should set up a basic gemini site first.
So I wrote a simple gemini server that simply serves text files on the disk, and for the content I'll use git, add some git hooks and it'll automatically update the content directory every time I update the git repo, just like how I'm managing my http homepage right now. I don't want to use an existing client for testing because in the beginning there is none and I want to prove to myself that I can carry out the whole thing. I hate relying on things that I could have be okay without. So I went with my half-baked local gemini proxy. Turns out writing a gemini proxy is way more work than writing a minimal gemini server.
text/gemini does not support nested lists; to me, even though it's understandable, that's still kind of a shame. I use nested lists in my writings a lot, I wonder if I can live without it.
I consider the thing (server) done. It's 3 A.M. right now, I'll leave the deployment job for tomorrow. Should I deploy my gemini-to-http proxy as well (when it's finished)? I can't really decide.
There's no gemtext support in vscode (that or I cannot find one). Might write one too.
The 4th night, 2020.11.7
Published the vscode syntax highlighting for gemtext.
vscode extension page
The 5th day, 2020.11.8
Had a terrible headache last night so I had to sleep early (with "early" I mean "earlier than 5 A.M.").
Deployed the simple gemini server. Currently it does not serve anything other than text files, because that's what I only need it to do right now.
First piece of Chinese content in the "geminiverse" maybe?
The git hook part always got me with all the permission issues. Definitely should set up some kind of proper CI stuff.
Speaking of git, if you're managing & deploying content using git like me, you should definitely block off any request to `/.git` directory (or all "dot" directory altogether). Last year (in May probably, kinda forgot) my gitlab account was compromised (now recovered) & people said it's because those who had their account being compromised deployed their apps as a whole git repo and the `.git` directory, seemingly contains passwords and stuff, become the target for attacking. At least that's the theory.
server code git repository
The same night, 2020.11.8
Added a basic CLI for the gemtext package.
I should definitely have a central store for all my blogposts.
The 6th night, 2020.11.9
Just found out that proxy.vulpes.one uses Iosevka. No wonder that the font looks so similar. Good taste.
Surprisingly, writing a client for gemini is much harder than a proxy; the difficulty, it's client > proxy > server. The big problem is how you do the layout & stuff. A gemini server doesn't have to worry about layout. A proxy has the browser to do the layout. A client has to do it on its own. If you do a terminal client, get ready to say goodbye to a lot of "eccentric" scripts (I doubt Noto will do well); if you do a graphical client, it's either you drive yourself crazy, or say goodbye to a lot of "eccentric" scripts. Yes you don't have to consider mixing traditional Mongol script with Hebrew script with normal latin script, but still.
I want to do something else so I decided I've had enough. This trip will stop here temporarily.
The 7th day, 2020.12.5
Added some kind of "local proxy". It's not really a proxy because it directly serves the files instead of talking to the gemini server part.