Lessons by Jon

Basic CGI Application

This lesson will cover the basic concepts in creating a CGI application for use with MacHTTP by using AppleScript. It will cover:

Script1.txt - A Basic CGI

Here is the entire script for this lesson. The comments have been removed so you see only the lines that actually get compiled. The full script, including comments and special characters, is in the archive with the name "Script1.txt".
property crlf : (ASCII character 13) & (ASCII character 10)
property http_10_header : "HTTP/1.0 200 OK" & crlf & "Server: MacHTTP" ¬
    & crlf & "MIME-Version: 1.0" & crlf ¬
    & "Content-type: text/html" & crlf & crlf

on «event WWW½sdoc» path_args ¬
   given «class kfor»:http_search_args, ¬
      «class post»:post_args, «class meth»:method, ¬
      «class addr»:client_address, «class user»:username, ¬
      «class pass»:password, «class frmu»:from_user, ¬
      «class svnm»:server_name, «class svpt»:server_port, ¬
      «class scnm»:script_name, «class ctyp»:content_type
	
   set return_page to http_10_header ¬
      & "<HTML><HEAD><TITLE>Unprocessed Results</TITLE></HEAD>" ¬
      & "<BODY><H1>Unprocessed Results</H1>" & return ¬
      & "<H4>http_search_args</H4>" & return & http_search_args
   set return_page to return_page & return ¬
      & "<H4>post_args</H4>" & return & post_args & return ¬
      & "<H4>method</H4>" & return & method & return ¬
      & "<H4>client_address</H4>" & return & client_address & return
   set return_page to return_page & return ¬
      & "<H4>from_user</H4>" & return & from_user & return ¬
      & "<H4>server_name</H4>" & return & server_name & return ¬
      & "<H4>server_port</H4>" & return & server_port & return
   set return_page to return_page & return ¬
      & "<H4>script_name</H4>" & return & script_name & return ¬
      & "<H4>content_type</H4>" & return & content_type & return ¬
      & "<H4>username</H4>" & return & username & return ¬
      & "<H4>password</H4>" & return
   set return_page to return_page ¬
      & "<I>Results generated at: " & (current date) ¬
      & "</I>" & "</BODY></HTML>"
   return return_page
   
end «event WWW½sdoc»
There are several special characters used in this AppleScript that you should know about:
«
THIS IS NOT TWO LEFT BRACKETS. It is a special character used to mark the beginning of data.
»
The same thing, only marking the end of data.
¬
The "continuation" marker. This indicates that the next line is to be considered part of the current line. You can use this to break up very long lines.
½
This should be a capital Omega character. Unfortunately, the font I use in NetScape makes it look like a capital Pi. Either way, look at the archived script using the Script Editor and you will see how it really should look.

Step By Step

Let's walk through this one line by line.
   property crlf : (ASCII character 13) & (ASCII character 10)
   property http_10_header : "HTTP/1.0 200 OK" & crlf & "Server: MacHTTP" ¬
      & crlf & "MIME-Version: 1.0" & crlf ¬
      & "Content-type: text/html" & crlf & crlf
These two lines are used to create variables that are needed when a CGI application will be returning an HTML document. By creating and setting these variables outside of the AppleEvent handler, they persist as long as the CGI application stays open, thus saving some miniscule amount of processing when successive forms are processed. For more information on the property command, see your favorite AppleScript book.

The first line creates a variable called crlf and sets it to be equivalent to a carriage return and a linefeed (thus the name, crlf). This combination is used to end lines in the header of an HTTP transaction. It is very important!
The second line creates a variable called http_10_header. This is the standard header (for HTTP version 1.0) that is returned in a transaction between an HTTP server and client when the transaction is successful. In this case you are returning code "200 OK", which means that an actual file is being returned. If you don't build a proper header, the client won't know what to do with the text you are returning. MacHTTP doesn't know what is going on, so it just assumes you are going to make the header.

on «event WWW½sdoc» path_args ¬
   given «class kfor»:http_search_args, ¬
      «class post»:post_args, «class meth»:method, ¬
      «class addr»:client_address, «class user»:username, ¬
      «class pass»:password, «class frmu»:from_user, ¬
      «class svnm»:server_name, «class svpt»:server_port, ¬
      «class scnm»:script_name, «class ctyp»:content_type
This line is the key to the entire script. I've broken it up across several lines here so it will display properly, but it really is just one long line in your script. This line defines a handler that takes in an AppleEvent of type "sdoc" with a number of arguments (information passed to it). The "sdoc" event is the one that MacHTTP sends when it is communicating with CGI applications. It also can send another event, the "srch" event, when it is using the "Search" method, but we're not going to cover that here. Note: there are several special characters used in this line. The markers around "event WWW½sdoc" are not double brackets, but special characters (ASCII 171 and 187). In addition, the character between "WWW" and "sdoc" should be a capital omega sign (look at the archived AppleScript to see what I mean). These special characters are incredibly important! Unfortunately, they are usually stripped out when you try to send an AppleScript as text in e-mail or news postings and not all of the characters are available for WWW client viewing. We'll do the best we can, though.

