#! /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" \ "" \ '' \ '