A few thoughts about how I see CGI
No Comments
Written by Anders on April 1, 2008 – 6:20 am
The CGI specification was designed to make it possible to implement CGI programs in essentially any language. A lot of the earliest CGI programs were written in C, but gradually interpreted scripting languages such as Perl becamemore popular.Many CGI programs were implemented by relatively inexperienced programmers who found the development cycle for an interpretive language somewhat easier than the conventional cycle of edit/compile/ re-edit/re-compile/re-edit/…/link/re-edit/re-compile/…/link/and install.
Most of the processing in a CGI program tends to be a matter of comparing and combining strings; Perl has inherently better support for such string manipulations than does C/C++. Finally, the Perl DBI module (library) for interfacing to databases was more accessible and easier to use than C/C++ equivalents. This first CGI example uses a little C++ framework. Since so much of a CGI program is standardized, it is possible to abstract out these standard parts and encode them in an extensible framework. The example framework uses two classes: Token and CGI_Helper. The Token class represents a name/value pair:
class Token {
public:
Token(char *name, char *value);
~Token();
const char *Name();
const char *Value();
private:
char *fName;
char *fValue;
};
The CGI_Helper class is a base class that must be subclassed to create an effective CGI program. The CGI_Helper class has no data members of its own; it simply defines the framework functions. There are a few private functions that implement details, such as the %xx to character decoding of strings. The public and protected functions are all defined as virtual, allowing them to be overridden in specialized subclasses.
class CGI_Helper {
public:
CGI_Helper() { }
virtual ~CGI_Helper() { }
virtual void HTML_Header(const char* title);
virtual void HTML_Trailer();
virtual void Handle_Request();
protected:
virtual void StartTokens() { }
virtual void EndTokens() { }
virtual void Process(char *data);
virtual void ProcessToken(Token *tok) { }
private:
int hexvalue(char ch);
void ReadString(char *str, char*& data, char*endpt);
Token *GetToken(char*& data);
void HandleGet();
void HandlePost();
};








