/*: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