Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Web Development

CGI and AppleScript


SP95: CGI and AppleScript

Cal is founder of Main Event Software, publisher of the Scripter development tool. He can be reached at [email protected].


One of the best-kept secrets about the World Wide Web is the extent to which the Macintosh is used as a development platform. A survey of 13,000 Web users conducted earlier this year by the Graphics, Visualization, and Usability (GVU) Center at Georgia Tech University found that the MacHTTP server software is the second-most popular server package. MacHTTP has 20.8 percent of installations, trailing NCSA (38.6 percent), but ahead of CERN (18.5 percent), and significantly ahead of most other servers. (The study was conducted in April and May of this year, and focused on a number of topics, not just servers.)

In this article, I begin by discussing the principal aspects of the Macintosh as an Internet platform, and then describe how you can use the AppleScript language for writing CGI applications that run on Macintosh servers, and end with a quick look at alternatives to AppleScript.

Macintosh Servers

The current situation is highly subject to change, of course; competition among desktop server packages has escalated several notches recently, with the release of a slew of Windows-based server products over the summer. Nevertheless, it is worth reminding those who discount the Mac as an Internet platform that MacHTTP was the third Web server ever written, after NCSA and CERN (both of which run on UNIX only).

MacHTTP is shareware and available at a number of ftp repositories on the net. Recently, Chuck Shotton, the author of MacHTTP, revamped the program and turned it into a commercial product called "WebStar,'' marketed by StarNine Technologies (Berkeley, CA). The author claims that WebStar is about four times faster than MacHTTP, and can handle 500,000 hits per day on a PowerMac 7100. Two sites at Apple currently running WebStar are www.apple.com and quicktime.apple.com. According to Shotton, MacHTTP and WebStar together comprise 66 percent of the "commercial Web-server market."

Whether you use MacHTTP or Webstar, you can create CGI-style applications that don't rely on the cumbersome UNIX-style CGI interface, as defined by the NCSA and CERN servers. The advantage of traditional CGI is that it is supported in many servers on many platforms, not just NCSA and CERN. One disadvantage, at least on the Mac platform, is that it is not as effective a mechanism for interapplication communication (IAC) as using native facilities--namely, Apple Events.

Apple incorporated Apple Events into System 7 as an efficient and flexible means for applications to communicate with each other. MacHTTP and WebStar use Apple Events for a CGI-style interface between server and back-end processing. WebStar also uses Apple Events to implement remote-administration facilities, which allow the site administrator to monitor multiple server machines simultaneously from a single workstation: examining outputs, memory usage, connection status, and so on. The Apple Event-based CGI facility lets you write CGI applications using any scripting language that is compliant with Apple's Open Scripting Architecture (OSA). OSA defines a standard on the Macintosh that lets different languages access the same system-level facilities. This includes Apple's own AppleScript language, as well as languages from third parties such as UserTalk, or simple macro packages such as QuicKeys.

Of course, you can still write CGI applications using the traditional CGI facility. With MacPerl, the Macintosh implementation of the Perl scripting language, it is possible to port scripts originally written for UNIX servers, as long as they do not rely on UNIX-specific operating system calls or call UNIX-specific utilities. But in many cases, you are better off rewriting the program using an OSA-compliant language. The increased flexibility and performance make it worth your while.

About AppleScript

The AppleScript language in many ways resembles HyperTalk, the language used in Hypercard, except that it is not designed just for user-interface-intensive single applications. Instead, it is an object-oriented language that integrates multiple applications and interacts with system-level facilities in the Macintosh operating system. The AppleScript package from Apple consists of a language, a system-software extension, a simple scripting editor, and language additions. AppleScript is now a standard component of System 7.5, and therefore available to all users.

