Writing Web Applications With WAI: Netscape Enterprise Server/FastTrack Server, Version 3.0/3.01

[Contents] [Previous] [Next] [Index]

Chapter 4
Writing a WAI Application in C

WAI provides a set of C API functions that you can use to write a WAI application. Your C application should:

After you write and compile your application, see the section "Running Your Web Service" for instructions on setting up and running your web service.

For a summary of the C functions available in WAI, see the section "Summary of C Functions"

Before continuing on, note the following points:

The rest of this chapter explains how to write a WAI application in C.

Defining a Function to Process Requests

The function that processes incoming HTTP requests (not all requests, just the requests directed specifically at your service) must comply with the following type definition:

typedef long (*WAIRunFunction)(ServerSession_t obj);
obj represents the HTTP request to be processed. You pass this argument to other WAI functions in order to get data from the client request, set data in the response, and send the response to the client.

The rest of this section explains how you can call WAI functions to process the request. WAI functions enable you to do the following tasks:

Getting Data from the Request

WAI provides functions for getting data from the client's HTTP request. You can call functions to accomplish the following tasks:

Getting Headers from the HTTP Request

To get headers from the HTTP request, call the WAIgetRequestHeader() function. For example, the following section of code gets and prints the user-agent header from the incoming request:

long MyRunFunction(ServerSession_t obj)
{
   char *var = 0;
   ...
   if (WAIgetRequestHeader(obj, "user-agent", var) == WAISPISuccess){ 
      printf( "User agent: %s\n", var); 
   } 
   ...
}
In addition to HTTP headers, you can get other types of information (such as CGI 1.1 environment variables) from the HTTP request by calling the WAIgetRequestInfo() function.

The section "getRequestInfo" lists the types of information you can retrieve from the request. Note that the CGI 1.1 environment variables that describe the server are accessible through the WAIgetInfo() function. See "Getting Information about the Server" for details.

The following section of code gets and prints the value of the REMOTE_ADDR CGI 1.1 environment variable for the incoming request:

long MyRunFunction(ServerSession_t obj)
{
   char *var = 0;
   ...
   if (WAIgetRequestInfo(obj, "REMOTE_ADDR", var) == WAISPISuccess){ 
      printf( "Client IP Address: %s\n", var); 
   } 
   ...
}

Getting Information about the Server

WAI also provides C functions for getting information about the server, such as the server identifier or CGI 1.1 environment variables that describe the server (for example, SERVER_NAME or SERVER_PORT).

To get these types of information, you can call the WAIgetInfo() function and specify the type of information that you want to retrieve. For example, the following section of code gets the value of the SERVER_PORT CGI 1.1 environment variable:

long MyRunFunction(ServerSession_t obj)
{
   int port_num;
   ...
   if (WAIgetInfo(obj, "SERVER_PORT", port_num) == WAISPISuccess){ 
      printf( "Server Port: %d\n", port_num); 
   } 
   ...
}
For a list of the types of information you can retrieve from this method, see the section "getInfo".

You can also call functions that specifically retrieve a certain type of information. For example, to get the port number that the server listens to, you can call the WAIgetPort() function:

long MyRunFunction(ServerSession_t obj)
{
   int port_num = 0;
   ...
   if ((port_num = WAIgetPort(obj)) != 0){ 
      printf( "Server Port: %d\n", port_num); 
   } 
   ...
}
For details on getting server information, see the section "netscape::WAI::HttpServerContext".

Getting and Setting Cookies in the Client

Before a client accesses a URL, the client checks the domain name in the URL against the cookies that it has. If any cookies are from the same domain as the URL, the client includes a header in the HTTP request that contains the name/value pairs from the matching cookies.

The Cookie header has the following format:

Cookie: name=value; [name1=value1; name2=value2 ... ]
To get these name/value pairs from the HTTP request, call the WAIgetCookie() function. To set your own name/value pairs in a client, call the WAIsetCookie() function.

The following example illustrates how you can use these functions to get and set cookies in the client.

long MyRunFunction(ServerSession_t obj)
{
   ...
   char *cookiebuff = NULL; 
   /* If no cookie has been set in the client, set a cookie. */
   if (WAIgetCookie(obj, cookiebuff)== WAISPIFailure) 
      WAIsetCookie(obj, "A_NAME", "A Value", "", "", "/", WAI_FALSE); 
   ...
}

Sending the Response Back to the Client

WAI functions also allow you to control the response sent back to the client. You can call these functions to accomplish the following tasks:

Setting Headers in the Response

WAI includes functions that you can use to set headers in the response that you want sent back to the client. You can call the WAIaddResponseHeader() function to set any header in the response. For example, the following section of code adds the Pragma header to the response:

...
WAIaddResponseHeader(obj, "Pragma", "no-cache");
...
You can also call functions that set specific types of headers. For example, you can call:

Setting the Status of the Response

To set the status of the response sent back to the client, call the WAIsetResponseStatus() function. For example, the following section of code sets the response status to a 404 status code ("File Not Found"):

...
WAIsetResponseStatus(obj, 404, "");
...

Sending the Response

After you have set up the response you want sent back to the client, you can start sending the response to the client. Call the WAIStartResponse() function to start sending the response.

To send the rest of the data to the client, call the WAIWriteData() function.

The following example sends the string Hello World back to the client:

long MyRunFunction(ServerSession_t obj)
{
   /* Specify the string that you want to send back to the client. */
   char *buffer = "Hello World\n"; 
   size_t bufflen = strlen(buffer); 
   /* Specify the length of the data that you are about to send back. */
   WAIsetResponseContentLength(obj, bufflen); 
   /* Start sending the response back to the client. */
   WAIStartResponse(obj); 
   /* Write the string to the client. */
   WAIWriteClient(obj, (const unsigned char *)buffer, bufflen); 
   return 0;
}

Redirecting Users to Another Page

In your WAI application, you can also redirect users to a different page than the requested page. You can either automatically redirect the user to a new page, or you can present the user with a link to click manually.

To automatically redirect the user to a different page, you can do the following:

  1. Call the WAIaddResponseHeader() function to add a Location header.
    The Location header points to the new location.

  2. Call the WAIsetResponseStatus() function to set the response status.
    Set the response status to 301 if the page has permanently moved or 302 if the page has temporarily moved.

  3. Call the WAIStartResponse() function to send the response back to the client.
For example:

long
MyRunFunction(ServerSession_t obj)
{
   WAIaddResponseHeader(obj, "Location", "http://www.newsite.com/");
   WAIsetResponseStatus(obj, 302, "Moved temporarily to newsite.com");
   WAIStartResponse(obj);
   return 0;
}
To give the user the choice of going to the new location (rather than automatically redirecting the URL), you can call the WAIRespondRedirect() function:

long
MyRunFunction(ServerSession_t obj)
{
   WAIRespondRedirect(obj, "http://www.newsite.com/");
   WAIStartResponse(obj);
   return 0;
}
Calling this method will send the following page back to the client:

Moved Temporarily
This document has moved to a new location. Please update your documents and hotlists accordingly.
The word "location" on this page is a link pointing to the new location of the page.

Registering Your Web Application Service

After you define the function for processing HTTP reequests, you need to create and register your web service. You need to register your web service to the web server under an instance name. The instance name that you select for your web service can be an arbitrary name; it does not need to be the same name as your application. (For example, if your application is named MyApp or MyApp.exe, your instance name can be MyWebService. They do not need to have the same name.)

Note, however, that your instance name must be unique. No other registered WAI application can have the same name.

Registering With a Web Server

To create and register your web application service, follow these steps:

  1. Call the WAIcreateWebAppService() function to create the web service.
    Specify the name of the service and the name of your function (that you defined in "Defining a Function to Process Requests") as arguments.
    The instance name that you select for your web service can be an arbitrary name. It does not need to be the same name as your application.
    WAIcreateWebAppService() returns a pointer to an IIOPWebAppService structure, which represents the newly created web service.

  2. Call the WAIregisterService() function to register the service.
    Pass the pointer to the IIOPWebAppService structure to this function. You also need to specify the hostname and port number of the web server in the form hostname:portnumber.
    Note that if your web server is running with SSL enabled, you need to specify a different value for this argument. For details, see "Registering With an SSL-Enabled Server".

  3. Call the WAIimplIsReady() function to indicate that your service is prepared to receive incoming requests.
Note that the WAIimplIsReady() function puts the application into an endless loop. Any statements that you insert after this function are not executed. So, for example, if you want to add a printf statement to indicate whether or not the application has registered successfully, add the statement before calling the WAIimplIsReady() function.

For example, the following section of code creates and registers a new web service with the instance name CAPIIIOP. Whenever this web service is accessed, the web server sends the HTTP request to the function named MyRunFunction.

...
IIOPWebAppService_t obj;
WAIReturnType_t rv;
...
/* Create the web service. */
obj = WAIcreateWebAppService("CAPIIIOP", MyRunFunction); 
/* Register the web service. */
rv = WAIregisterService(obj, "myhost.netscape.com:81");
if (rv == WAI_FALSE) { 
   printf("Failed to Register with %s\n", host); 
   return 1;
} else { 
   printf("Registered successfully with %s\n", host); 
} 
/* Indicate that the service is ready to receive requests. */
WAIimplIsReady();
return 0;
...

