💾 Archived View for gemlog.blue › users › ttocsneb › 1614025696.gmi captured on 2022-01-08 at 15:09:02. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-12-04)
-=-=-=-=-=-=-
As I have been working on my server implementation for gemini, I started thinking about what is too much effort. I have been able to embed a python instance into the main process of the server which barely works. It can send requests, but can't import libraries without getting some esoteric error.
Sure, I could use swig to help me manage the python instance, but what about other WSGI servers? Maybe I should just fork into a main program that communicates using pipes. That way I could have one main server, and several virtual hosts managed by that server, and they don't need any special plugin to work. This of course is the idea of a cgi-bin, where each file is executed on request from the client.
But that causes problems when you want to have pages that can interact with each other, or even have virtual paths that the client can access. From the start, I was thinking of using a plugin system that will manage different requests. I still like that idea, but I feel that there is a simpler solution.
The protocol that I have written out is in no way finished or meant to be taken seriously. At the moment, it is only an idea of what could be.
Updated 21/2/23
Differing from a cgi where each request will create a new process that runs the requested file, a WSGI will be a single long lived process that acts like a standalone server, but without the need of dealing with tls connections.
Because the main server is listening for all incoming connections, the child servers have to be able to communicate with the parent as a proxy to the client. Similarly to CGIs, stdout will be directed towards the client. The incoming requests will be forwarded to stdin.
The major drawback of this method is that logging cannot be done through stdout, only stderr or file logging. I don't see this as a big problem though.
When the child is ready to process requests, it should send a message to stdout. This message should be one of two possible:
fail\n ready\n
This message should be sent only once per life cycle, and as soon as possible. The server will wait until the message is received. Once the child server is running, the parent will never expect this message again during the child's lifetime.
If for whatever reason the server cannot start, the message 'fail' should be sent to stdout after which the child will exit.
Once the server is ready, it should send the message 'ready'.
Because of the way virtual hosting inherently works, the path the client is requesting may not be the same as the path the child server receives. Because of this, the protocol for sending a request to the child will be different to that of a standard gemini request:
<SCHEMA>://<HOST>[:<PORT>]<FULL_PATH>[?<QUERY>]\n <PREFIX_PATH>\n <SERVER_PATH>\n gemini://example.com/mysite/foo/bar/?my_query /mysite\n /foo/bar/\n
When generating links relative to the root directory of the server "/", the PREFIX_PATH should always be prepended to the path.
/foo/baz/ -> /mysite/foo/baz/
The response starts out like a normal gemini response header, but will also specify the length of the body. The length is required because the pipe lasts the entirety of the server's lifecycle.
20 text/gemini\n 12\n Hello World!