Using AppleScript, you can design work-flow applications that govern data flow from one program to another. If a program has been designed to be scriptable, AppleScript (and other OSA languages) has access, at a fine-grain level, to a range of object types within the application. For example, in the QuarkXPress page-layout program your scripts have access to specific paragraphs or graphics; in the FileMaker Pro database program, you can manipulate individual database records and fields. There are over a hundred more scriptable applications, including WebStar, Eudora, Netscape Navigator, and the MacOS Finder itself. As a result, power users and programmers can quickly put together end-user scenarios, be they simple or complex.

An Apple Event is a message (corresponding to an action) sent between two applications or between a scripting system and an application. The code in the target application is known as the "event handler." In a CGI communication between server and back-end application, the CGI arguments are represented by parameters to the Apple Event, and are identified by 4-byte IDs (see Table 1). The CGI application returns data by providing a "reply" to the Apple Event.

Within an AppleScript CGI script, you can process data or instructions entered into a form. You can initiate a database search, assemble text, and produce charts or graphics--all driven from user choices. In addition, you can send e-mail, assemble HTML pages on the fly, and deal with run-time errors.

Integrating multiple applications is accomplished through application-specific vocabularies housed within scriptable applications. A vocabulary extends AppleScript to include new terms representing actions and objects specific to the particular application. Together with AppleScript's built-in terms, you write scripts by putting together sentences that often resemble grammatically correct, English-language sentences rather than traditional C code.

A script consists of properties (the data) and handlers (the methods). AppleScript variables and properties are dynamically typed --their types are not declared and can change from statement to statement. Properties are initialized when the script is first run, and are updated each time a script completes. Example 1(a) shows a script that increments its counter every time it is run. Handlers (which either respond to an Apple-Event message or are analogous to subroutines in other languages) use one of two methods of specifying parameters: positional and keyword. For CGI use, the keyword form is employed.

An AppleScript CGI

In CGI scripts, the message sent by the Web server is handled by a "raw event handler," for which there are no terminology equivalents for the verb and parameter keywords. AppleScript provides a mechanism for specifying these terms using their 4-byte code values. In a declaration for a keyword handler, raw event and parameter codes are enclosed in "chevron" or "French quote" << >> characters. You don't need to specify all the CGI parameters in your handler declaration, only the ones you need. Example 1(b) shows the counter-incrementing script as a CGI program.

Moving to a more interesting example, suppose you maintain a regularly updated database of information that includes a table of numeric values, and you want to provide, on demand to your Web users, the table in the form of a chart. For this example, I'll use three familiar applications, FileMaker Pro (to hold the data), DeltaGraph Pro (to make a chart of the data), and Clip2Gif (to store the chart in a GIF file). You can use redirection ("Location" in the reply header) to point the Web server to the GIF file. The resulting CGI program is shown in Example 2.

AppleScript provides an interesting mechanism for handling errors known as a "try block," which resembles the TRY...CATCH construct in C and some other languages. Your regular application code goes in the first part of the try block; if an error occurs, the error-handling code in the second part of the try block is invoked. Example 3 shows a simple error handler that generates an HTML page by concatenating a bunch of strings.

Other Tools and Alternative Languages

There are a variety of small tools to simplify processing the data passed to an AppleScript CGI program by MacHTTP. These small tools are AppleScript scripting additions, colloquially referred to as "osax" in the singular, and "osaxen" in the plural. An osax extends the AppleScript command set by providing additional verb and parameter keywords to the vocabulary. Scripting additions work not just with AppleScript but with any OSA-compliant language.

Most CGI programs use HTML forms to pass in fields of data using particular formats. Various osaxen are used to process this data. For example, there is an osax for decoding URLs, and one that splits up the arguments into individual chunks (the Tokenize osax). There is also the "parse CGI" osax that combines many of the commonly used tasks in implementing CGI programs. The parse CGI osax can be used to decode, parse, and access the HTML form information that is passed in to an AppleScript CGI. It combines the functionality of the "DePlus," "Decode URL," and "Tokenize" osaxen to handle incoming HTML forms and field data.

