C++ FastCGI Echo Example


// 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;
}

// ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

Comments