diff --git a/harbour/ChangeLog b/harbour/ChangeLog
index 56fab6c15d..75c02f8ea5 100644
--- a/harbour/ChangeLog
+++ b/harbour/ChangeLog
@@ -8,6 +8,26 @@
2009-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
*/
+2009-03-03 23:56 UTC+0100 Francesco Saverio Giudice (info/at/fsgiudice.com)
+ * harbour/contrib/examples/uhttpd/uhttpd.prg
+ * Updated uHTTPD (Work in progress)
+ ! Fixing memory usage attempt.
+ Set PRIVATE vars to NIL when not more used and force
+ collect memory with hb_GCAll( .T. )
+ * Set Service Threads initial value to 0
+ + Added support for directory index files
+ + Added support for filters (WIP)
+ * Added creation of error.log file in case of error
+ * Minor changes
+ * harbour/contrib/examples/uhttpd/cgifunc.prg
+ * Fixed comment
+ * harbour/contrib/examples/uhttpd/uhttpd.ini
+ + DirectoryIndex entry
+ ; NOTE: Please check me for memory usage. I have added a comment
+ // FSG - memory check
+ to interested lines. But I'm not sure if this solves the
+ problem.
+
2009-03-03 22:22 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/tests/speedtst.prg
* updated to work with CA-Cl*pper
diff --git a/harbour/contrib/examples/uhttpd/cgifunc.prg b/harbour/contrib/examples/uhttpd/cgifunc.prg
index fc3717cf45..654b61ec57 100644
--- a/harbour/contrib/examples/uhttpd/cgifunc.prg
+++ b/harbour/contrib/examples/uhttpd/cgifunc.prg
@@ -53,7 +53,6 @@
#ifdef __XHARBOUR__
#include "hbcompat.ch"
#else
-
//#include "xhb.ch"
#include "common.ch"
#include "error.ch"
@@ -718,8 +717,7 @@ PROCEDURE uhttpd_WriteToLogFile( cString, cLog, lCreate )
nHandle := FOpen( cLog, FO_READWRITE + FO_SHARED)
ELSE
nHandle := FCreate( cLog )
- // Dopo che lo creato, lo richiudo immediatamente e lo riapro in modo condiviso
- // nel caso arrivasse una nuova scrittura
+ // After creation, I close and reopen it shared
IF Ferror() == 0 .AND. nHandle > 0
FClose( nHandle )
nHandle := FOpen( cLog, FO_READWRITE + FO_SHARED)
@@ -862,3 +860,4 @@ FUNCTION uhttpd_HGetValue( hHash, cKey )
ENDIF
//RETURN IIF( cKey IN hHash:Keys, hHash[ cKey ], NIL )
RETURN xVal
+
diff --git a/harbour/contrib/examples/uhttpd/uhttpd.ini b/harbour/contrib/examples/uhttpd/uhttpd.ini
index b5701b8e22..f2eafabb5f 100644
--- a/harbour/contrib/examples/uhttpd/uhttpd.ini
+++ b/harbour/contrib/examples/uhttpd/uhttpd.ini
@@ -11,6 +11,9 @@
# --- display folder content
#show_indexes = .f.
+# --- default index files
+#DirectoryIndex = index.html index.htm
+
[THREADS]
# --- how much a thread has to wait a connection before quit
#max_wait = 60
@@ -33,4 +36,4 @@
# --- here put aliases to real path
# (under document_root path defined above)
/info = /cgi-bin/info.hrb
-/cookie = /cgi-bin/cookie.hrb
+/cookie = /cgi-bin/cookie.hrb
\ No newline at end of file
diff --git a/harbour/contrib/examples/uhttpd/uhttpd.prg b/harbour/contrib/examples/uhttpd/uhttpd.prg
index 0667ddb43a..a9fc804874 100644
--- a/harbour/contrib/examples/uhttpd/uhttpd.prg
+++ b/harbour/contrib/examples/uhttpd/uhttpd.prg
@@ -122,7 +122,7 @@
#define START_RUNNING_THREADS 4 // Start threads to serve connections
#define MAX_RUNNING_THREADS 20 // Max running threads
-#define START_SERVICE_THREADS 1 // Initial number for service connections
+#define START_SERVICE_THREADS 0 // Initial number for service connections
#define MAX_SERVICE_THREADS 3 // Max running threads
#define LISTEN_PORT 8082 // differs from standard 80 port for tests in case
@@ -130,6 +130,7 @@
#define FILE_STOP ".uhttpd.stop"
#define FILE_ACCESS_LOG "logs\access.log"
#define FILE_ERROR_LOG "logs\error.log"
+#define DIRECTORYINDEX_ARRAY { "index.html", "index.htm" }
#define PAGE_STATUS_REFRESH 5
#define THREAD_MAX_WAIT ( 60 ) // HOW MUCH TIME THREAD HAS TO WAIT BEFORE FINISH - IN SECONDS
@@ -176,6 +177,7 @@ STATIC s_nServiceConnections, s_nMaxServiceConnections, s_nTotServiceConnections
STATIC s_aRunningThreads := {}
STATIC s_aServiceThreads := {}
STATIC s_hHRBModules := {=>}
+STATIC s_aDirectoryIndex
#ifdef USE_HB_INET
STATIC s_cLocalAddress, s_nLocalPort
@@ -197,7 +199,7 @@ FUNCTION MAIN( ... )
LOCAL aThreads, nStartThreads, nMaxThreads, nStartServiceThreads
LOCAL i, cPar, lStop
LOCAL cGT, cDocumentRoot, lIndexes, cConfig
- LOCAL lConsole, lScriptAliasMixedCase
+ LOCAL lConsole, lScriptAliasMixedCase, aDirectoryIndex
LOCAL nProgress := 0
LOCAL hDefault, cLogAccess, cLogError, cSessionPath
LOCAL cCmdPort, cCmdDocumentRoot, lCmdIndexes, nCmdStartThreads, nCmdMaxThreads
@@ -294,6 +296,7 @@ FUNCTION MAIN( ... )
lIndexes := hDefault[ "MAIN" ][ "SHOW_INDEXES" ]
lScriptAliasMixedCase := hDefault[ "MAIN" ][ "SCRIPTALIASMIXEDCASE" ]
cSessionPath := hDefault[ "MAIN" ][ "SESSIONPATH" ]
+ aDirectoryIndex := hDefault[ "MAIN" ][ "DIRECTORYINDEX" ]
cLogAccess := hDefault[ "LOGFILES" ][ "ACCESS" ]
cLogError := hDefault[ "LOGFILES" ][ "ERROR" ]
@@ -393,6 +396,7 @@ FUNCTION MAIN( ... )
s_nMaxServiceConnections := 0
s_nTotServiceConnections := 0
s_cSessionPath := cSessionPath
+ s_aDirectoryIndex := aDirectoryIndex
// --------------------- Open log files -------------------------------------
@@ -456,6 +460,8 @@ FUNCTION MAIN( ... )
WriteToConsole( "Starting AcceptConnection Thread" )
aThreads := {}
AADD( aThreads, hb_threadStart( @AcceptConnections() ) )
+ //hb_ToOutDebug( "Len( aThreads ) = %i\n\r", Len( aThreads ) )
+
// --------------------------------------------------------------------------------- //
// main loop
@@ -478,10 +484,10 @@ FUNCTION MAIN( ... )
// Show application infos
IF hb_mutexLock( s_hmtxBusy )
- hb_DispOutAt( 5, 5, "Threads : " + Transform( s_nThreads, "9999999999" ) )
- hb_DispOutAt( 6, 5, "Connections : " + Transform( s_nConnections, "9999999999" ) )
- hb_DispOutAt( 7, 5, "Max Connections : " + Transform( s_nMaxConnections, "9999999999" ) )
- hb_DispOutAt( 8, 5, "Total Connections : " + Transform( s_nTotConnections, "9999999999" ) )
+ hb_DispOutAt( 5, 5, "Threads : " + Transform( s_nThreads, "9999999999" ) )
+ hb_DispOutAt( 6, 5, "Connections : " + Transform( s_nConnections, "9999999999" ) )
+ hb_DispOutAt( 7, 5, "Max Connections : " + Transform( s_nMaxConnections, "9999999999" ) )
+ hb_DispOutAt( 8, 5, "Total Connections : " + Transform( s_nTotConnections, "9999999999" ) )
hb_DispOutAt( 5, 37, "ServiceThreads : " + Transform( s_nServiceThreads, "9999999999" ) )
hb_DispOutAt( 6, 37, "Connections : " + Transform( s_nServiceConnections, "9999999999" ) )
@@ -506,7 +512,7 @@ FUNCTION MAIN( ... )
// Accept a remote connection
#ifdef USE_HB_INET
- hSocket := HB_INETACCEPT( hListen )
+ hSocket := hb_InetAccept( hListen )
#else
hSocket := socket_accept( hListen, @aRemote )
#endif
@@ -535,10 +541,13 @@ FUNCTION MAIN( ... )
ENDIF
+ // Memory release
+ hb_GCAll( TRUE ) // FSG - memory check
+
ENDDO
WriteToConsole( "Waiting threads" )
- // Send to thread that they have to stop
+ // Send to threads that they have to stop
AEVAL( aThreads, {|| hb_mutexNotify( s_hmtxQueue, NIL ) } )
// Wait threads to end
AEVAL( aThreads, {|h| hb_threadJoin( h ) } )
@@ -644,7 +653,7 @@ STATIC FUNCTION AcceptConnections()
pThread := hb_threadStart( @ServiceConnection(), @nThreadID )
AADD( s_aServiceThreads, { pThread, nThreadID } )
ENDIF
- // Otherwise I send connection to service thread
+ // Otherwise I send connection to current service thread queue
hb_mutexNotify( s_hmtxServiceThreads, hSocket )
LOOP
@@ -653,9 +662,11 @@ STATIC FUNCTION AcceptConnections()
ELSEIF nConnections >= nThreads
// Add one more
pThread := hb_threadStart( @ProcessConnection(), @nThreadID )
+ //hb_ToOutDebug( "Len( s_aRunningThreads ) = %i\n\r", Len( s_aRunningThreads ) )
AADD( s_aRunningThreads, { pThread, nThreadID } )
ENDIF
- // Otherwise I send connection to running thread
+ // Otherwise I send connection to running thread queue
+ //hb_ToOutDebug( "Len( s_aRunningThreads ) = %i\n\r", Len( s_aRunningThreads ) )
hb_mutexNotify( s_hmtxRunningThreads, hSocket )
ENDDO
@@ -673,6 +684,8 @@ STATIC FUNCTION ProcessConnection( /*@*/ nThreadId )
nThreadId := hb_threadID()
+ //hb_ToOutDebug( "nThreadId = %s\r\n", nThreadId )
+
ErrorBlock( { | oError | uhttpd_DefError( oError ) } )
WriteToConsole( "Starting ProcessConnections() " + hb_CStr( nThreadId ) )
@@ -761,19 +774,24 @@ STATIC FUNCTION ProcessConnection( /*@*/ nThreadId )
WriteToLog( cRequest )
+ // Destroy PRIVATE VARIABLES // FSG - memory check
+ _SERVER := _GET := _POST := _COOKIE := _SESSION := _REQUEST := _HTTP_REQUEST := m_cPost := NIL
+
ENDIF
-#ifdef USE_HB_INET
- hb_InetClose( hSocket )
-#else
- socket_shutdown( hSocket )
- socket_close( hSocket )
-#endif
END SEQUENCE
nParseTime := hb_milliseconds() - nMsecs
WriteToConsole( "Page served in : " + Str( nParseTime/1000, 7, 4 ) + " seconds" )
+#ifdef USE_HB_INET
+ hb_InetClose( hSocket )
+ hSocket := NIL
+#else
+ socket_shutdown( hSocket )
+ socket_close( hSocket )
+#endif
+
IF hb_mutexLock( s_hmtxBusy )
s_nConnections--
hb_mutexUnlock( s_hmtxBusy )
@@ -785,6 +803,7 @@ STATIC FUNCTION ProcessConnection( /*@*/ nThreadId )
IF hb_mutexLock( s_hmtxBusy )
s_nThreads--
+ //hb_ToOutDebug( "Len( s_aRunningThreads ) = %i\n\r", Len( s_aRunningThreads ) )
IF ( nPos := aScan( s_aRunningThreads, {|h| h[2] == nThreadId } ) > 0 )
hb_aDel( s_aRunningThreads, nPos, TRUE )
ENDIF
@@ -884,18 +903,24 @@ STATIC FUNCTION ServiceConnection( /*@*/ nThreadId )
WriteToLog( cRequest )
+ // Destroy PRIVATE VARIABLES // FSG - memory check
+ _SERVER := _GET := _POST := _COOKIE := _SESSION := _REQUEST := _HTTP_REQUEST := m_cPost := NIL
+
ENDIF
-#ifdef USE_HB_INET
- hb_InetClose( hSocket )
-#else
- socket_shutdown( hSocket )
- socket_close( hSocket )
-#endif
+
END SEQUENCE
nParseTime := hb_milliseconds() - nMsecs
WriteToConsole( "Page served in : " + Str( nParseTime/1000, 7, 4 ) + " seconds" )
+#ifdef USE_HB_INET
+ hb_InetClose( hSocket )
+ hSocket := NIL
+#else
+ socket_shutdown( hSocket )
+ socket_close( hSocket )
+#endif
+
IF hb_mutexLock( s_hmtxBusy )
s_nServiceConnections--
hb_mutexUnlock( s_hmtxBusy )
@@ -922,7 +947,7 @@ STATIC FUNCTION ParseRequest( cRequest )
// RFC2616
aRequest := uhttpd_split( CR_LF, cRequest )
- //hb_toOutDebug( "aRequest = %s\n\r", hb_ValToExp( aRequest ) )
+ //hb_ToOutDebug( "aRequest = %s\n\r", hb_ValToExp( aRequest ) )
WriteToConsole( aRequest[1] )
aLine := uhttpd_split( " ", aRequest[1] )
@@ -1384,11 +1409,13 @@ STATIC FUNCTION readRequest( hSocket, /* @ */ cRequest )
DO WHILE /* AT( CR_LF + CR_LF, cRequest ) == 0 .AND. */ nRcvLen > 0
cBuf := hb_InetRecvLine( hSocket, @nRcvLen )
//hb_ToOutDebug( " nRcvLen = %i, cBuf = %s \n\r", nRcvLen, cBuf )
- cRequest += cBuf + CR_LF
- nLen += nRcvLen
- IF nRcvLen > 0 .AND. At( "CONTENT-LENGTH:", Upper( cBuf ) ) == 1
- cBuf := Substr( cBuf, At( ":", cBuf ) + 1 )
- nContLen := Val( cBuf )
+ IF nRcvLen > 0
+ cRequest += cBuf + CR_LF
+ nLen += nRcvLen
+ IF At( "CONTENT-LENGTH:", Upper( cBuf ) ) == 1
+ cBuf := Substr( cBuf, At( ":", cBuf ) + 1 )
+ nContLen := Val( cBuf )
+ ENDIF
ENDIF
ENDDO
@@ -1397,7 +1424,7 @@ STATIC FUNCTION readRequest( hSocket, /* @ */ cRequest )
IF nLen > 0 .AND. nContLen > 0
// cPostData is autoAllocated
cBuf := Space( nContLen )
- IF InetRecvAll( hSocket, @cBuf, nContLen ) <= 0
+ IF hb_InetRecvAll( hSocket, @cBuf, nContLen ) <= 0
nLen := -1 // force error check
ELSE
cRequest += cBuf
@@ -1502,7 +1529,7 @@ FUNCTION uhttpd_join( cSeparator, aData )
STATIC FUNCTION uproc_default()
LOCAL cFileName, nI, cI
- LOCAL cExt, xResult, pHRB, oError, cHRBBody
+ LOCAL cExt
//cFileName := STRTRAN(cRoot + _SERVER["SCRIPT_NAME"], "//", "/")
cFileName := _SERVER[ "SCRIPT_FILENAME" ]
@@ -1522,14 +1549,21 @@ STATIC FUNCTION uproc_default()
//hb_toOutDebug( "cFileName = %s, uhttpd_OSFileName( cFileName ) = %s,\n\r s_hScriptAliases = %s\n\r", cFileName, uhttpd_OSFileName( cFileName ), hb_ValToExp( s_hScriptAliases ) )
+ // Server status request
IF Upper( _SERVER[ "SCRIPT_NAME" ] ) == "/SERVERSTATUS"
+
ShowServerStatus()
+
+ // real file request
ELSEIF HB_FileExists( uhttpd_OSFileName( cFileName ) )
+
IF ( nI := RAT( ".", cFileName ) ) > 0
SWITCH ( cExt := LOWER( SUBSTR( cFileName, nI + 1 ) ) )
- CASE "hrb" ; cI := "text/html"; EXIT
- CASE "exe" ; cI := "text/html"; EXIT
+ // First filters
+ CASE "hrb" ; EXIT
+ CASE "exe" ; EXIT
+ // Then other files
CASE "css" ; cI := "text/css"; EXIT
CASE "htm" ; CASE "html"; cI := "text/html"; EXIT
CASE "txt" ; CASE "text"; CASE "asc"
@@ -1566,95 +1600,44 @@ STATIC FUNCTION uproc_default()
cI := "application/octet-stream"
ENDSWITCH
+ // Starting Filters
IF cExt == "hrb"
// Starting HRB module
-
- TRY
- // Lock HRB to avoid MT race conditions
- IF !HRB_ACTIVATE_CACHE
- cHRBBody := HRB_LoadFromFile( uhttpd_OSFileName( cFileName ) )
- ENDIF
- IF hb_mutexLock( s_hmtxHRB )
- IF HRB_ACTIVATE_CACHE
- // caching modules
- IF !hb_HHasKey( s_hHRBModules, cFileName )
- hb_HSet( s_hHRBModules, cFileName, HRB_LoadFromFile( uhttpd_OSFileName( cFileName ) ) )
- ENDIF
- cHRBBody := s_hHRBModules[ cFileName ]
- ENDIF
- IF !EMPTY( pHRB := HB_HRBLOAD( cHRBBody ) )
-
- xResult := HRBMAIN()
-
- HB_HRBUNLOAD( pHRB )
- ELSE
- uhttpd_SetStatusCode( 404 )
- t_cErrorMsg := "File does not exist: " + cFileName
- ENDIF
- hb_mutexUnlock( s_hmtxHRB )
-
- ENDIF
-
- IF HB_ISSTRING( xResult )
- uhttpd_AddHeader( "Content-Type", cI )
- uhttpd_Write( xResult )
- ELSE
- // Application in HRB module is responsible to send HTML content
- ENDIF
-
- CATCH oError
-
- WriteToConsole( "Error!" )
-
- uhttpd_AddHeader( "Content-Type", "text/html" )
- uhttpd_Write( "Error" )
- uhttpd_Write( "
Description: " + hb_cStr( oError:Description ) )
- uhttpd_Write( "
Filename: " + hb_cStr( oError:filename ) )
- uhttpd_Write( "
Operation: " + hb_cStr( oError:operation ) )
- uhttpd_Write( "
OsCode: " + hb_cStr( oError:osCode ) )
- uhttpd_Write( "
GenCode: " + hb_cStr( oError:genCode ) )
- uhttpd_Write( "
SubCode: " + hb_cStr( oError:subCode ) )
- uhttpd_Write( "
SubSystem: " + hb_cStr( oError:subSystem ) )
- uhttpd_Write( "
Args: " + hb_cStr( hb_ValToExp( oError:args ) ) )
- uhttpd_Write( "
ProcName: " + hb_cStr( procname( 0 ) ) )
- uhttpd_Write( "
ProcLine: " + hb_cStr( procline( 0 ) ) )
- END
+ RETURN Filter_HRB( cFileName )
ELSEIF cExt == "exe"
// Starting CGI application
-
- IF ( CGIExec( uhttpd_OSFileName(cFileName), @xResult ) ) == 0
-
- //uhttpd_AddHeader( "Content-Type", cI )
- //uhttpd_Write( xResult )
- RETURN "HTTP/1.1 200 OK " + CR_LF + xResult
-
- ELSE
-
- uhttpd_AddHeader( "Content-Type", cI )
- uhttpd_Write( "CGI Error" )
-
- ENDIF
+ RETURN Filter_EXE( cFileName )
ELSE
+
+ // Standard file
+
uhttpd_AddHeader( "Content-Type", cI )
uhttpd_Write( HB_MEMOREAD( uhttpd_OSFileName( cFileName ) ) )
ENDIF
ELSE
+ // Unknown file type
+
cI := "application/octet-stream"
uhttpd_AddHeader( "Content-Type", cI )
uhttpd_Write( HB_MEMOREAD( uhttpd_OSFileName( cFileName ) ) )
ENDIF
+ // Directory content request
ELSEIF HB_DirExists( uhttpd_OSFileName( cFileName ) )
+
+ // if it exists as folder, add trailing slash and redirect to it
IF RIGHT( cFileName, 1 ) != "/"
uhttpd_AddHeader( "Location", "http://" + _SERVER[ "HTTP_HOST" ] + _SERVER[ "SCRIPT_NAME" ] + "/" )
RETURN MakeResponse()
ENDIF
- IF ASCAN( { "index.html", "index.htm" }, ;
+
+ // Search for directory index file, i.e.: index.html
+ IF ASCAN( s_aDirectoryIndex, ;
{|x| IIF( HB_FileExists( uhttpd_OSFileName( cFileName + X ) ), ( cFileName += X, .T. ), .F. ) } ) > 0
uhttpd_AddHeader( "Content-Type", "text/html" )
uhttpd_Write( HB_MEMOREAD( uhttpd_OSFileName( cFileName ) ) )
@@ -1672,9 +1655,13 @@ STATIC FUNCTION uproc_default()
ShowFolder( cFileName )
ELSE
+
+ // We cannot handle request
+
uhttpd_SetStatusCode( 404 )
t_cErrorMsg := "File does not exist: " + cFileName
ENDIF
+
RETURN MakeResponse()
// Define environment SET variables - TODO: Actually only for windows, make multiplatform
@@ -1932,7 +1919,8 @@ STATIC FUNCTION ParseIni( cConfig )
"DOCUMENT_ROOT" => EXE_Path() + "\home" ,;
"SHOW_INDEXES" => FALSE ,;
"SCRIPTALIASMIXEDCASE" => TRUE ,;
- "SESSIONPATH" => EXE_Path() + "\sessions" ;
+ "SESSIONPATH" => EXE_Path() + "\sessions" ,;
+ "DIRECTORYINDEX" => DIRECTORYINDEX_ARRAY ;
},;
"LOGFILES" => { ;
"ACCESS" => FILE_ACCESS_LOG ,;
@@ -1999,6 +1987,11 @@ STATIC FUNCTION ParseIni( cConfig )
// Change APP_DIR macro with current exe path
xVal := StrTran( cVal, "$(APP_DIR)", Exe_Path() )
ENDIF
+ CASE cKey == "DIRECTORYINDEX"
+ IF !Empty( cVal )
+ // Change APP_DIR macro with current exe path
+ xVal := uhttpd_split( " ", AllTrim( cVal ) )
+ ENDIF
ENDCASE
CASE cSection == "LOGFILES"
DO CASE
@@ -2135,6 +2128,9 @@ STATIC FUNCTION uhttpd_DefError( oError )
OutErr( hb_OSNewLine() )
OutErr( cCallstack )
+ // Write to errorlog
+ uhttpd_WriteToLogFile( cMessage + HB_OsPathSeparator() + cCallstack, Exe_Path() + "\error.log" )
+
ErrorLevel( 1 )
QUIT
@@ -2173,3 +2169,79 @@ STATIC FUNCTION ErrorMessage( oError )
ENDCASE
RETURN cMessage
+
+// ------------------ FILTERS ---------------------
+STATIC FUNCTION Filter_HRB( cFileName )
+ LOCAL xResult
+ LOCAL cHRBBody, pHRB, oError
+
+ TRY
+ // Lock HRB to avoid MT race conditions
+ IF !HRB_ACTIVATE_CACHE
+ cHRBBody := HRB_LoadFromFile( uhttpd_OSFileName( cFileName ) )
+ ENDIF
+ IF hb_mutexLock( s_hmtxHRB )
+ IF HRB_ACTIVATE_CACHE
+ // caching modules
+ IF !hb_HHasKey( s_hHRBModules, cFileName )
+ hb_HSet( s_hHRBModules, cFileName, HRB_LoadFromFile( uhttpd_OSFileName( cFileName ) ) )
+ ENDIF
+ cHRBBody := s_hHRBModules[ cFileName ]
+ ENDIF
+ IF !EMPTY( pHRB := HB_HRBLOAD( cHRBBody ) )
+
+ xResult := HRBMAIN()
+
+ HB_HRBUNLOAD( pHRB )
+ ELSE
+ uhttpd_SetStatusCode( 404 )
+ t_cErrorMsg := "File does not exist: " + cFileName
+ ENDIF
+ hb_mutexUnlock( s_hmtxHRB )
+
+ ENDIF
+
+ IF HB_ISSTRING( xResult )
+ uhttpd_AddHeader( "Content-Type", "text/html" )
+ uhttpd_Write( xResult )
+ ELSE
+ // Application in HRB module is responsible to send HTML content
+ ENDIF
+
+ CATCH oError
+
+ WriteToConsole( "Error!" )
+
+ uhttpd_AddHeader( "Content-Type", "text/html" )
+ uhttpd_Write( "Error" )
+ uhttpd_Write( "
Description: " + hb_cStr( oError:Description ) )
+ uhttpd_Write( "
Filename: " + hb_cStr( oError:filename ) )
+ uhttpd_Write( "
Operation: " + hb_cStr( oError:operation ) )
+ uhttpd_Write( "
OsCode: " + hb_cStr( oError:osCode ) )
+ uhttpd_Write( "
GenCode: " + hb_cStr( oError:genCode ) )
+ uhttpd_Write( "
SubCode: " + hb_cStr( oError:subCode ) )
+ uhttpd_Write( "
SubSystem: " + hb_cStr( oError:subSystem ) )
+ uhttpd_Write( "
Args: " + hb_cStr( hb_ValToExp( oError:args ) ) )
+ uhttpd_Write( "
ProcName: " + hb_cStr( procname( 0 ) ) )
+ uhttpd_Write( "
ProcLine: " + hb_cStr( procline( 0 ) ) )
+ END
+
+ RETURN MakeResponse()
+
+STATIC FUNCTION Filter_EXE( cFileName )
+ LOCAL xResult
+
+ IF ( CGIExec( uhttpd_OSFileName(cFileName), @xResult ) ) == 0
+
+ //uhttpd_AddHeader( "Content-Type", cI )
+ //uhttpd_Write( xResult )
+ RETURN "HTTP/1.1 200 OK " + CR_LF + xResult
+
+ ELSE
+
+ uhttpd_AddHeader( "Content-Type", "text/html" )
+ uhttpd_Write( "CGI Error" )
+
+ ENDIF
+
+ RETURN MakeResponse()
\ No newline at end of file