#!/usr/local/bin/tops -s /usr/local/tops/sys -u /opt/mytops/usr/
{  File tops_http
   February 2005

   Copyright (C) 2005-2014  Dale R. Williamson

   Running the program as a daemon, this script listens on port 80 for 
   an HTTP request, forwards it to Apache web server running with these
   directives (directives are made in file /etc/apache/httpd.conf):
      BindAddress 127.0.0.1
      Port 9880
   and then sends the HTTP response to the requestor.

   Mar 18 13:36:22 PDT 2011.  If flag APACHE is equal to no, daemon 
   tops_wbsvr is running instead.
}
\-----------------------------------------------------------------------

   CATMSG push no catmsg

   no "APACHE" book

\  Logging.

\  A log file is defined for SYSOUT using word set_sysout:
   "HOME" env "tops_http.log" catpath "LOG" book LOG set_sysout

\  Display some starting lines in the log file:
   "-" 72 cats nl dot nl
   "PID " getpid intstr + spaced date + dot nl

\  Make sure a web server is listening:
   APACHE
   IF 9880
   ELSE \ running tops_wbsvr:
      "WBSVRport" exists? \ defined in mytops/usr/uboot.v
      IF WBSVRport ELSE 9880 THEN
   THEN "WPORT" book
   WPORT port_listening not
   IF " tops_http: port" . WPORT .i " not listening; halting" . nl HALT
   THEN

\-----------------------------------------------------------------------

\  Words.

   "tops_http.v" filefound IF (qFile) source THEN
 
\  The following line defines this server as an HTTP server:
   0 "SERVE_F" "TYPE" bank \ HTTP type

\  Bank the ptr to the word that services HTTP requests into word 
\  SERVE_F, the word the program runs on every request to SERVER:
   "REQUESTrun" exists? 
   IF "REQUESTrun" 
   ELSE "HTTPput" \ HTTPput is the default to service HTTP requests
   THEN ptr (n)
   (n) "SERVE_F" "SERVICE" bank \ ptr to word that services requests

\  In word HTTPput, define the HTTP provider and port (set these
\  even if REQUESTrun is used for SERVE_F.SERVICE):
   ontheweb (f)
   IF "127.0.0.1" "HTTPput" "PROVIDER" bank
      WPORT "HTTPput" "PORT" bank

   ELSE host "diego" =
        host "plunger" = or
        host "riggo" = or
      IF \ tops_wbsvr on 127.0.0.1:WBSVRport:
         "127.0.0.1" "HTTPput" "PROVIDER" bank
         WPORT "HTTPput" "PORT" bank

      ELSE "WSERVER" ptr "HTTPput" "PROVIDER" bank
         UDEF "HTTPput" "PORT" bank
      THEN
   THEN

\  Use word APP_CLIENT_ALLOW and its default file, usrpath/ACCESS, to 
\  define hosts that are not allowed to connect:
   "APP_CLIENT_ALLOW" missing
   IF " tops_http: APP_CLIENT_ALLOW not present, halting" . nl HALT
   THEN

\  To hook word APP_CLIENT_ALLOW into the program, bank its ptr into 
\  word CLIENT_ALLOW, the word the program runs on every connect:
   "APP_CLIENT_ALLOW" ptr "CLIENT_ALLOW" "APP_CLIENT_ALLOW" bank

\-----------------------------------------------------------------------

   pull catmsg

   "HTTPport" exists? IF HTTPport ELSE 80 THEN "PORT" book

 \ Thu Mar 17 16:36:14 PDT 2011.  Set flag for tops_http.v:
   no "PORTSSL" book \ listening port is not secure

   ontheweb (f)
   IF PORT "SERVER-CYCLE" "PORT" bank
      1 20 / "SERVER-CYCLE" PLAY 
   THEN
   4096 netrate

\  Wed Jun 27 19:20:30 PDT 2012.
   host "diego" = 
   host "plunger" = or
   host "riggo" = or \ Sat Jul  5 12:13:50 PDT 2014
   IF 5 "NIST_DELTA" ELSE 5 "NIST_SYNC" THEN ALARM           

\  Start the server:
   "*" PORT DSERVER

   private halt

\-----------------------------------------------------------------------

   Word remoteprompt allows interactive work right on the stack of this
   running daemon.  

   Here is an example of connecting an instance of this program to the 
   daemon started above, and running word remoteprompt to virtually 
   move to the stack of the daemon (which is indicated by the prompt 
   tops@socket3 rather the ready prompt).  

   Different view points are displayed by word clients when it is run 
   at the ready prompt versus at the tops@socket3 prompt (the daemon 
   server).  The "Clients:" list on the daemon shows us connected on 
   socket 6 and a foreign client connected on socket 5 with an HTTP 
   request being served:

      [dale@clacker] /opt > tops
               Tops 2.4.3
      Tue Feb 22 23:18:05 PST 2005
      [tops@clacker] ready > IPloop 80 CLIENT "S" book
   
      [tops@clacker] ready > clients [our session]
       Server local is off
       Clients:
        socket 3, port  80, conn C>S, 127.0.0.1 dale clacker

      [tops@clacker] ready > S remoteprompt
      tops@socket3 > clients [now on SERVER]
       Server local is listening on port 80
       Clients:
        socket 5, port 32882, conn S<F, XXX.XX.148.191 GET /index.html HTTP/1.1
        socket 6, port 32884, conn S<C, 127.0.0.1 LOGIN dale clacker
      tops@socket3 > [pressing Esc-q returns to our session]

      [tops@clacker] ready > 

   Notes:
      C>S indicates us as a client connected to the server 
      S<C indicates this is a server with client (us, this program) 
         connected 
      S<F indicates this is a server with client foreign (not this
         program) connected
