INTERNET DEVELOPMENT


Using VC++ 4.x with WinCGI

Mark Wheeler

If you have a Windows-based web server, WinCGI can ease your CGI programming chores.


Introduction and Background

Early in the development of the Web, CGI became the standard server method for processing client requests. To this day, CGI is still a common method of interfacing a browser with the web server. But CGI is no longer the only game in town. There are many ways you can implement, or simulate interactive conversation between a web browser and a web server. One of these methods is WinCGI.

This article describes a set of C++ classes that enable you to create a WinCGI application in Visual C++. The source code is available electronically from the CUJ archives (see p. 3 for details).

What is WinCGI?

WinCGI is a logical spin-off of CGI. Whereas CGI interfaces the server and the application's software through the "standard in" and "standard out" environment, WinCGI uses Microsoft Windows profiles, also known as .INI files. Here's how it works: when the web server receives a request to invoke a WinCGI server application, it first generates a profile file and passes the file specification of this profile to the server application as an argument. Next, the server application retrieves the information in this profile, placing each component into variables. One component of this profile contains the output file specification. This is where the server application will place its information destined for the client. Once the WinCGI application has finished storing its output to this file and closed it, the application terminates and the web server sends it to the client's browser. The web server does not wrap the output in any way, so the output file must contain any necessary HTML tags required at the browser end.

WinCGI has an advantage over CGI in that it provides a consistent interface and works well in the object-oriented world of Visual C++. It has a disadvantage in that it is Microsoft Windows centric, so the code you write will only operate on a Windows platform. However, since WinCGI only restricts the server operating system, clients can still enjoy access to the functionality these server applications provide.

For more information on the WinCGI specification, set your browser to http://website.ora.com/wsdocs/32demo/windows-cgi.html.

Implementing WinCGI in C++

The primary development language at my company is Microsoft Visual C++, and we use it to produce our web-server applications. I was recently involved in a project to serve up data from a proprietary database system over the Internet via a web server, in the well known three-tier client/server model. We chose to implement WinCGI rather than CGI because of its data transfer capabilities. However, WinCGI was originally developed to work with Visual Basic or Delphi. Therefore, we needed an interface that would allow Visual C++ to interoperate with the WinCGI specification.

The result of our efforts is four classes and their accompanying header files. These classes are directly modeled after the Visual Basic "CGI Framework" implementation, developed by Bob Denny of O'Reilly and Associates. (O'Reilly and Associates were instrumental in the definition of the WinCGI specification.) We defined each class to take advantage of MFC and the Visual C++ environment. The names of these classes are: CWinCGI, Tuple, HugeTuple, and FileTuple. CWinCGI contains the methods needed to absorb the profile generated by the server and parse each field of the incoming data into member variables. The Tuple, HugeTuple, and FileTuple classes are data structures and contain no methods. All of the processing is performed by the main procedure and the CWinCGI class methods.

Process Flow

When the server invokes the WinCGI application, it passes the file specification of the profile file to the main procedure as an argument. If no argument exists, the procedure assumes that the software was invoked via the command line and displays an appropriate message. Assuming an argument exists, main calls the CWinCGI method InitializeCGI and passes the profile file specification to it. InitializeCGI then opens and parses the profile file into the designated member variables. Finally, main calls CGI_Main, which invokes the core application that actually performs the processing.

The core application writes any output destined for the client to the output file (also specified in the profile file). Just before the server application terminates, it closes the output file, causing the web server to send its contents (an HTML page) back to the client's browser.

An Application Example

This simple "Hello World" example is designed to create a console application on Microsoft NT 3.51 server running O'Reilly and Associates Website server. This example assumes you have Microsoft Visual C++ version 4.x. (Instructions for building the application are included with the source code.) The reason this is a console application is because there's no need for WinCGI to interact with a GUI. You should easily be able to extend the idea to just about any other server based application desired.

The primary procedure in this application is WinCGI_application, shown in part in Listing 1. There are two things I want to point out about the cWinCGI.Send functions. First, all cWinCGI.Send invocations require CString arguments, hence the conversion of each string literal to a CString type. Second, the "Content-type" argument in the first statement is required, as is the empty string in the second "Send" statement. These two statements supply the header for an HTML page. The third cWinCGI.Send procedure call returns the visible text back to the client's browser.

Although the example doesn't show it, WinCGI can also utilize HTML forms processing. An HTML page containing a form can be made part of the WinCGI server application and sent to the browser when an HTTP "GET" method is received (i.e. when the client first invokes the WinCGI server application). The method type is contained in the member variable cWinCGI.CGI_RequestMethod, where possible values are "POST" and "GET". This HTML page would be embedded with form fields and the "POST" method tag so that when it was submitted back to the web server, the server application could determine that it was a "POST" method and branch to another part of the application, supposedly to store the data.

Conclusion

This implementation of the WinCGI interface takes advantage of the object-oriented environment and speed of Visual C++. Another advantage of this interface to WinCGI is that any Visual C++ code can be used. All of the functionality you would expect is there (DAO for example) and all in the environment that you are used to (i.e. Developer Studio). Debugging is quite easy since most web servers will allow the .INI files to accumulate, allowing you to run the exact profile against the code and find out where the error occurred. These features provide a rapid application development environment which is key to software success. o

Mark Wheeler is a Senior Software Engineer at Claritas Inc. and is currently pursuing a Ph.D. in Computer Science at Syracuse University. He may be reached at mwheeler@clarityconnect.com.