#! /bin/ksh
#Set your hostname after this variable
fqdn=gopher.zcrayfish.soy

cr=$(printf '\r')
crlf=$(printf '\r\n')
null=$(printf '')

error400 () {
   printf "%s\15\12" "HTTP/1.0 400 Bad Request" \
       "Content-Type: text/plain; charset=us-ascii" \
       "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=us-ascii" \
       "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=us-ascii" \
       "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
 test "$header" = "$cr" && break
 test "$header" = "$crlf" && break
 test "$header" = "$null" && break
 header="$(printf "$header" | sed -e 's/://')"
 eval $header=$headervalue
 #[ "$header" == $'\r ] && break;
done


#log me up?

echo $cmd $obj $proto $badclient >> /tmp/www3.log
echo $header $headervalue >> /tmp/www3.log

#Get the HTTP command, filename, protocol version . . .
while read -r cmd obj proto badclient
do
   # We put the date in the loop in case the client waits before sending another request
   date="$(date -u +'%a, %d %b %Y %H:%M:%S GMT')"
   case "$cmd" in
       GET)

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


           #Step4
           case "$filename" in
               /favicon.ico)
                   error404
                   ;;
               /sitemap*|/robots.txt)
                   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*httpsearch*)
                   printf "%s\15\12" "HTTP/1.0 200 OK" \
                       "Content-Type: text/html; level=1" \
                       "Date: $date" \
                       "Server: gopher to http gateway at $fqdn" \
                       "Connection: close" \
                       "" \
                       '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 1//EN">'
                   searchytwothousand="$(printf "%s" "$filename" | sed 's/httpsearch=//g')"
                   lynx -anonymous -dump -source "gopher://$fqdn:70$searchytwothousand" | sed 's/<A HREF="\/\/$fqdn:70/<A HREF="http:\/\/$fqdn:80/g' | sed 's/<A HREF="\/\//<A HREF="gopher:\/\//g'
                   exit
                   ;;
               /7*)
                   printf "%s\15\12" "HTTP/1.0 200 OK" \
                       "Content-Type: text/html; charset=us-ascii" \
                       "Date: $date" \
                       "Server: gopher to http gateway at $fqdn" \
                       "Connection: close" \
                       "" \
                       '<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">' \
                       '<title></title>' \
                       "<form action='$fqdn$filename' method='get'>" \
                       '<p>This is a searchable gopher index. Enter search keywords:<input type="text" name="httpsearch"></p></form>'
                   ;;
               /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*)
                           printf "%s\15\12" "Content-Type: text/plain"
                           ;;
                       /4*)
                           printf "%s\15\12" "Content-Type: application/mac-binhex40"
                           ;;
                       /5*)
                           printf "%s\15\12" "Content-Type: application/octet-stream"
                           ;;
                       /6*)
                           printf "%s\15\12" "Content-Type: message/rfc822"
                           ;;
                       /9*)
                           printf "%s\15\12" "Content-Type: application/octet-stream"
                           ;;
                       /I*)
                           printf "%s\15\12" "Content-Type: image/jpeg"
                           ;;
                       /M*)
                           printf "%s\15\12" "Content-Type: message/rfc822"
                           ;;
                       /P*)
                           printf "%s\15\12" "Content-Type: application/pdf"
                           ;;
                       /d*)
                           printf "%s\15\12" "Content-Type: application/pdf"
                           ;;
                       /g*)
                           printf "%s\15\12" "Content-Type: image/gif"
                           ;;
                       /h*)
                           printf "%s\15\12" "Content-Type: text/html"
                           ;;
                       /p*)
                           printf "%s\15\12" "Content-Type: image/png"
                           ;;
                       /s*)
                           printf "%s\15\12" "Content-Type: application/octet-stream"
                           ;;
                   esac
                   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; level=1' \
                       "Date: $date" \
                       "Server: gopher to http gateway at $fqdn" \
                       'Connection: close' \
                       '' \
                       '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 1//EN">'
                   lynx -anonymous -dump -source "gopher://$fqdn:70$filename" | \
                       tidy -in -w 0 -cn --doctype omit --show-errors 0 --show-warnings 0 --tidy-mark 0 --quiet 1 --uppercase-tags 1 --uppercase-attributes 1| \
                       sed -e 's/<A HREF="\/\/'$fqdn':70/<A HREF="http:\/\/'$fqdn'/g' -e 's/<A HREF="\/\//<A HREF="gopher:\/\//g'

                   ;;
           esac
           ;;
       HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH)
           error501
           ;;
       "$cr" | "$crlf" | "$null" )
           exit;
           ;;
   esac
done
exit