How do you create, edit, and debug AppleScript code? As part of System 7.5, Apple provides a very simple Script Editor, offering basic editing functions. This editor allows you to write and edit text, and turn the text into scripts. There are also third-party tools, such as Scripter and FaceSpan.

Scripter, from my company, Main Event Software (Washington, DC), is an authoring and development environment that includes point-and-click access to the vocabularies in dictionaries of scriptable applications, an enhanced scripting editor, and integrated debugger of considerable depth, specifically designed for AppleScript. ScriptBase, also from Main Event, provides an object database for system-wide storage of values and objects that may need to be accessed from scripts.

FaceSpan, from Software Designs Unlimited of (Chapel Hill, NC), is a design tool for visual-interface-intensive applications, containing UI elements such as buttons, text boxes, lists, popups, menus, and gauges. FaceSpan applications can be built using AppleScript or another OSA-compliant language, such as Usertalk or QuicKeys.

Usertalk is the language used in the Aretha scripting environment from Userland Software. Aretha (Palo Alto, CA), formerly called "Frontier," actually predates AppleScript and was designed with similar goals: to provide a system-level facility for integrating applications. Usertalk is now OSA-compliant, so AppleScript and Usertalk code can be used interchangeably in the same script. Usertalk is considered by some to be more difficult to learn. It offers a multithreaded environment with an object database that can store both application data and scripts. The Aretha package used to be a commercial application but its author, Dave Winer, has recently made it free. The support is now handled by volunteers.

Conclusion

This whirlwind tour of scripting on the Macintosh platform gives you some idea of the facilities available for developing internetworked applications. As you explore further, you'll find that the tools have a flexibility and power that cannot be emulated on other platforms.

References

Apple Computer. Inside Macintosh: Interapplication Communication. Reading, MA: Addison-Wesley, 1994.

--------. AppleScript Language Reference Guide. Reading, MA: Addison-Wesley, 1994.

Goodman, Danny. Danny Goodman's Complete AppleScript Handbook. New York, NY: Random House, 1994.

Two internet mailing lists, available via [email protected], are applescript-users (for writers of scripts), and applescript-implementors (for developers of scriptable apps).

Table 1: The parameters for the Apple Event WWWdoc, a custom event sent by the Web server.


<b>
Code    Suggested name     Description  </b>
----    path_args          Data in URL following "$"
kfor    http_search_args   Data in URL passed using GET method, or
                          following "?"
post    post_args          Data in URL passed using POST method
meth    method             Which argument to use: GET (search args)
                          or POST (post args)
addr    client_address     The client's IP address (or DNS)
user    username           The client's user name (if using security)
pass    password           The client's password (if using security)
frmu    from_user          Additional user information (often an
                          e-mail address)
svnm    server_name        The server's name (MacHTTP or WebSTAR)
svpt    server_port        The server's port
scnm    script_name        The URL sent to the server
refr    referer            The URL the client was viewing before
                          the current one
Agnt    user_agent         The client software's name
ctyp    content_type       MIME content type of post args
Kact    action             Method of calling CGI: PREPROCESSOR,
                          POSTPROCESSOR, CGI, or ACGI
Kapt    action_path        If present, path to file from disk root
                          (used for ACTIONS), defaults to
                          script_name
Kcip    client_ip          The client's IP address (present even if
                          NO_DNS is false)
Kfrq    full_request       Full text of client's request

Example 1: (a) A simple script that increments a counter; (b) the equivalent script as a CGI program.


(a)
property counter : 0
on run
        -- The run handler is executed each time
        -- a script is run or launched.
    set counter to counter + 1
end run

(b)
property counter : 0
-- The run handler is executed when the CGI is
-- launched. But if the CGI is already running when
-- the special Apple event fires, the run handler isn't run.
on run 
    -- This handler is optional in a CGI
    -- If you have any initialization code, it goes here
