you can put CGI scripts anywhere. as long as you make the file executable and have it output the correct format for gemini. the server calls a new instance of the program for every request it has to handle, meaning that data isn't saved between runs unless you manually save the data to a file or database and load the data on the next run.
any language that can read environment variables can be used for CGI. even shell scripting can be used for CGI, given you provide the correct shebang.
these are the environment variables gemserv (our trusty gemini server) gives a CGI program:
GATEWAY_INTERFACE
- always CGI/1.1
in our caseGEMINI_URL
- the full URL used to request the page, including any query
stringsPATH_INFO
- any extra path after the script itself (for instance,
gemini://tilde.team/~khuxkm/test.cgi/test/one
gives a PATH_INFO
of
/test/one
)REMOTE_ADDR
, REMOTE_HOST
, REMOTE_PORT
- the addr/host/port of the
connecting client, the former two useful for rate-limitingSCRIPT_NAME
- the path component of the URL that corresponds to the script
being calledSERVER_NAME
- the name of the server, in our case tilde.team
SERVER_PROTOCOL
- always GEMINI
in our caseSERVER_SOFTWARE
- always gemserv
in our caseLC_CTYPE
- always C.UTF-8
in our case (allows for UTF-8 output)also, if the user supplies a cert:
AUTH_TYPE
- always Certificate
if present; if not present, no cert is
suppliedTLS_CLIENT_HASH
- the hash of the certificate, prepended with the hash typeREMOTE_USER
- the Common Name of the certificatein order to write a CGI program, simply use these environment variables to figure out what you want to do and then do it. for a simple hello world:
#!/bin/sh
printf '20 text/gemini\r\n'
printf 'Hello world from CGI!\r\n'
do note that the first line MUST use \r\n as a terminator. after that, if you're serving gemtext, you can use whatever LF/CRLF you want for line endings as long as you stay consistent.
for a more complex hello world that asks for input, here's a python script that asks for your name and says hello to you:
#!/usr/bin/python3
from urllib.parse import unquote
from os import environ
from sys import exit
if "QUERY_STRING" not in environ:
print("10 Please enter your name",end="\r\n")
exit()
name = unquote(environ["QUERY_STRING"])
print("20 text/gemini",end="\r\n")
print(f"Hello {name}!")
remember, anything that can read environment variables and write to stdout can be used to make CGI, as long as the server can figure out how to execute it.
##how to set a CGI script as executable
The CGI script must be marked as executable in order to actually run.
To make the script executable, run this command:
chmod +x SCRIPT_NAME.cgi