💾 Archived View for bbs.geminispace.org › s › Gemini › 22856 captured on 2024-12-17 at 15:01:21. Gemini links have been rewritten to link to archived content

View Raw

More Information

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

Server best practices for routing and relative links

I'm writing a gemini server and ran into some gotchas when it comes to relative linking from within gemtext.

The server will route gemini requests to paths on the filesystem. i.e. a url "index.gmi" would route to a file named "index.gmi"

As a convenience, the server will also resolve requests that correspond to a directory on the filesystem iff the directory contains a file named "index.gmi"

Let's say there's a file at the subpath ~subspace/index.gmi on the filesystem. Now, the server will allow all of the following requests to the same content:

gemini://server/~subspace

gemini://server/~subspace/

gemini://server/~subspace/index.gmi

You'd think that since the content is identical for each of these requests that the behaviour would be the same.

But this is not the case for relative links!

Consider the following document that might be served. In the document, you can see relative links and their resolved URLs based on the client's current address in the URL bar.


# Try to link to ~subspace/bookshelf.gmi

Each heading contains the "source" document
from which the relative URI is resolved.

The link text for each link holds the resolved
URL from the source document.

The intended target url in all cases is
~subspace/bookshelf.gmi

## ~subspace

=> bookshelf.gmi bookshelf.gmi
=> ./bookshelf.gmi bookshelf.gmi
=> ~subspace/bookshelf.gmi ~subspace/bookshelf.gmi
=> ./~subspace/bookshelf.gmi ~subspace/bookshelf.gmi

## ~subspace/

=> bookshelf.gmi ~subspace/bookshelf.gmi
=> ./bookshelf.gmi ~subspace/bookshelf.gmi
=> ~subspace/bookshelf.gmi ~subspace/bookshelf.gmi
=> ./~subspace/bookshelf.gmi ~subspace/~subspace/bookshelf.gmi

## ~subspace/index.gmi

=> bookshelf.gmi ~subspace/bookshelf.gmi
=> ./bookshelf.gmi ~subspace/bookshelf.gmi
=> ~subspace/bookshelf.gmi ~subspace/bookshelf.gmi
=> ./~subspace/bookshelf.gmi ~subspace/~subspace/bookshelf.gmi

Given how the above examples resolve relative URIs, my current thinking is that my server should exhibit the following behaviour:

If there exists a file `~subspace/index.gmi`, and:

- A request arrives for `~subspace`, then redirect to `~subspace/`

- A request arrives for `~subspace/index.gmi`, then redirect to `~subspace/`

- A request arrives for `~subspace/`, then serve the content

What do you think the ideal behaviour of the gemini server is in this scenario?

Do you think a redirect to a single user-facing URL is a good approach to solving this content-editing ambiguity?

If a redirect is a good approach, would it be better to redirect to `~subspace/` or to `~subspace/index.gmi`?

Note that I'm using Lagrange as my client, so I'm not sure if your gemini client would resolve relative links differently.

Posted in: s/Gemini

🏕️ bjnaved

Dec 16 · 1 day ago

11 Comments ↓

🕹️ skyjake [mod...] · Dec 16 at 16:51:

A request arrives for `~subspace`, then redirect to `~subspace/`

I think this is the only actual redirect you should have. Generally speaking, it makes things a lot simpler for everyone involved if URLs referring to directories end in a slash.

Lagrange follows the standard rules for resolving relative URL paths.

When it comes to index.gmi, that is merely a best practice kind of thing. Depending on the server, the directory index could be something else, maybe not even a page at all, so the client cannot make any assumptions regarding "/path/" and "/path/index.gmi" being equivalent.

This means it's entirely up to your server whether it links to index.gmi files or directories. I would advise avoiding redirections that are not really needed because clients behind a slow connection will be having an even worse experience.

🏕️ bjnaved [OP] · 23 hours ago:

the directory index could be something else, maybe not even a page at all

That's a great point that I hadn't considered. Thanks for the insight! I was only thinking about the redirect-to-index behaviour, not file listings, etc. I think I'll do as you suggest and only perform the append-slash redirect for directory paths.

🎵 alice-sur-le-nuage · 22 hours ago:

I don't think anything is gained by having a URL pointing to a directory return the content of <directory name>/index.gmi . If you want the content of index.gmi, just add that to your link. I know it's common practice on the web - but only because it looks neater, not because it's useful.

🚀 stack · 21 hours ago:

There is a great reason -- you can hide the contents of your directories by dropping in a blank index.gmi .

As well as providing access to some files but not allowing the user to snoop.

Also, that is the expected behavior.

🐐 satch · 20 hours ago:

@alice-sur-le-nuage it looks neater, and that matters! Aesthetics are important. Sometimes leaving index.gmi in the link is the preferred aesthetic, other times not.

Often, it's nice to make all urls on the site point to directories, so every page ends up being called index.gmi.

I do wish more servers supported omitting the file name extension from html/gmi files. I think they should be the default types for their associated protocols, not plain text. While it's useful in some contexts, you don't *need* the extension, that's what MIME type is for - and anyway, you can serve any kind of file with any extension you want, so it's not good to assume you know the file type of a resource when all you have is an filename extension.

🎵 alice-sur-le-nuage · 12 hours ago:

@stack Only if your server shows a list of files when accessing a directory, which I think is in itself a bad feature. And when that option is enabled by default as you suggest, then it's a security risk.

🎵 alice-sur-le-nuage · 12 hours ago:

@satch I couldn't agree less regarding file extensions ! As a human I need to be able to look at a file name (and at a uri) and go "OK, that's gemtext" or "OK that's a picture". By removing the file extensions from paths, you're removing that capacity from me. I can't tell what type of content is hosted at a URL unless I view it.

🎵 alice-sur-le-nuage · 11 hours ago:

The fact a server can send back any mimetype regardless of what the requested URL was is a weakness of the protocol, not a feature. If I ask for a Jpeg, I should get a Jpeg back.

🐐 satch · 10 hours ago:

As a human I need to be able to look at a file name (and at a uri) and go "OK, that's gemtext" or "OK that's a picture".

I totally get wanting to do that, and I could even be persuaded that the fact a server can send back any MIME type is a weakness of the protocol.

But given the way things are, all I'm saying is sometimes the filename extension is convenient or aesthetically nice, other times it's not. Having the option is a good thing.

If I was designing a protocol which like nex used filename extensions but gemtext as the default content type, I would specify that without any filename extension, getext should be assumed. That way people get more aesthetic choice.

🎵 alice-sur-le-nuage · 9 hours ago:

@satch fair enough ! As it happens I'm also implementing my own gemini server at the moment (only out of interest, there's plenty already that would fit my needs), it's interesting to see we're making different design choices (which justifies the fact we need more than one Gemini server so people can choose what they like most).

🚀 stack · 3 hours ago:

@alice-sur-le-nuage, agreed, but every gemini server I've used (on tildes) dumps directories as links. It makes it very simple to get started, and a simple 'touch index.gmi' disables this behavior when required... I believe this is a defacto expected behavior.

I don't think it's a security threat by itself unless you actively insert the links or files you don't want to see into the directory