end run
-- This is the CGI Handler receiving the arguments from the Web server.
-- This handler has the same form as any other handler.
-- In this example we only handle five of the 18 CGI parameters,
-- the direct parameter plus four others.
on <<event WWWdoc>> path_args ¬
    given <<class post>>:post_args, <<class meth>>:method, <<class addr>>:client_address
    -- CGI body goes here
    set counter to counter + 1
end <<event WWWdoc>>

Example 2: A CGI program that generates a chart on the fly from a database.


property crlf : (ASCII character 13) & (ASCII character 10)
property reply_header : "HTTP/1.0 302 FOUND" & crlf & ¬
    "Server: WebSTAR/1.0 ID/ACGI" & crlf & ¬
    "Location: http://www.your.site/home.html" & crlf & ¬
    "URI: http://www.your.site/home.html" & crlf & ¬
        crlf
-- This is the CGI Handler
on <<event WWWdoc>> path_args ¬
    given <<class post>>:post_args,  ¬
        <<class meth>>:method, ¬
        <<class addr>>:client_address
        -- Interpret CGI arguments. Here you would obtain the
        -- user's choices from the arguments.
        -- After this, the next step is to retrieve data from database
    tell application "FileMaker Pro"
        Open alias "Macintosh HD:Databases folder:Web DataBase"
        set numRecs to Count of Record in Document 1
        -- Make tab-delimited data for Deltagraph
        set dataString to "Month" & tab & "Amount" & return
        repeat with i from 1 to numRecs
            copy dataString & Cell "month" of Record i ¬
                                & tab & Cell "amount" of Record i ¬
                                & return to dataString
        end repeat
    end tell
        -- Create the desired chart
    tell application "Deltagraph Pro"
        Data dataString
        Plot Options Text Font "Palatino" Text Size 12 ¬
                        Colorstyle "blue"
        Set Axis Lengths for X 100 for Y 100
        Output PICT
        set dataChart to Plot chart chartType
    end tell
        -- Make the GIF file for the redirect
    tell application "clip2gif"
        save dataChart as GIF in file "Macintosh HD:home.html"
    end tell
        -- Return the reply data to the server and exit the CGI handler
    return reply_header  -- reply and exit
end <<event WWWdoc>>

Example 3: A simple error handler.


property crlf : (ASCII character 13) & (ASCII character 10)
property http_header : "HTTP/1.0 200 OK" & crlf ¬
    & "Server: WebSTAR/1.0 ID/ACGI" & crlf ¬
    & "MIME-Version: 1.0" & crlf & "Content-type: text/html" ¬
        & crlf & crlf
-- The CGI Handler
on <<event WWWdoc>> path_args ¬
    given <<class post>>:post_args, ¬
    <<class meth>>:method, ¬
    <<class addr>>:client_address
    -- Enclose your CGI code in a "try/on error/end try" construct
    try
        -- Put the body of your CGI here.
    on error errNum number errMsg
        -- If there's an error, the error-handling
        -- mechanism will drop you in here:
        -- Create a page of HTML text to return.
        set return_page to http_header ¬
            & "<html><head><title>Error Page</title></head>" ¬
            & "<body><h1>Error Encountered!</h1>" & return ¬
            & "An error was encountered while trying " ¬
            & "to run this script." ¬
            & return
        set return_page to return_page ¬
            & "<H3>Error Message</H3>" & return  ¬
            & errMsg & return ¬
            & "<H3>Error Number</H3>" & return ¬
            & errNum & return ¬
            & "<H3>Date</H3>" & return ¬
            & (current date) ¬
            & return
        set return_page to return_page ¬
            & "<hr>Please notify the webmaster at "  ¬
            & "<a href=\"mailto:[email protected]\">" ¬
            & "mailto:[email protected]</a> " ¬
            & "of this error." ¬
            & "</body></html>" ¬
            & return
        -- Return the error page created and exit the handler.
        return return_page
    end try
end <<event WWWdoc>>


Copyright © 1995, Dr. Dobb's Journal


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.