There are several arguments passed to your CGI application, with more being added every year. Most of these are not used in every script, but they're very handy when you need them. It doesn't hurt to list every argument here so I recommend that you use this line in every script, just to be sure you don't miss any. The arguments are:

http_search_args
The data passed in when using the GET method or when "$" is appended to the URL of the CGI application. This argument will be empty when you're using the POST method. You can actually use both at once, though, as you might see in a later lesson.
post_args
The data passed in when using the POST method. Contains all of the information that was typed into the form.
method
Tells whether GET or POST was used so you know which argument to use.
client_address
The IP address of the client making the request.
username
The username given by the client (if you're using the security features).
password
The password given by the client (if you're using the security features).
from_user
More information about the user.
server_name
The name of the requesting server (which MacHTTP you're using).
server_port
What port the server is running on.
script_name
The name of the CGI application that is running.
content_type
MIME content type of post_args
Generally, the only argument you care about is post_args, since that contains all of the data that the user entered. All of the others are generated automatically by MacHTTP. If you decide not to list all of them in your AppleScript, or if you forget one, it will not cause any problems. Any not listed are ignored.

The next lines are the actual processing part of this script.

   set return_page to http_10_header ¬
      & "<HTML><HEAD><TITLE>Unprocessed Results</TITLE></HEAD>" ¬
      & "<BODY><H1>Unprocessed Results</H1>" & return ¬
      & "<H4>http_search_args</H4>" & return & http_search_args
   set return_page to return_page & return ¬
      & "<H4>post_args</H4>" & return & post_args & return ¬
      & "<H4>method</H4>" & return & method & return ¬
      & "<H4>client_address</H4>" & return & client_address & return
   set return_page to return_page & return ¬
      & "<H4>from_user</H4>" & return & from_user & return ¬
      & "<H4>server_name</H4>" & return & server_name & return ¬
      & "<H4>server_port</H4>" & return & server_port & return
   set return_page to return_page & return ¬
      & "<H4>script_name</H4>" & return & script_name & return ¬
      & "<H4>content_type</H4>" & return & content_type & return ¬
      & "<H4>username</H4>" & return & username & return ¬
      & "<H4>password</H4>" & return
   set return_page to return_page ¬
      & "<I>Results generated at: " & (current date) ¬
      & "</I>" & "</BODY></HTML>"
These lines create a variable called return_page which will hold the entire text that we plan to return to MacHTTP when we're finished. return_page is set to include:
  1. the HTTP 1.0 Header that we made earlier (http_10_header)
  2. the tags needed to start a nice HTML document (HTML and HEAD)
  3. a TITLE for the page
  4. the HEAD end tag and BODY tag (separates the header information from the body of the page)
  5. a level 1 header to display
  6. level 4 headers with variable names followed by the contents of those variables.
  7. the BODY and HTML end tags
If you don't understand what it will look like, try the form later on this page. It will return this information and you can use the "View Source..." option on your WWW client to see what was returned.
   return return_page
This line returns the contents of return_page to MacHTTP. As mentioned in the pseudo-dialog in the overview, MacHTTP will not process this returned information at all, except to pass it along to the WWW client. The client will then display it properly as an HTML page. You can see now why we had to build the whole header ourselves (or the client wouldn't know what was being sent to it).
   end «event WWW½sdoc»
This is the last line of the handler. It tells AppleScript that the handler is finished, we're all done handling the AppleEvent that was sent. If there was an error and nothing was returned by this point, then MacHTTP will hang up waiting for information to be returned. This will usually result in an error in the MacHTTP log which says "Error -1701". We'll address this problem in later lessons.

Test the Script

I have compiled the script above on my own server, with an accompanying form. Try this form out with a variety of WWW clients if you can. You may notice that each client returns slightly different information to the user. The information that is returned has not been processed at all, so it is useless for any real work.

Wrap It Up

Now you have everything you need to begin building your own CGI applications for use with MacHTTP forms, maps, or whatever. There are a few important items to reiterate, though:
  1. Always return information to MacHTTP. If you can return an HTML document with useful feedback for the user, that is best. Even straight text can be returned, though.
  2. Don't count on every client returning exactly the same information. There is a lot of leeway still in what the clients are to do, especially in the newer features (such as forms support).
  3. MacHTTP provides lots of information in the various arguments. You don't have to use them all, though. Some of them will occasionally be empty if they don't apply (like username and password).
  4. Be sure to read Chuck Shotton's notes that accompany each beta release of MacHTTP. They include updates on the variables that MacHTTP returns.
  5. Get a good AppleScript book! Apple's free stuff is not sufficient.

[Go back to Tutorial Index]

Jon Wiederspan
Last Edited: November 26, 1994