Inputs and client certs
-----------------------

With the link syntax finally established, the next biggest priority in
my mind is to stabilise the status codes, because this is currently
the only other significant place where the existing implementations
vary and I think it's important to unify the current tiny Geminiverse
ASAP.  I've already written something[1] about status codes, and I
have much more developed thoughts on that to share soon.  But to put
that discussion into full context, I wanted to quickly present a few
other ideas.  Both of these will be fleshed out more fully later.

The first is the idea of queries, or user inputs, or whatever we want
to call them.  Essentially, an equivalent of gopher's item type 7.
When you use a gopher client to follow a link with item type 7, the
client will prompt you for up to 256 characters of input.  It will
then connect to the relevant server, and instead of sending just the
path followed by a CRLF as per a standard Gopher request, it will send
the path, then a tab, then your input followed by a CRLF.  This is how
serarch engines like Veronica accept search terms, and the same
functionality is also sometimes used for things like guestbooks.  It's
nice functionality to have and I want something similar in Gemini.

There are basically two questions here.  The short and boring and
probably pretty easy one is how do we add user input to the request
format?  Right now I see no problem with simply copying Gopher's tab
separation approach, but let me know if you think this has severe
shortcomings.  More substantially, is given that we do not have item
types, how should a Geminimap convey that a particular link is to a
resource which accepts an input?

The best idea I've come up with so far on this front is to dedicate a
status code to this issue.  The status code would indicate that the
server is requesting user input, and the line of text that comes after
the code would be a prompt to present the user.  The client should
present the prompt, get the user's response, then make a new request
to the same resource with the response included.  This does mean that
"doing a Gemini search" becomes a two-request action, which is a
shame, but since the user has to read the prompt and type their input
in between the two queries, the time wasted on setting up / tearing
down the connections should still be a small proportion of the total
time involved (and I'm hoping that one day TLS session resumption is
well-supported enough that connections become cheaper than they are
today).  The bonus of this approach is that the server gets to specify
a custom prompt for each resource which accepts input, which is not
possible in gopher.  This might seem like a small thing, but I'll come
back to it later and reveal its true power.  But first...

The other idea is authentication using client TLS certificates.  This
idea is actually already implemented in the Conman server, and
interest has already been expressed in possibly adding it to Germinal.
I endorse this idea very strongly and I plan for it to be the only
implementation of authentication in Gemini, i.e. there will be no
password-based authentication comparable to HTTP's.  Why?

Firstly, because we're aiming for maximum power-to-weight ratio.  The
weight of TLS is already in the protocol, so we should try to extract
maximum power from it.  Anything which can be achieved using TLS
should be achieved using it, rather than adding more weight with extra
parts of the protocol.

Secondly, because using client certificates is slightly more
complicated than using passwords, which means people won't deploy
authentication lightly.  This might seem like an odd consideration.
It's motivated by the thought-provoking article "Avoiding the gravity
hole of webbiness in gopher"[2] by enkiv2, written in response to my
early ponderings which eventually spawned the Gemini project.  You
should definitely read this article if you're interested in this whole
discussion - the final four paragraphs are the most important, IMHO.
enkiv2 opines that one of the immediate negative consequence of the
introduction of HTTPS was the proliferation of "registration gating"
on the web.  This honestly isn't something I'd thought about before
but I definitely understand the sentiment.  A Geminispace where the
majority of content is totally publicly accessible, like gopherspace,
sounds like a good thing.  Making private Geminispace possible but not
straightforward discourages forcing people to authenticate themselves
for no good reason, while still catering to people who want to do
things like serve content only for their own use.

Finally, because client certs can also be used to function as a
superior version of cookies!  By remembering the fingerprint of a
client certificate, a server can recognise that a given connection is
coming from the same client as a previous one.  That might sound like
a very bad thing, just like cookies are a very bad thing, but client
certs differ from cookies in very important ways.  They aren't given
to the client by the server like cookies are, but the client has to
generate them itself before even connecting to the server - they are
fundamentally opt-in.  Even better, once a client deletes a key/cert
pair, it is gone for good - the server remembers only the fingerprint,
which is insufficient to recreate the pair.  Client certs allow
clients to voluntarily and very visibly (generating a new key/cert
pair takes some time and will briefly spike your CPU usage) enter into
a temporary session of state-persistence with a given server, which
the client is guaranteed to be able to permanently end whenever it
wants to, whether the server likes it or not.  This functionality is
somewhat similar to the Session-ID header idea that gcupc proposed in
their excellent response to enkiv2's article[3], which talks about a
possible "lynx web" - yet more required reading.

Now, back to the "true power" of the input prompt status code: within
one of these "client-certificate sessions", a server can respond to
successive requests from the same client for a resource which wants a
user input with different prompts each time.  This can be used to do
things like simulate a HTML form with multiple text fields, by asking
for the fields one at a time.  Or it can be used to play very simple
text-based adventure games!  It's basically a minimalist remote REPL
interface and should allow some interesting server-side applications
to be built on Gemini.  I'm fairly excited about this - not because I
have lots of such applications that I really want to make, but rather
because it's a very nice emergent property of the protocol.  This sort
of application was not in my mind whatsoever when I started designing
Gemini, it just turned out to be possible using a combination of two
features which were included for entirely unrelated reasons.  Stuff
like that is neat!

My next post will give my latest thoughts on the status code system,
and my current ideas are largely based around making these two
features work.  That's why I wanted to provide some context by
describing them first.  Feedback on these two ideas, even before the
status code post comes up, are of course welcome.

[1] gopher://zaibatsu.circumlunar.space:70/0/~solderpunk/gemini/status-codes.txt
[2] gopher://fuckup.solutions:70/1/enkiv2/avoiding-the-gravity-hole-of-webbiness-in-gopher
[3] https://jfm.carcosa.net/blog/computing/gopher-and-the-lynx-web/