Registering With an SSL-Enabled Server

Typically, when you call the WAIregisterService function to register your web service, you pass the host name and port number of your web server as an argument.

The function constructs a URL to the web server's built-in naming service and gets the object reference for this naming service. This object reference is used to register your application.

If your web server has SSL enabled, the WAIregisterService function cannot get the naming service object reference in the manner described above. Instead, it needs to use the Interoperable Object Reference (IOR) file to get the object reference for the naming service.

To find the IOR file, the WAIregisterService function assembles a path to the file using the following information:

If your web server does not use the default values for either of these, you must set environment variables to identify the correct values before running your WAI application:

   setenv NS_SERVER_ID https-webserver

Running Your Web Service

After you write and compile your application, you can run your application to make your web service available. The web server should recognize your application, if you've registered it (see "Registering Your Web Application Service").

End users can access your service by going to the URL:

http://server_name:port_number/iiop/instance_name
For example, you can access the CAPIIIOP example by going to the URL:

http://server_name:port_number/iiop/CAPIIIOP

Summary of C Functions

The following table summarizes the C functions available in WAI.

Table 4.1 C Functions in WAI
Function Name Description For More Information, See...
WAIaddResponseHeader()
Adds a header to the HTTP response to be sent back to the client.

"addResponseHeader"

WAIBuildURL()
Builds an absolute URL from the URI prefix and the URI suffix.

"BuildURL"

WAIcreateWebAppService()
Creates a new web application service, assigns it an instance name, and associates it with a function for processing HTTP requests.

"WAIWebApplicationService"

WAIdeleteService()
Deletes a web application service.

WAIdelResponseHeader()
Removes a header from the HTTP response to be sent back to the client.

"delResponseHeader"

WAIgetConfigParameter()
Gets the value of a parameter of the iiopexec function in the Service directive of the obj.conf file.

"getConfigParameter"

WAIgetCookie()
Retrieves any cookies sent by the client.

"getCookie"

WAIgetHost()
Gets the hostname of the machine where the web server is running.

"getHost"

WAIgetInfo()
Retrieves information about the web server (such as the value of CGI 1.1 environment variables that describe the server).

"getInfo"

WAIgetName()
Gets the server ID (for example, https-myhost) of the web server.

"getName"

WAIgetPort()
Gets the port number that the web server listens to.

"getPort"

WAIgetRequestHeader()
Gets a header from the HTTP request sent by the client.

"getRequestHeader"

WAIgetRequestInfo()
Gets information about the client request (such as the value of a CGI 1.1 environment variable).

"getRequestInfo"

WAIgetResponseContentLength()
Gets the content length (the value of the Content-length header) of the response.

"getResponseContentLength"

WAIgetResponseHeader()
Gets a header from the HTTP response you plan to send to the client.

"getResponseHeader"

WAIgetServerSoftware()
Gets the type and version of the server software.

"getServerSoftware"

WAIimplIsReady()
Prepares your WAI application to receive requests.

"Registering Your Web Application Service"

WAIisSecure()
Specifies whether or not the server is run with SSL enabled.

"isSecure"

WAILogError()
Logs an entry to the server's error log file (server_root/server_id/logs/errors on UNIX and server_root\server_id\logs\errors on Windows NT).

"LogError"

WAIReadClient()
Reads data from the client (for example, for data sent through the HTTP POST method).

"ReadClient"

WAIregisterService()
Registers the WAI application with the web server.

"RegisterService"

WAIRespondRedirect()
Redirects the client to a different URL.

"RespondRedirect"

(*WAIRunFunction)()
Type definition for the function that processes HTTP requests.

"Run"

WAIsetCookie()
Sets a cookie in the response header to be sent to the client.

"setCookie"

WAIsetRequestInfo()
(This method has no functional use at this time.)

"setRequestInfo"

WAIsetResponseContentLength()
Sets the content length (the value of the Content-length header) of the response to be sent to the client.

"setResponseContentLength"

WAIsetResponseContentType()
Sets the content type (the value of the Content-type header) of the response to be sent to the client.

"setResponseContentType"

WAIsetResponseStatus()
Sets the HTTP response code (for example, 404 for "File Not Found") of the response to be sent to the client.

"setResponseStatus"

WAIStartResponse()
Starts sending the response back to the client.

"StartResponse"

WAIstringFree()
Frees a string from memory.

"StringDelete"

WAIWriteClient()
Writes data to the client.

"WriteClient"


[Contents] [Previous] [Next] [Index]

Last Updated: 12/04/97 16:12:17


Copyright © 1997 Netscape Communications Corporation

Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use