// Compiles with Visual Studio 2008 for Windows // FastCGI App - Demonstrates all the function call's for this C Library // running locally using the (free) Abyss Web Server #include <iostream> // input/output functionality #include <sstream> // manipulate strings (integer conversion) #include <string> // work with strings in a more intuitive way using namespace std; // Header file for FastCGI library #include "libfcgi2.h" // Link the required .lib spec file for the dll #pragma comment(lib,"libfcgi2.lib") // Specify the compiled apps path and name // (delete entry: project -> properties -> Linker -> General -> Output File) #pragma comment(linker, "/out:\"C:\\Program Files\\Abyss Web Server\\htdocs\\FCGIecho.exe\"") // ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ int main( ) { FCGX_REQUEST Req = { 0 }; // Create & Initialize all FCGX Struct members to zero int ConLen(0), DecLen(0), RetVal(0); bool bErr; // Error Flag const char *cString, *cStrRet; // Uninitialized C-Strings string sReply, sTemp; // Strings string sHead("Content-Type: text/html\r\n\r\n"); // HTTP header ostringstream ss; // String Stream object // FCGX_NONE if( FCGX_InitRequest( &Req, 0, FCGX_DEBUG ) < 0 ) return 0; // Initialize FCGI Library // Open Databases etc while(true) // Main Request processing loop { RetVal = FCGX_Accept_r(&Req); // Execution blocked here until an HTTP request arrives if( RetVal < 0 ) { if( RetVal == -1 ) break; // SIGTERM FCGX_PutS( "Content-Type: text/html\r\n\r\n", Req.pOut ); FCGX_PutS( Req.pzLastErr, Req.pOut ); // Return Error to User FCGX_PutS( Req.pzLastErr, Req.pErr ); // Add to Web Server Error Log bErr = true; break; } //============ sReply = sHead; // HTTP Header switch(Req.ReqMethod) // Very fast, no string comparisons { case HTTP_GET: if( strlen(Req.pzQuery) > 0 ) // Echo the Query String { ss << strlen(Req.pzQuery); // Convert to string sReply += "Query String length=" + ss.str()+ "<BR>"; ss.str(""); // reset sReply += "GET Data: <BR>"; sReply += Req.pzQuery; // Append null terminated char array sReply += "<BR>"; // HTML newline } case HTTP_POST: ConLen = Req.pIn->LenStored; // De-reference content length if( ConLen > 0 ) // Echo POST data { ss << ConLen; // Convert to string sReply += "CONTENT_LENGTH= " + ss.str()+ "<BR>"; ss.str(""); // reset sTemp.resize(ConLen, 0); // Create a string big enough for the Query if( FCGX_GetStr(sTemp.data(), sTemp.length(), Req.pIn) < 0 ){bErr=true; break;} DecLen = FCGX_URLDecode(sTemp.data(), sTemp.length()); // InPlace Decoding sReply += "'POST' Data: <BR> <PRE>"; // Show text as formatted sReply.append(sTemp.data(), DecLen); // Add the decoded length only } case HTTP_HEAD: case HTTP_TRACE: default: // Web Servers usually only pass a few Request Methods break; } if( FCGX_PutStr( sReply.data(), sReply.length(), Req.pOut ) < 0 ){bErr=true; break;} //============ // Demonstrate some C-String function calls cString = "A C-String is only a Null Terminated Character array"; // C Example if( FCGX_PutS( cString, Req.pOut ) < 0 ){bErr=true; break;} if( FCGX_PutS( "<BR>", Req.pOut ) < 0 ){bErr=true; break;} //============ cStrRet = FCGX_GetParam( "REMOTE_ADDR", Req.envp ); // Retrieve a Request Param if( FCGX_PutS( cStrRet, Req.pOut ) < 0 ){bErr=true; break;} if( FCGX_PutS( "<BR>", Req.pOut ) < 0 ){bErr=true; break;} //============ if( FCGX_Finish_r(&Req) < 0 ){bErr=true; break;} //============ } if(bErr) FCGX_PutDebug( Req.pzLastErr ); // Add Errors to Debug file (if used) // Close Databases return 0; } // ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ |