jetforce icon indicating copy to clipboard operation
jetforce copied to clipboard

INDEX-FILE not running as CGI

Open maimere opened this issue 3 years ago • 3 comments

I have a CGI file running smooth if requested directly by the client, but, if set as the INDEX-FILE, its raw code is responded as text/gemini instead.

I guess it has to do with the appended part of the code, as filename being parsed different from index_file, it jumps straight to the INDEX-FILE if-clause.

filename = pathlib.Path(os.path.normpath(str(url_path)))

index_file = filesystem_path / self.index_file

https://github.com/michael-lazar/jetforce/blob/b4fd0919ebf7f75b348a9033bc64777f69c4ba7d/jetforce/app/static.py#L83

maimere avatar Nov 28 '20 08:11 maimere

Welcome,

Can you help me understand what you are trying to accomplish here? Jetforce has admittedly basic support for CGI using the /cgi-bin directory pattern that can result in ugly looking URLs. But you can always link the client directly to the CGI script that you wish to run, and the CGI script can generate a custom directory listing as the output. It sounds like you are trying to hack around these limitations to get cleaner URL paths?

michael-lazar avatar Nov 29 '20 02:11 michael-lazar

Hello. Sorry, I guess I rushed straight to my conclusions.

I am running a jetforce server with default cgi-dir (/cgi-bin) and index-file (/index.gmi).

I wrote a bash script and put it in /cgi-bin, and it runs perfectly, showing a proper gemini page when I run it through gemini://mydomain.com/cgi-bin/index.cgi.

Now, I wanted it to be my index-file, so it can show a custom welcoming message to each visitor. So, I set --index-file=cgi-bin/index.cgi. Unfortunately, when I access gemini://mydomain.com, the file is not rendered as CGI. From the very beginning, it is rendered as text/gemini, not evaluating any of the commands.

Even the first line,#!/bin/bash, is rendered as a "# heading", showing !/bin/bash. Other commands and variable assignments are treated as plain text.

Upon inspection of the code, I noticed this difference on Response of CGI files and the index file, hence my suspicious.

Please keep in touch for any further clarifications.

maimere avatar Nov 29 '20 03:11 maimere

Thanks for the explanation! That makes a lot more sense now. The index file is supposed to be only a filename and not a full directory path, so the way I would do this is:

  • --cgi-dir="." (allow everything in /var/gemini/ to be run as an executable)
  • --index-file=index.cgi

Of course, that doesn't work either because of the code as you pointed out above.

Thinking about how CGI would work properly with the root directory like this is kind of making my head spin. Say you get this working, and then the client requests gemini://example.com/myfile.txt. Does the server look for /var/gemini/myfile.txt and try to return it as a plain text file, or does it invoke your cgi script with "/myfile.txt" as the PATH_INFO environment variable. Returning static files from inside of the cgi directory is disabled by jetforce because it's a security risk (forget to set the executable bit in your script, and suddenly the hardcoded credentials in that file are exposed for anyone to download).

I'll leave this as an open issue because I don't see any reason not to do it, but I suspect it would take some significant refactoring.

Personally, what I would do is subclass the server and write my own custom route handler (jetforce is designed to be extended like this).

#!/usr/local/env python3
from jetforce import GeminiServer, StaticDirectoryApplication

app = StaticDirectoryApplication("/var/gemini")

@app.route("", strict_trailing_slash=False)
def custom_index_page(request):
    return app.run_cgi_script("/var/gemini/cgi-bin/index.cgi", request.environ)

if __name__ == "__main__":
    # Add the host, port, etc... arguments here that are normally set through the command line
    server = GeminiServer(app, host="...", hostname="...")
    server.run()

michael-lazar avatar Nov 29 '20 20:11 michael-lazar