1. 22

  2. 9

    If anyone has questions about the protocol, I can answer them. While I did not create the protocol, I did implement the first Gemini server (and surprised the protocol creator by beating him to the punch so to speak). Most of what I’ve implemented was there to push the boundaries of what could be done with the protocol and to hash out details that were under-specified/not specified.

    1. 4

      Gemini response headers look like this:


      <STATUS> is a two-digit numeric status code, as described below in 1.3.2 and in Appendix 1.

      <whitespace> is any non-zero number of consecutive spaces or tabs.

      So I could respond to a client request by sending a status, then dribbling out space chars forever if I felt like being a jerk?

      1. 4

        Yes. In fact, that does sound like a decent client torture test to add (as maintainer of said torture test). In fact, you could just send the output a byte at a time with a long time delay between each byte (you can do this with any TCP-based protocol in fact). A server could also just accept the request and not say anything at all. There are plenty of ways to mess with the client (and conversely, the server as well).

        1. 2

          I’m not sure why it wants to permit runs of whitespace at all, given that the rest of the protocol is meant to be minimal.

          1. 4

            I’d have to go through a bunch of discussions, but I think the early spec had a tab between the status and the meta information, but due to some people hating on tabs, it was changed to a space, and then finally space or a tab and to be generous, any number of such whitespace characters.

            1. 7

              Seems like it’d be simple and uncontroversial to switch it to a single whitespace character. Make clients simpler, remove a potential torture test.

      2. 3

        Now that I’ve read the spec and FAQ, I am intrigued, as I rather like the “make it as simple as possible, and no simpler” design. A few decisions seem to verge close to the edge of “no simpler” though, and I’d like to know more about them.

        • Mainly, closing the connection after each exchange and not including a content-length in the server response header seem to combine to make life more difficult and slower than necessary. You don’t know how much memory to allocate to store the server’s response, you can’t tell the difference between malformed data or just something going wrong upstream, and you have to go through the whole TLS negotiation each time.
        • Ever considered a variant using QUIC instead of TCP? It actually seems like a nice solution to the previous problems, since lightweight streams make it easier to say “your framing protocol is a single connection”. Plus, its assumption of TLS everywhere makes it feel like it should go well together QUIC.
        1. 5

          The content-length was brought up on the mailing list a few times (here’s a good thread about it) but the overriding principle of Gemini has been simplicity of implementation—the protocol creator has mentioned several times it should be possible to implement the protocol in about 100 lines of code. So keep that in mind.

          For your second question, I wouldn’t even consider QUIC until there’s an RFC (and even then, I wouldn’t necessarily like it [1]) but I’m not the protocol creator. But I suspect he wouldn’t consider it either. There was a push to use NaCL over TLS that was ultimately rejected due to implementation issues.

          [1] It feels too much like Google is trying to ram it down our throats, like it did for HTTP/2. Imagine if Microsoft was pushing this—I suspect there’d be more of an uproar, but I’ll stop here before I rant more.

          1. 1

            Thanks for the info! I would kinda argue that omitting a content length makes actually using the thing more complicated rather than simpler, since it just shoves more problems into the “well, just give up” category. But I’ll read the thread you linked and get the whole story.

            As for QUIC, depends what you want I suppose. I’m fine with Google ramming it down our throats if it’s good technology that solves common problems, which in my experience it is. It’s definitely a big honkin’ complex system though, which is still evolving. Was just curious if it’d been considered.

            1. 4

              There is often a tension between which side of the connection should be made easy to implement - the client or the server. If you make it too difficult, people will give up and ignore your protocol. A great example of this is IMAP. IMAP works, but implementing a client is incredibly hard. So much so, that many mobile clients just implement proprietary json-over-http protocols to talk to a handful of mail providers and nothing more. (JMAP - RFC 8620 - tries to fix that by explicitly pushing complexity away from the client.)

              I have no idea what this implies for Gemini. :)

              Providing a Content-Length header means the server has to know the length - generally easy with static content, but much harder with dynamic content (I saw there was discussion about CGI on the mailing list). Not making the header always present forces extra complexity in the client.

        2. 1

          The CR+LF hurts.

          Let’s get rid of obsolete line terminations, where we can. A new protocol is a place where we can.

          UTF-8 requirement + CRLF is a painfully dissonant chord.