This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
|
Porting Windows CGI Applications To ASP Robin Ren |
Although Active Server Pages are defining the new Web server specifications, thousands of CGI scripts are still creaking along. Converting your scripts to ASP can be well worth a bit of effort. |
The Microsoft Internet Information Server 4.0 technology in Windows NT® Server is capturing a lot of attention these days for its flexibility, robustness, and great performance. So you would think the entire world, or at least the folks hosting their Web sites on Windows NT-based boxes would convert to IIS 4.0 overnight, right? Wrong! They already have a working Web site in which they have invested time and money. Unless there is a way to port the existing applications to the new paradigm without having to rewrite everything from scratch and retest apps, those people will not convertat least not any time soon.
There is a way to make the leap without too much hassle. CGI2ASP is a framework for porting programs written in Visual Basic® using one of the most popular old paradigm Web programming interfaces, Windows CGI (not actually part of Microsoft Windows, but an O'Reilly & Associates product), to component-based ASP applications with virtually no change to the existing Visual Basic®-based code. The basic function of a Web server is to take requests from and send responses to Web clients through the HTTP interface. Most of the Web pages on the Internet today are static HTML files sitting on the server's hard disk. All the server has to do is find the right file and send it to the client using HTTP. But more and more commercial Internet and company intranet sites are deploying sophisticated Web applications that rely on dynamic Web pages generated on the fly. To churn out these dynamic pages, the Web server usually needs either in-process or out-of-process help from other programs. These helper programs typically perform functions such as parsing user input and formatting output into HTML or something the client can understand. Sometimes helper programs need to perform more complicated tasks such as accessing back-end databases, applying business rules, and communicating with other servers. One of the most popular ways of generating dynamic Web pages in Windows is the Windows CGI programming interface, originally created by Robert Denny as part of the HTTPd Web server running on Windows 3.1. Now part of the O'Reilly catalog of products, Windows CGI is supported by several major Web server products on the Windows NT platform, including O'Reilly's Web Site (the successor to the HTTPd shareware program) and Netscape FastTrack and Enterprise Servers. Windows CGI gained its popularity because it uses Visual Basic. Armed with some basic HTML knowledge, a programmer using Visual Basic can be turned into a Windows CGI developer in days.
How Windows CGI Works
|
Figure 1: Windows CGI Architecture |
Several points are worth noting here. First, the Windows CGI programs are standalone, out-of-process, single-threaded executable files, usually written in Visual Basic. This kind of one-thread-per-process programming model can trace its origin to its CGI counterpart on the Unix platform, where processes, not threads, are the basic unit of execution. Under a multithreading operating system such as Windows NT, each process runs in its own memory space, and having many executable programs running on your Web server at the same time is inefficient.
Second, the Web server and Windows CGI programs communicate with one another through input and output files. The input file uses the Windows INI file format. Microsoft provides special Win32® API calls to allow quick access to INI files. In the early days when there was no COM or DCOM, passing information back and forth using INI files was a great idea. The performance was remarkable since there was no better alternative. Visual Basic also has no concept of standard input/output pipes (stdio), so file-based I/O is just about the only way to feed it data. However, if you are running a popular site, your hard disk access speed can quickly become a serious bottleneck. Last but not least, the architecture of the Windows CGI interface demands that the Web server and Windows CGI programs run on the same computer. There is no easy way to distribute workload to other servers on the network. This means your Web site will not be very scalable as your company grows.
Windows CGI Framework
I've created a simplified Windows CGI intranet phone directory and reduced it to its simplest form. This sample retains some of the basic characteristics of Windows CGI applications. It uses environmental variables and the GetSmallField function to read the input and uses the Send function to write to the output. The sample app uses Data Access Objects (DAO) to access a back-end Jet database. The data-access capability is one major reason why most Windows CGI applications were developed in the first place. Like many other Windows CGI applications, this one controls its flow, or the order of different screens users see in their browsers, by sending different pages depending on whether the request method is GET or POST. The Visual Basic project window contains the two modules included in the project: the Windows CGI framework and the custom code module (see Figure 3). The project is compiled into an executable file, search.exe, and put into a Windows CGI-enabled folder on the Web server. The user points their browser to this EXE file to use the application. |
Figure 5: User Input Form |
Figure 4 shows the code contained in the custom code module. The starting point of the custom code module is the CGI_Main sub procedure. CGI_Main first looks at the CGI_RequestMethod environmental variable. If the request method is GET (the first time the user requests this application), CGI_Main calls SendShortForm to display an online form (see Figure 5). The user fills out the form and submits the request to the same URL using the POST method. This time CGI_Main knows it is a POST request by reading CGI_
RequestMethod. It calls SendResponse to read from the back-end database and sends the result to the Web server, which relays it to the user, as shown in Figure 6.
Repackaging Your Code Into Components
|
Figure 6: Search Result Page |
How do you turn your existing custom Visual Basic-based code into components? Repackage it! Remember when I discussed an interface between the Windows CGI framework and the custom code? This interface is composed of public CGI environmental variables and several functions, including GetSmallField and Send. You can replace the Windows CGI framework with a new CGI2ASP framework. This new framework will preserve the interface with your custom code, but it also knows how to communicate with ASP pages.
Figure 7 shows the architecture of a Windows CGI- converted ASP application running under IIS 4.0. The ASP page communicates with the CGI2ASP component through a Request object and an output string variable. Request is an ASP built-in object, containing standard CGI environmental variables, user form inputs, and much more. Inside the CGI2ASP component, the new CGI2ASP framework is responsible for reading the input from the Request object and writing to the output string. It is easy to see why this component-based ASP architecture solution is superior to Windows CGI. First, you run the component in the same process as the Web server itself, which eliminates a lot of overhead associated with spawning and destroying a new process every time a user accesses a Windows CGI application. Furthermore, using the Request object and the output string variable is much more efficient than using the input and output files, since no disk access is required. |
Figure 7: CGI2ASP Application Architecture |
In IIS 4.0, every application runs under the control of the Microsoft Transaction Server technology. MTS oversees the life cycle of each component. When a component is released by an application, it's not destroyed. Instead, MTS deactivates it, recycles it, and prepares it for just-in-time activation again. MTS also provides the flexibility of running certain applications in separate memory spaces, so if one application crashes, it will not bring down the whole Web server. Please note that even when an application runs in a separate memory space from the Web server, all the components of that application will still run in-process in that memory space while being monitored and recycled by MTS. This is very different from Windows CGI, where a process is created and then destroyed with every request to that application.
MTS makes it possible to run components on other servers using DCOM. Therefore you can host a Web site on one server, and your ASP pages can activate and use components running on another server. This gives your Web site more flexibility and scalability. MTS also lets the components share expensive resources such as database connections more efficiently through resource pooling. You can expect to get a significant performance boost by repackaging your Windows CGI custom code, which connects to a Jet database, into components running under IIS 4.0 and MTS technologies.
The New CGI2ASP Framework
|
Figure 9: Project Properties |
Let's go through the steps to port my sample intranet phone directory, a Windows CGI application, into component-based ASP pages.
The first step is to open a new Visual Basic ActiveX DLL project. Make sure to use the Single Threaded threading model under Project Properties (see Figure 9). I'll explain why later. You may also need to add a reference to the Microsoft Active Server Pages Object Library in the Project References window. Next, add the CGI2ASP framework files, cgi2asp.bas and interface.cls, and your custom code modules (custom.bas here) to the project (see Figure 10).
The next step is to compile the project into a DLL component. If the component will run on the same machine where it was created, Visual Basic automatically registers it. If it runs on a remote machine before the component is ready to use, you will have to register it using either the MTS explorer or a Visual Basic setup routine. The last building block of the application is an ASP page. In the sample, the ASP page does nothing other than create an instance of the component, pass the Request object to the component, get the result back, and relay it to the client. Here's the ASP page for the sample phone directory, search.asp: |
|
The user will notice no difference in the application after the paradigm shift, except that they need to point their browser to search.asp instead of search.exe. The search result will be identical to the one shown in Figure 6.
Debugging CGI2ASP Components
|
|
statement to quickly isolate a problem when something doesn't work. Unfortunately, this trick no longer works when you try to debug the newly converted components. If you are porting existing applications, try to finish all your debugging in the Windows CGI environment before you try to migrate them. If you are developing a new application, you should not be using this CGI2ASP method at allgo straight to ASP.
If you really have to debug your CGI2ASP application, you can do it using the standard Visual Basic-based method of debugging components, which is to write a small client and step through the execution inside the Visual Basic environment. As I mentioned before, once a component is loaded into IIS, it stays loaded so it can be reused. This creates a problem if you need to make any changes to the component but do not want to stop and restart the Web service. Fortunately, with IIS 4.0 it is possible to unload an application along with all its components if the application is running in a separate memory space. The rule of thumb is that when you are developing and testing a new application, it makes sense to run it in a separate memory space from the server process. Once the application is fully debugged, you can decide whether to run it in the same process as the Web server.
More Performance and Scalability
Conclusion
|
From the October 1998 issue of Microsoft Interactive Developer.