omar-polo / gmid

a Gemini server
https://gmid.omarpolo.com
ISC License
97 stars 8 forks source link

Support for other protocols (gopher, spartan, ...) #33

Open omar-polo opened 3 days ago

omar-polo commented 3 days ago

In the past I've discarded the feature requests to add support for other protocols, since I saw gmid only as a gemini server. The idea was that if there was the need for a gmid-style server for spartan or gopher, a new server could be written (eventually borrowing from gmid.)

However this doesn't seem much viable practically speaking, and with also #19 there is some room to discuss adding other protocols to gmid. I'm fearing in part that we'd become a kitchen sink, but there is also some value in speaking a few adjacent protocols: the code won't explode in size and the service is nice.

This feature has to be planned carefully however. The protocol(s) implementation may be trivial, but the configuration changes have to be planned.

For example, gopher doesn't have (AFAIK) the notion of virtual hosts, so the server block makes little sense. On the other hand, stuff like the TLS settings makes sense only for gemini. On the third (?) hand, some options will need to be handled per-protocol (index comes to mind).

Titan (see #19) could also be "plugged" this way.

One way to handle this could be by introducing a protocol block. I still fear that we'd have to treat each protocol as it were a tiny snowflake in the configuration syntax anyway. We shouldn't be limited by the backward compatibility: at least initially let's try to design something that makes sense; we'll deal with the backward compat only when we have a nice design.

The milestone is temporary 2.2 (don't want to delay 2.1) but it could also be 3.0. Titan may be moved from 2.1 to this milestone.

Thoughts?

omar-polo commented 3 days ago

Another thing I forgot, should we also consider having multiple chroot? e.g. /var/gemini for the gemini content, /var/gopher for gopher and so on...?

ThomasAdam commented 3 days ago

Hi,

I agree with this overall sentiment. It's important to remember that gmid right now only understands gemini.

If we were to introduce other protocols -- the most practical example right now is gopher -- this has very different requirements compared to gemini, compared to $SOME_OTHER_PROTOCOL. As a result, I feel we need to protect those things from a server-perspective which are also going to be common to whichever protocol.

For example, you could say (I'm surmising on the syntax here -- I'm not wanting to bikeshed this at all just yet. This is for illustrative-purposes only):

server {
    protocol "gopher"
    domain "gopher.example.org"
    port 71
    root "/var/something/gopher"
    index "gophermap"
{

In this example, there is a server block, where the protocol is gopher, and the rest follows.

Similarly, one could imagine:

server {
    protocol "gemini"
    domain "gemini.example.org"
}

I'm refraining from adding any "metadata" to the server name, so as to infer everything it needs.

Note that, in this way, with a server block defined, we could infer missing attiributes. For example, if there were a server block without a port attribute, but the protocol were gemini, we should infer port of 1965.

I don't think this assumption is unreasonable. That's how a lot of configs work.

With regards to becoming a kitchen sink, I doubt that. At the very least, gemini, and gopher are sufficiently close enough that this analogy makes sense.

Were we to introduce another type, it's possible we could add a proxy variable with a hostname:port requirement to infer serving up "unknown" content.

But the key thing here is that gmid has enough latitude right now to support different protocols, and that's what I intend to do.

Note that there's a fair amount of refactoring work I can do as an almost prerequisite to any thing else proposed here. That's precisely what I intend to do.

omar-polo commented 2 days ago

Note that, in this way, with a server block defined, we could infer missing attiributes. For example, if there were a server block without a port attribute, but the protocol were gemini, we should infer port of 1965.

I don't think this assumption is unreasonable. That's how a lot of configs work.

I think this is very reasonable.

With regards to becoming a kitchen sink, I doubt that. At the very least, gemini, and gopher are sufficiently close enough that this analogy makes sense.

Yes, I agree, otherwise I wouldn't have created this issue to discuss :)

That was the past me worrying, but I've changed my mind and pragmatically speaking I believe it's fine to make this move. I just need to slightly change the topic for gmid from "gemini server" to "smol internet server" or something like this.

I'm not wanting to bikeshed this at all just yet. This is for illustrative-purposes only

instead I'd like to bikeshed this a bit! :P

Or, phrasing it better, to brainstorm a possible grammar. I was thinking of something around these lines:

protocol gopher {
    listen on localhost # implicit "port 71" for gopher!
    root /some/path
    chroot "/var/gopher" # different chroot path for gopher?
    prefork 2 # different prefork for gopher?
    auto index off # maybe even different defaults per-protocol?
}

protocol gemini {
    chroot "/var/gemini"
    prefork 5

    server "example.org" {
        listen on localhost # implicit "port 1965"
        cert "/path/to/cert"
        key "/path/to/key"
        root "/some/other/path"
    }
}