// // $Id$ // /* * * TestCGI.PRG * Harbour Test of a CGI/HTML-Generator class. * * 1999/05/30 First implementation. * * Tips: - Use ShowResults to make dynamic html (to test dynamic * results, put the exe file on CGI-BIN dir or equivalent); * - Use SaveToFile to make static html page * * 1999/05/31 Initial CGI functionality. * 1999/06/01 Translated %nn to correct chars. * 1999/06/02 Dynamic TAG matching routines (inspired on Delphi). * First attempt to convert Delphi's ISAPI dll of WebSites' * Function List * (See http://www.flexsys-ci.com/harbour-project/functions.htm) * 1999/06/11 List can be viewed online at * http://www.flexsys-ci.com/cgi-bin/testcgi.exe * 1999/07/29 Changed qOut() calls to OutStd() calls. * **/ #include "cgi.ch" #define IF_BUFFER 65535 FUNCTION Main() LOCAL oHTML := THTML():New() LOCAL hFile, nPos, cString, cBuf, i, cTable, cLine oHTML:SetHTMLFile( "function.cfm" ) hFile := fOpen( "list.txt", 0 ) cString := space( IF_BUFFER ) cBuf := "" cTable := "" // Builds dynamic table replacement WHILE hFile != -1 .AND. (nPos := fRead( hFile, @cString, IF_BUFFER )) > 0 i := 1 DO WHILE i <= nPos IF substr( cString, i, 1 ) = chr( 13 ) i := i + 1 cLine := cBuf cBuf := "" IF left( cLine, 1 ) <> ';' cTable += '
', ;
' ' ) + ;
'
', ;
' ' ) + ;
'
', ;
' ' ) + ;
'" + HB_OSNewLine() + ; cPara + HB_OSNewLine() + ; "
" RETURN( Self ) STATIC FUNCTION Generate() LOCAL Self := QSelf() LOCAL cFile, i, hFile, nPos, cRes := "" LOCAL lFlag := .f. // Is this a meta file or hand generated script? IF empty( ::cHTMLFile ) ::cContent := ; "" + HB_OSNewLine() + ; "No such file: " + ; ::cHTMLFile ELSE // Read from file hFile := fOpen( ::cHTMLFile, 0 ) cFile := space( IF_BUFFER ) DO WHILE (nPos := fRead( hFile, @cFile, IF_BUFFER )) > 0 cFile := left( cFile, nPos ) cRes += cFile cFile := space( IF_BUFFER ) ENDDO fClose( hFile ) // Replace matched tags i := 1 ::cContent := cRes /* TODO: Replace this DO WHILE with FOR..NEXT */ DO WHILE i <= len( ::aReplaceTags ) ::cContent := strtran( ::cContent, ; "<#" + ::aReplaceTags[i, 1] + ">", ::aReplaceTags[i, 2] ) i++ ENDDO /* TODO: Clear remaining (not matched) tags */ /* cRes := "" FOR i := 1 TO len( ::cContent ) IF substr( ::cContent, i, 1 ) == "<" .AND. ; substr( ::cContent, i + 1, 1 ) == "#" lFlag := .t. ELSEIF substr( ::cContent, i, 1 ) == ">" .AND. lFlag lFlag := .f. ELSEIF !lFlag cRes += substr( ::cContent, i, 1 ) ENDIF NEXT i ::cContent := cRes */ ENDIF ENDIF RETURN( Self ) STATIC FUNCTION ShowResult() LOCAL Self := QSelf() OutStd( ; "HTTP/1.0 200 OK" + HB_OSNewLine() + ; "CONTENT-TYPE: TEXT/HTML" + HB_OSNewLine() + HB_OSNewLine() + ; ::cContent ) RETURN( Self ) STATIC FUNCTION SaveToFile( cFile ) LOCAL Self := QSelf() LOCAL hFile := fCreate( cFile ) fWrite( hFile, ::cContent ) fClose( hFile ) RETURN( Self ) STATIC FUNCTION ProcessCGI() LOCAL Self := QSelf() LOCAL cQuery := "" LOCAL cBuff := "" LOCAL nBuff := 0 LOCAL i IF empty( ::aCGIContents ) ::aCGIContents := { ; GetEnv( "SERVER_SOFTWARE" ), ; GetEnv( "SERVER_NAME" ), ; GetEnv( "GATEWAY_INTERFACE" ), ; GetEnv( "SERVER_PROTOCOL" ), ; GetEnv( "SERVER_PORT" ), ; GetEnv( "REQUEST_METHOD" ), ; GetEnv( "HTTP_ACCEPT" ), ; GetEnv( "HTTP_USER_AGENT" ), ; GetEnv( "HTTP_REFERER" ), ; GetEnv( "PATH_INFO" ), ; GetEnv( "PATH_TRANSLATED" ), ; GetEnv( "SCRIPT_NAME" ), ; GetEnv( "QUERY_STRING" ), ; GetEnv( "REMOTE_HOST" ), ; GetEnv( "REMOTE_ADDR" ), ; GetEnv( "REMOTE_USER" ), ; GetEnv( "AUTH_TYPE" ), ; GetEnv( "CONTENT_TYPE" ), ; GetEnv( "CONTENT_LENGTH" ), ; GetEnv( "ANNOTATION_SERVER" ) ; } cQuery := ::GetCGIParam( CGI_QUERY_STRING ) IF !empty( cQuery ) ::aQueryFields := {} FOR i := 1 TO len( cQuery ) + 1 IF i > len( cQuery ) .OR. substr( cQuery, i, 1 ) == "&" aadd( ::aQueryFields, ; { substr( cBuff, 1, at( "=", cBuff ) - 1 ), ; strtran( substr( cBuff, at( "=", cBuff ) + 1, ; len( cBuff ) - at( "=", cBuff ) + 1 ), "+", " " ) } ) cBuff := "" ELSE IF substr( cQuery, i, 1 ) = "%" cBuff += chr( Hex2Dec( substr( cQuery, i + 1, 2 ) ) ) nBuff := 3 ENDIF IF nBuff = 0 cBuff += substr( cQuery, i, 1 ) ELSE nBuff-- ENDIF ENDIF NEXT ENDIF ENDIF RETURN( Self ) STATIC FUNCTION GetCGIParam( nParam ) LOCAL Self := QSelf() ::ProcessCGI() IF nParam > 20 .OR. nParam < 1 outerr( "Invalid CGI parameter" ) RETURN( NIL ) ENDIF RETURN( ::aCGIContents[nParam] ) STATIC FUNCTION QueryFields( cQueryName ) LOCAL Self := QSelf() LOCAL cRet := "" LOCAL nRet ::ProcessCGI() nRet := aScan( ::aQueryFields, ; { |x| upper( x[1] ) = upper( cQueryName ) } ) IF nRet > 0 cRet := ::aQueryFields[nRet, 2] ENDIF RETURN( cRet ) STATIC FUNCTION SetHTMLFile( cFile ) LOCAL Self := QSelf() ::cHTMLFile := cFile RETURN( Self ) STATIC FUNCTION AddReplaceTag( cTag, cReplaceText ) LOCAL Self := QSelf() aAdd( ::aReplaceTags, { cTag, cReplaceText } ) RETURN( Self )