💾 Archived View for gemini.thegonz.net › glog › 210508-multilineInput.gmi captured on 2021-11-30 at 20:18:30. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

Multiline input in Gemini

Background

Gemini is a line-based protocol. You submit a request consisting of a single line to a server, and it responds with a sequence of lines.

Something which has come up repeatedly is that this makes POST-like interaction and file upload difficult. Various solutions have been proposed, including using an existing protocol like ssh (sftp/scp), new "side-protocols" designed to handle uploads and/or POST including Titan and Dioscuri, and hacks like "gemini://example.com/upload?file=foo&bytes=3601-4500&data=[...]".

The commonly accepted line seems to be: this is not what Gemini is for, don't try it. I'm not sure I actually disagree, but nonetheless I'm here to argue for the opposite.

Ancient wisdom

Let's return to the line-based nature of Gemini. As I've tried to push before, to me it seems natural to consider the analogy with classic line-based unix programs like ed, which also proceed by accepting a single line of input, doing something with it, responding with some lines of output, and then waiting for another line of input. So how do you do multiline input in such a program? By... inputting multiple lines. So why not do the same in Gemini?

In both cases, the main difficulty is how to indicate the end of input. One classical convention for this, used by ed's input mode and by SMTP among other things, is to have a line consisting entirely of a single dot indicate the end of input. We can copy that convention.

So this would mean making one Gemini request per line, waiting for a response before submitting the next line, with each line as a query parameter "foo?[line]", and with a final request "foo?." to terminate input.

Implementation

Example

A simple example I hacked up to demonstrate how this could work.

(I wrote this using my general gemrepl system, because I already had it to hand. But it should be fairly (though not wholly) straightforward to implement it directly.)

Details

You're probably thinking: but what if I actually want to input a line consisting of a single dot? Well, we can copy SMTP's solution to this: if a line has a dot as the first character but has characters after that, the dot is deleted. So ".." becomes ".".

You may also be thinking: but we have a hard limit of 1024 characters for a request. What if I want to input a longer line? My answer: tough. In particular, this isn't suitable for binary uploads.

Further thoughts

So, what do you think? If we made this a common convention, or even a companion spec, it could make sense for clients to support it by having a command to upload a text file by making requests as above. I'm sure you can interesting imagine potential uses for this.

There's one clear downside to this whole approach, which perhaps is enough to make it a Really Bad Idea: even with TLS resumption, the overheads involved in setting up a fresh connection for each line would presumably be substantial. I'm not really sure how substantial, please let me know if you have an estimate. Having a full TLS handshake for each line would certainly be ridiculous.