Add gemini CGI page
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
Nobody told me it was awful, so I'm going to put it up. If any changes need to be made, they can be made.
This commit is contained in:
parent
23805c9224
commit
6dde906e15
|
@ -0,0 +1,82 @@
|
||||||
|
---
|
||||||
|
author: ~khuxkm
|
||||||
|
published: true
|
||||||
|
title: gemini cgi guide
|
||||||
|
description: a guide to using CGI on gemini
|
||||||
|
category:
|
||||||
|
- main
|
||||||
|
---
|
||||||
|
|
||||||
|
## where to put CGI scripts
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## what languages can be used to write CGI
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## how to write a gemini CGI script
|
||||||
|
|
||||||
|
these are the environment variables gemserv (our trusty gemini server) gives a
|
||||||
|
CGI program:
|
||||||
|
|
||||||
|
- `GATEWAY_INTERFACE` - always `CGI/1.1` in our case
|
||||||
|
- `GEMINI_URL` - the full URL used to request the page, including any query
|
||||||
|
strings
|
||||||
|
- `PATH_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-limiting
|
||||||
|
- `SCRIPT_NAME` - the path component of the URL that corresponds to the script
|
||||||
|
being called
|
||||||
|
- `SERVER_NAME` - the name of the server, in our case `tilde.team`
|
||||||
|
- `SERVER_PROTOCOL` - always `GEMINI` in our case
|
||||||
|
- `SERVER_SOFTWARE` - always `gemserv` in our case
|
||||||
|
- `LC_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
|
||||||
|
supplied
|
||||||
|
- `TLS_CLIENT_HASH` - the hash of the certificate, prepended with the hash type
|
||||||
|
- `REMOTE_USER` - the Common Name of the certificate
|
||||||
|
|
||||||
|
in 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.
|
Loading…
Reference in New Issue