Writing a CGI script for Molly Brown and why <CR><LF> is so important

2021-02-24

This Gemini capsule is currently powered by Agate on the default port of 1965. I am also running Molly Brown, a Gemini server, on port 7070. Molly Brown can also do server side scripts. The random quote link on the index page is powered by a CGI script.

Here is a portion of the script:

#!/bin/sh
printf "20 text/gemini\r\n"

printf "$(/pathto/fortune /pathtomollybrowncgiscripts/cgi-bin/churchfathers)" | fold -s

I spent hours trying to take this script that is on my Gopher server and switching it to the server running Molly Brown. I am embarrassed to admit. Here is what I missed and why it is important.

Here is the Gemini Specification that is important:

3.1 Response headers

Gemini response headers look like this:

<STATUS><SPACE><META><CR><LF>

<STATUS> is a two-digit numeric status code, as described below in 3.2 and in Appendix 1.

<SPACE> is a single space character, i.e. the byte 0x20.

<META> is a UTF-8 encoded string of maximum length 1024 bytes, whose meaning is <STATUS> dependent.

<STATUS> and <META> are separated by a single space character.

If <STATUS> does not belong to the "SUCCESS" range of codes, then the server MUST close the connection after sending the header and MUST NOT send a response body.

If a server sends a <STATUS> which is not a two-digit number or a <META> which exceeds 1024 bytes in length, the client SHOULD close the connection and disregard the response header, informing the user of an error.

Taken from gemini://gemini.circumlunar.space/docs/specification.gmi

This is how I originally wrote my code:

#!/bin/sh
printf "20 text/gemini"

printf "$(/pathto/fortune /pathtomollybrowncgiscripts/cgi-bin/churchfathers)" | fold -s

I added the response header but did not terminate that line correctly. The script ran correctly in bash. It ran on the Gemini server but never displayed anything but returned a status code of 20. By not terminating the response header with a carriage return and a line feed the script did not display the rest of the page in Gemini. Once I added the carriage return and the line feed the script ran as intended.

#!/bin/sh
printf "20 text/gemini\r\n"

printf "$(/pathto/fortune /pathtomollybrowncgiscripts/cgi-bin/churchfathers)" | fold -s

My mistake shows the importance of paying attention to details.

..