#! /bin/ksh #Set your hostname after this variable fqdn=gopher.zcrayfish.soy oldfqdn=zcrayfish.dyndns.org cr=$(printf '\r') crlf=$(printf '\r\n') null=$(printf '') securityheaders () { printf '%s\15\12' "Strict-Transport-Security: max-age=31536000;" \ "Content-Security-Policy: default-src *.zcrayfish.soy; object-src *.zcrayfish.soy; base-uri *.zcrayfish.soy;" \ "X-Frame-Options: DENY" \ "X-XSS-Protection: 1; mode=block" \ "Referrer-Policy: no-referrer" } error301 () { printf '%s\15\12' "HTTP/1.0 301 Moved Permanently" \ "Location: https://$fqdn$obj" \ "Content-Type: text/plain; charset=utf-8" \ "Date: $date" \ "Server: gopher to http gateway at $fqdn" \ "Connection: close" \ "" \ "HTTP/1.0 301 Moved permanently" \ "http://$oldfqdn$obj" \ "Might be found at:" \ "https://$fqdn$obj" \ "" \ "gopher to http gateway at $fqdn" } error400 () { printf '%s\15\12' "HTTP/1.0 400 Bad Request" \ "Content-Type: text/plain; charset=utf-8" \ "Allow: GET" \ "Date: $date" \ "Server: gopher to http gateway at $fqdn" \ "Connection: close" \ "" \ "HTTP/1.0 400 Bad Request" \ "Request could not be understood - bad syntax" \ "" \ "gopher to http gateway at $fqdn" exit } error404 () { printf '%s\15\12' "HTTP/1.0 404 Not Found" \ "Content-Type: text/plain; charset=utf-8" \ "Date: $date" \ "Server: gopher to http gateway at $fqdn" \ "Connection: close" \ "" \ "HTTP/1.0 404 Not Found" \ "'$obj' doesn't exist!" \ "This resource cannot be located." \ "" \ "gopher to http gateway at $fqdn" } error501 () { printf '%s\15\12' "HTTP/1.0 501 Not Implemented" \ "Content-Type: text/plain; charset=utf-8" \ "Allow: GET" \ "Date: $date" \ "Server: gopher to http gateway at $fqdn" \ "Connection: close" \ "" \ "HTTP/1.0 501 Not Implemented" \ "This error has accoured for one of the following reasons:" \ " *This server only implements the GET method (e.g. your browser sent a HEAD or PUT)" \ " *This server, while acting as a gateway or proxy, does not support CSO queries." \ "" \ "gopher to http gateway at $fqdn" exit } # Gather request read -t 30 -r cmd obj proto badclient #Did we time out... If so just exit, HTTP 1.0 does not have a timeout code test "$?" != "0" && exit # See if request is a GET, if not, throw it away test "$cmd" != 'GET' && error501 && exit # Likewise ignore invalid gets too. test ! -z "$badclient" && error400 && exit # If it all looks good, find out what they want filename="$(printf "%s" "$obj" | sed -e 's/%2c/,/' -e 's/%20/ /')" # Gather headers, assume headers are done when we see CRLF or weird crap while /bin/true; do read -t 300 -r header headervalue port test "$header" = "$cr" && break test "$header" = "$crlf" && break test "$header" = "$null" && break header=$(echo "$header" | tr '[:upper:]' '[:lower:]') test "$header" = "host:" && host="$headervalue" #header="$(printf "$header" | sed -e 's/://')" #declare -a $header #printf -v "${header}" '%s' "${headervalue}" 2> /dev/null done #old FQDN? Redirect them! zdo=$(echo "$host" | grep -i zcrayfish.dyndns.org) test ! -z "$zdo" && error301 && exit date="$(date -u +'%a, %d %b %Y %H:%M:%S GMT')" #Step4 case "$filename" in /favicon.ico) error404 ;; /sitemap*|/robots.txt|/.well-known*) printf '%s\15\12' "HTTP/1.0 200 OK" \ "Date: $date" \ "Server: gopher to http gateway at $fqdn" \ "Connection: close" \ "" lynx -anonymous -source "gopher://$fqdn:70/0/$filename" ;; /2*) error501 ;; /7*) printf '%s\15\12' "HTTP/1.0 200 OK" \ "Content-Type: text/html; charset=utf-8" \ "Date: $date" \ "Server: gopher to http gateway at $fqdn" \ "Connection: close" \ "" \ '' \ '' \ "
" \ '

This is a searchable gopher index. Enter search keywords:

' ;; /debug*) printf '%s\15\12' "HTTP/1.0 200 OK" \ "Content-Type: text/plain" \ "" set ;; ###START OF DUMB / NON-INTELLIGENT GOPHER TYPES### /[04569IMPdghps]*) printf '%s\15\12' "HTTP/1.0 200 OK" case "$filename" in /0/stylesheet.css) printf '%s\15\12' "Content-Type: text/css" \ "X-Content-Type-Options: nosniff" ;; /0*) printf '%s\15\12' "Content-Type: text/plain" \ "X-Content-Type-Options: nosniff" ;; /4*) printf '%s\15\12' "Content-Type: application/mac-binhex40" \ "X-Content-Type-Options: nosniff" ;; /5*) printf '%s\15\12' "Content-Type: application/octet-stream" \ "X-Content-Type-Options: nosniff" ;; /6*) printf '%s\15\12' "Content-Type: message/rfc822" \ "X-Content-Type-Options: nosniff" ;; /9*) printf '%s\15\12' "Content-Type: application/octet-stream" \ "X-Content-Type-Options: nosniff" ;; /I*) printf '%s\15\12' "Content-Type: image/jpeg" \ "X-Content-Type-Options: nosniff" ;; /M*) printf '%s\15\12' "Content-Type: message/rfc822" \ "X-Content-Type-Options: nosniff" ;; /P*) printf '%s\15\12' "Content-Type: application/pdf" \ "X-Content-Type-Options: nosniff" ;; /d*) printf '%s\15\12' "Content-Type: application/pdf" "X-Content-Type-Options: nosniff" \ ;; /g*) printf '%s\15\12' "Content-Type: image/gif" \ "X-Content-Type-Options: nosniff" ;; /h*) printf '%s\15\12' "Content-Type: text/html" \ "X-Content-Type-Options: nosniff" ;; /p*) printf '%s\15\12' "Content-Type: image/png" \ "X-Content-Type-Options: nosniff" ;; /s*) printf '%s\15\12' "Content-Type: application/octet-stream" ;; esac securityheaders printf '%s\15\12' "Date: $date" \ "Server: gopher to http gateway at $fqdn" \ "Connection: close" \ "" lynx -anonymous -dump -source "gopher://$fqdn:70$filename" ;; ###END OF DUMB / NON-INTELLIGENT GOPHER TYPES### *) printf '%s\15\12' 'HTTP/1.0 200 OK' \ 'Content-Type: text/html; charset=utf-8' \ "Date: $date" \ "Server: gopher to http gateway at $fqdn" securityheaders printf '%s\15\12' 'Connection: close' \ 'X-Content-Type-Options: nosniff' \ '' \ '' # '' lynx -anonymous -dump -source "gopher://$fqdn:70$filename" | \ tidy -in -w 0 -cn --doctype omit --show-errors 0 --show-warnings 0 --quiet 1 --uppercase-tags 1 --uppercase-attributes 1 --char-encoding utf8 | \ # sed -e 's//a ' # sed -e 's/