Lessons by Jon

CGI Applications and MacHTTP

This guide to CGI applications for MacHTTP should be usable for anyone, even if you have no previous programming experience. Of course, you shouldn't expect miracles (at least not here). These lessons will make things easier for most people, but they still require work and study. You will only get out of this what you put in, plus about 12%. Take your time, think about what is said here, challenge anything that seems to be wrong (its not unthinkable that I get something wrong here) and do things in order as much as possible.

NOTE: This information is relevant only for MacHTTP on Macintosh computers. While CGI applications exist for most platforms, the method of communication between CGI applications and the servers on various platforms differs so CGI applications cannot be used across platforms. There is one kind for Unix, another for Macintosh, and yet another for any other types of computers you might be using.

What does CGI mean?

CGI stands for "Common Gateway Interface". There. Now you know. The CGI definition provides a standard for external gateway programs to interface with information servers such as MacHTTP. When MacHTTP passes information off to a CGI application it not only sends the data from the user, but it also includes useful information about the transaction such as the client address, username, and password. I'll write more about his later, but for now you can read this Overview of CGI from NCSA.

How They Work - The Basics

When trying to understand how CGI applications work, the first thing to learn is the difference between the server and the client. MacHTTP is the server. Mosaic, MacWeb, and NetScape are all clients. When a user clicks on a link, the client send a request to the server to see the file that the link points to. Here's an example of some typical client-server interaction with an HTML page:
  NetScape: I want to look at the page with the URL 
            http://www.uwtc.washington.edu/UWHome.html
  
  MacHTTP: Ah!  That's one of my pages.  Here is all 
           the data from the URL you sent.  I'm sending 
           it as text.
  
  NetScape: Ah!  I see the text begins with an HTML tag 
            that I recognize.  I'll interpret this as HTML 
            then and display it correctly for my user.
  
  MacHTTP: I couldn't care less how you display it.  I'm 
           done dumping the data so goodbye.
As you can see, the client and the server both have their responsibilities in the interaction. The server decides what the client is requesting and how to feed it back to the client. The client decides what to do with what is returned to display it for the user.

When the user requests a URL that involves a CGI application (like clicking on a map, submitting a form, or many other things), the interaction is a little different because there is also interaction between the server and the CGI. Let's take a look now at the conversation that might occur between a server and client when handling a map click (assuming they speak English, of course).

  User: Hmmmm.  A map of Washington state.  There's a star in 
        the upper right-hand corner.  I wonder what that's 
        for.  Let's click on it.

  NetScape: Let's see, that click was at 287,48.  I'll add 
            that to the URL that was given with the map and 
            send it back to the server.

  MacHTTP: Hey, someone sent me a URL with some extra data. 
           That URL is for a CGI application on this machine. 
           Well I'll just send an AppleEvent to that CGI 
           application with the data enclosed in the post_args 
           argument.  I'm glad I don't have to do anything to 
           the data myself.

  CGI app: Finally, an AppleEvent!  Let's see, first I 
           decode the information in the post_args argument. 
           Now I can use these map click coordinates to figure 
           out what page to return to the client.  Here it is - 
           I'll send the server an AppleEvent reply, 
           containing the URL for the new page and a code to 
           redirect the client to that page.
  
  MacHTTP: Finally.  I've been waiting for this AppleEvent reply. 
           This code says I should redirect the client to this 
           other page instead.  I'll send back the new page then.
  
  NetScape: Here comes another HTML page.  Better display it 
            nicely for my user.
  
  User: Republic, Washington? I've never even heard of that
        place before!
Well, that was a bit long, but it should give you an idea of the complex interactions that go on when you're using a CGI application. There are a couple of important points to remember from the above nonsense:

How CGI's Work - Advanced

This may turn into an entire page by itself, but for now its not really necessary.

Synchronicity

Not too long ago MacHTTP was only able to handle CGI applications synchronously. That meant that every time a CGI application was called, MacHTTP waited for a response. Therefore, noone else could get any information until that CGI application finished and returned some information. A very slow connection, sending lots of data to a slow application, could tie up your server for several minutes or cause an error when MacHTTP got tired of waiting.

Later, Chuck added the ability to run the CGI applications asynchronously. This meant that MacHTTP didn't have to wait uselessly while the CGI application ran. Instead, it passed an AppleEvent to the application then went on processing other things until a reply was received. To distinguish between the two, MacHTTP now recognizes two different file extensions. ".cgi" means the file should be handled synchronously and ".acgi" means to handle it asynchronously. The latter is almost always preferable (actually, I can't think of a reason not to use the asynchronous mode), but a well-written CGI application can run either way. The key is to remember that AppleEvents might be queued up in your CGI application while it is processing the current event. Therefore, you want to design the application so it doesn't quit immediately after processing an event or it might miss the next one. Instead, give it time to test to see if there is another event queued up.


How To Write a CGI Application

You can write a CGI application in any language you want, it need only be able to accept and return the proper AppleEvent information. Chuck Shotton has provided an example in C that handles the "srch" event. There is also a MacPerl droplet that can be used as a CGI application. However, for most of us, the easiest way to write a CGI application is by using AppleScript. Luckily for you, I have a tutorial on writing CGI applications using AppleScript. Someday I will also have one on writing CGI applications using C, but that will have to wait until I actually write one.

After you have finished those lessons, you may want to take a look at a real-world solution using CGI applications, Form Processing.


Jon Wiederspan
Last Edited: December 11, 1994