WAIWebApplicationService
base class. See "Declaring a Class for Your Web Service"
Run
method for processing the incoming HTTP request. See "Defining a Method to Process Requests".
getServiceInfo
method for returning information about the service and its version.
Before continuing on, note the following points:
ONESrvPI.hpp
header file when writing a WAI application in C++:#include "ONESrvPI.hpp"
This header file declares the C++ classes available in WAI.
server_root
/wai/examples/WASP
directory on UNIX and the server_root
\wai\examples\WASP
directory on Windows NT.You can follow this example as a guideline for writing and compiling your
application.
Choose New from the File menu. Click the Projects tab and select the type
of application you want to write from this list:
Type the name of the project in the Project Name field and click OK.
From the Project menu, choose Add to Project and then choose Files. Use
the file browser to add the files you want to include in your project.
multi-threaded dll
run-time library.
From the Project menu, select Settings. Click the C/C++ tab and choose
Code Generation from the pull-down menu next to the Category option
(see Figure 5.1).
Choose Multithreaded DLL from pull-down menu next to the "Use run-time
library" option.
Click Settings from the Project menu. Click the C/C++ tab and choose
Preprocessor from the Category option menu (see Figure 5.2).
Add XP_WIN32 to the Preprocessor Definitions field.
include
directories.
Add the
include
file directories (../../include,..\..\include
)
Alternatively, you can add the
include
file directories by choosing Options
from the Tools menu and clicking the Directories tab. Choose "Include files"
from the "Show directories for" field, then add the include
directories to
the list.
Choose Settings from the Project menu. Click the Link tab in the Project
Settings dialog box. Choose General from the pull-down menu next to the
Category option. In the "Object/docs modules" field, type the names of
additional libraries. See Figure 5.3.
ALLOC
and FREE
executables. They conflict with the WAI API functions and can cause unpredictable results.
WAIWebApplicationService
base class. (This class represents a web application service.)
For example, the WASP example provided with the web server declares a WebApplicationServicePrototype
class, which is derived from the WAIWebApplicationService
base class:
//
// Declare a WAS class deriving from Netscape base class
//
class WebApplicationServicePrototype: public WAIWebApplicationService
{
public:
WebApplicationServicePrototype(const char *object_name = (const char *)NULL)
;
long Run(WAIServerRequest_ptr session);
char *getServiceInfo();
};
WebApplicationServicePrototype::WebApplicationServicePrototype(const char *object_name):WAIWebApplicationService(object_name)
{
}
...
The class that you define represents your web service. You need to define the following methods for your class; these methods are virtual methods in the WAIWebApplicationService
base class:
Run
This method is called by the web server to process HTTP requests for this
service. For details on defining this method, see "Defining a Method to
Process Requests".
getServiceInfo
This method returns information about your web service (such as version
information). For details on defining this method, see "Providing
Information About the Service".
long Run(WAIServerRequest_ptr session);
session
represents the HTTP request to be processed. You can call the methods of this object to get data from the request, set data in the response headers, and send the response back to the client.
The rest of this section explains how you can use these methods and objects to process the request. WAI functions enable you to do the following tasks:
WAIServerRequest
class (see the section "netscape::WAI::HttpServerRequest" for details), you can get data from the client's HTTP request. You can call functions accomplish the following tasks:
WAIServerRequest
class, you can get headers from the corresponding HTTP request by calling the getRequestHeader
method. For example, the following section of code gets the user-agent
HTTP request header from the incoming request:
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
char *var = 0;
ostrstream outstr;
...
if (session->getRequestHeader("user-agent", var) == WAISPISuccess){
outstr << "User Agent: " << var;
StringDelete(var);
}
outstr << endl;
...
}
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 getRequestInfo
method of the WAIServerRequest
class.
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 getInfo
method. 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
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
char *var = 0;
ostrstream outstr;
...
if (session->getRequestInfo("REMOTE_ADDR", var) == WAISPISuccess){
outstr << "Client IP Address: " << var;
StringDelete(var);
}
outstr << endl;
...
}
Getting Information about the Server
WAI also provides methods 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
).
These methods are available as part of the WAIServerContext
class (for more information, see the section "netscape::WAI::HttpServerContext"). You can get an object of this class by using the getContext
method of the WAIServerRequest
class.
For example, the following section of code gets an WAIServerContext
object:
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
...
WAIServerContext_ptr context = session->getContext();
...
}
To get information about the server, you can call the getInfo
method of the WAIServerContext
object 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
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
int port_num;
ostrstream outstr;
WAIServerContext_ptr context = session->getContext();
...
if (context->getInfo("SERVER_PORT", port_num) == WAISPISuccess){
outstr << "Port Number: " << var;
StringDelete(var);
}
outstr << endl;
}
...
}
For a list of the types of information you can retrieve from this method, see the section "getInfo".
You can also use methods that specifically retrieve a certain type of information. For example, to get the port number that the server listens to, you can call the getPort
method:
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
int port_num = 0;
ostrstream outstr;
WAIServerContext_ptr context = session->getContext();
...
if ((port_num = context->getPort()) != 0){
outstr << "Port Number: " << var;
StringDelete(var);
}
outstr << endl;
}
...
}
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 getCookie
method. To set your own name/value pairs in a client, call the setCookie
method.
The following example illustrates how you can use these methods to get and set cookies in the client.
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
...
char *cookiebuff = NULL;
/* If no cookie has been set in the client, set a cookie. */
if (session->getCookie(cookiebuff)== WAISPIFailure)
session->setCookie("MY_NAME", "My Value", "", "", "/", WAI_FALSE);
...
}
Sending the Response Back to the Client
Methods of the HttpServerRequest
class also allow you to control the response sent back to the client. You can call these functions to accomplish the following tasks:
addResponseHeader
method to set any header in the response. For example, the following section of code adds the Pragma
header to the response:
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
...
session->addResponseHeader("Pragma", "no-cache");
...
}
You can also call functions that set specific types of headers. For example, you can call:
setResponseContentType
to specify the content type of the response (the Content-type
header)
setResponseContentLength
to specify the length of the response in bytes (the Content-length
header)
setResponseStatus
method. For example, the following section of code sets the response code to a 404 status code ("File Not Found"):
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
...
session->setResponseStatus(404, "");
...
}
Sending the Response
After you have specified the length of the content you want sent back to the client, you can start sending the response to the client. Call the StartResponse
method to start sending the response.
To send the rest of the data to the client, call the WriteClient
method.
The following example sends the string Hello World
back to the client:
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
...
/* 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. */
session->setResponseContentLength(bufflen);
/* Start sending the response back to the client. */
session->StartResponse();
/* Write the string to the client. */
session->WriteClient((const unsigned char *)buffer, bufflen);
...
}
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 on manually.
To automatically redirect the user to a different page, you can do the following:
addResponseHeader
setResponseStatus
StartResponse
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
session->addResponseHeader("Location", "http://www.newsite.com/");
session->setResponseStatus(301, "Moved permanently to newsite!");
session->StartResponse();
return 0;
}To give the user the choice of going to the new location (rather than automatically redirecting the URL), you can call the
RespondRedirect
method:
long
WebApplicationServicePrototype::Run(WAIServerRequest_ptr session)
{
session->RespondRedirect("http://www.newsite.com/");
session->StartResponse();
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.
Providing Information About the Service
Part of the WAIWebApplicationService
base class is the virtual getServiceInfo
method. When you write your web application class (which is derived from the base class), you need to include a definition of this method.
The getServiceInfo
method should provide information about the web service, such as the name of the author, the version of the service, and so on.
The following section of code defines the getServiceInfo
method for a web service class WebApplicationServicePrototype
. The example uses the StringDup
method to allocate memory for the returned string.
...
char *
WebApplicationServicePrototype::getServiceInfo(void)
{
return StringDup("My Test Web Service. Version 1.0\nCopyright Netscape Communications Corporation\nAuthor: Mozilla\n");
}
...
Registering Your Web Application Service
Next, you need to create an instance of your class and assign an instance name to the object. You need to register your web service to the web server under this 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 register your application with the web server's built-in name service, call the RegisterService
method. Pass the name of the web server's hostname and port number as an argument (in the form hostname
:
portnumber
) to this method.
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 a Web Server".
The following section of code creates the web service ExeFoo
from the web service class WebApplicationServicePrototype
. The example registers this object to the web server under the instance name MyService
.
...
WAIBool rv;
char *host = "myhost.mydomain.com:81";
char *instanceName = "MyService";
...
/* Create the web service. */
WebApplicationServicePrototype ExeFoo(instanceName);
/* Register the web service. */
rv = ExeFoo.RegisterService(host);
/* Provide feedback on the result of the registration attempt. */
if (rv == WAI_FALSE) {
printf("Failed to register with %s\n", host);
} else {
printf("Successfully registered with %s\n", host);
}
...
Registering With an SSL-Enabled Server
Typically, when you call the RegisterService
or 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 RegisterService
or 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 RegisterService
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:
/export/netscape/suitespot
. In a C shell, you need to set the following environment variable before running your WAI application:
setenv NS_SERVER_ROOT /export/netscape/suitespotFor example, suppose that your server is running on the machine
preston
and your server identifier is https-webserver
instead of https-preston
. In C shell, you need to set the following environment variable before running your WAI application:
setenv NS_SERVER_ID https-webserver
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 C++ WASP
example by going to the URL:
http://server_name:port_number/iiop/WASP
Last Updated: 12/04/97 16:12:20
Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use