Metropoli BBS
VIEWER: gofilter.vrx MODE: TEXT (ASCII)
/*:VRX         Main
*/
Main:
    signal on halt
/****************************************************************************/
/* GOFILTER.80 - A thined down version of the GOSERVE filter.               */
/* The objective is to make "forms" programming as simple as possible.      */
/* This is designed to provide the minimal amount of support.               */
/* Other features (logs, statistics, etc.) are being developed by other     */
/* projects. The results can be merged later on.  This code has less        */
/* than other project, not more.                                            */
/****************************************************************************/

parse arg source, request, sel

parse var source myaddr port transaction who .
        /*  myaddr      is this machines IP address
            port        is "80"
            transaction is unique integer for this thread
            who         is requestor's IP address */

parse var request verb uri protocol .
        /*  verb        is "GET" or "PUT"
            uri         is like sel
            protocol    is "HTTP/1.0"   */

dir = datadir()                         /* Data directory */
tempfile=dir'$'transaction'.'port       /* unique file name  */
if sel='' then sel="default.htm"        /* home page default */

if left(protocol,4)\='HTTP' & protocol\='' then return "NODATA"

file=dir||sel       /* Note: dir has '\" and sel has "/" */
parse var file filestem '.' ext '?' query
ext=translate(ext)
filestem=translate(filestem,"\","/")

select

  when verb='GET' | verb='HEAD' then
    do
    if ext="" | query<>"" then
        return call_external(tempfile,filestem,query)

    temp=wordpos(ext,"HTM HTML TXT PS ZIP WAV GIF BMP JPG TIF MPG")
    if temp=0 then 
        return response('forbid',"requested unsupported file type")
    mimestuff=word("text/html text/html text/plain application/postscript application/zip audio/x-wav image/gif image/bmp image/jpeg image/tiff video/mpeg",temp)
    if stream(file, 'c', 'query exists')='' then 
        return response('notfound', '"'sel'" could not be found')
    return 'FILE TYPE' mimestuff 'NAME' file
    end

  when verb='POST' then do
    /************************************************************************/
    /* In this support, a POST is always a forms query                      */
    /* It's like GET, but supports more data in the request                 */
    /************************************************************************/
    'read body var words'                    /* get the incoming data */
    if rc=-4 then                            /* body too large */
      return response('badreq', 'sent too much data')
    if rc<>0 then                            /* e.g., invalid HTTP header */
      return response('badreq', 'sent data that could not be read')
    return call_external(tempfile, filestem, words)      
    end /* post */

  otherwise return response('badreq', 'sent an unknown verb "'verb'"')
  end /* select verb */

/* [cannot reach here] */

/* ----------------------------------------------------------------------- */
/* RESPONSE: Standard [mostly error] responses.                            */
/* ----------------------------------------------------------------------- */
/* This routine should stay in the main filter program.                    */
/* Arguments are: response type and extended message information.          */
/* It returns the GoServe command to handle the result file.               */
response: procedure expose tempfile
  parse arg request, message
  select
    when request='badreq'   then use='400 Bad Request Syntax'
    when request='notfound' then use='404 Not found'
    when request='forbid'   then use='403 Forbidden'
    when request='unauth'   then use='401 Unauthorized [list]'
    end  /* Add others to this list as needed */
  /* Now set the response and build the response file */
  'RESPONSE HTTP/1.0' use     /* Set HTTP response line */
  parse var use code text
  call lineout tempfile, '<!doctype html public "-//IETF//DTD HTML 2.0//EN">'
  call lineout tempfile, "<html><head><title>"text"</title></head>"
  call lineout tempfile, "<body><h2>Sorry...</h2>"
  call lineout tempfile, "<p>The request from your Web client" message"."
  call lineout tempfile, "<hr><em>HTTP response code:</em>" code
  call lineout tempfile, "<br><em>From server at:</em>" servername()
  call lineout tempfile, "<br><em>Running:</em>" server()
  call lineout tempfile, "</body></html>"
  call lineout tempfile  /* close */
  return 'FILE ERASE TYPE text/html NAME' tempfile

/****************************************************************************/
/* This routine provides the interface to external Rexx programs that       */
/* reside in the library.  All information has to be passed as a parameter. */
/****************************************************************************/
call_external: procedure
parse arg file, routine, list

 if stream(routine".80","c","query exists")<>"" then
    do
    interpret 'action= "'routine'"(file,list)'
    say action
    return action
    end
 else
    return response('notfound', " the" routine "routine is not in the library.")
exit

/*:VRX         Halt
*/
Halt:

exit

[ RETURN TO DIRECTORY ]