Service Example

This section discusses a very simple Service function
called simple_service. This function sends a message in
response to a client request. The message is initialized by the init_simple_service function during server initialization.

Installing the Service Example

To call the simple-service-init function to initialize
the message representing the generated output, add the following line to the Init section in obj.conf.
This line must appear after the line that loads the library containing simple-service-init.)

To execute the custom SAF during the request-response process for an
object, add the following line to that object in the obj.conf file:

Service type="text/html" fn=simple-service

The type="text/html" argument indicates that this
function is invoked during the Service stage only if the content-type has been set to text/html.

Service Example Source Code

#include <nsapi.h>
static char *simple_msg = "default customized content";
/* This is the initialization function.
* It gets the value of the generated-output parameter
* specified in the Init directive in magnus.conf
*/
NSAPI_PUBLIC int init-simple-service(pblock *pb, Session *sn,
Request *rq)
{
/* Get the message from the parameter in the directive in
* magnus.conf
*/
simple_msg = pblock_findval("generated-output", pb);
return REQ_PROCEED;
}
/* This is the customized Service SAF.
* It sends the "generated-output" message to the client.
*/
NSAPI_PUBLIC int simple-service(pblock *pb, Session *sn, Request *rq)
{
int return_value;
char msg_length[8];
/* Use the protocol_status function to set the status of the
* response before calling protocol_start_response.
*/
protocol_status(sn, rq, PROTOCOL_OK, NULL);
/* Although we would expect the ObjectType stage to
* set the content-type, set it here just to be
* completely sure that it gets set to text/html.
*/
param_free(pblock_remove("content-type", rq->srvhdrs));
pblock_nvinsert("content-type", "text/html", rq->srvhdrs);
/* If you want to use keepalive, need to set content-length header.
* The util_itoa function converts a specified integer to a
* string, and returns the length of the string. Use this
* function to create a textual representation of a number.
*/
util_itoa(strlen(simple_msg), msg_length);
pblock_nvinsert("content-length", msg_length, rq->srvhdrs);
/* Send the headers to the client*/
return_value = protocol_start_response(sn, rq);
if (return_value == REQ_NOACTION) {
/* HTTP HEAD instead of GET */
return REQ_PROCEED;
}
/* Write the output using net_write*/
return_value = net_write(sn->csd, simple_msg,
strlen(simple_msg));
if (return_value == IO_ERROR) {
return REQ_EXIT;
}
return REQ_PROCEED;
}

More Complex Service Example

The send-images function is a custom SAF that replaces
the doit.cgi demonstration available on the iPlanet home
pages. When a file is accessed as /dir1/dir2/something.picgroup,
the send-images function checks whether the file is being
accessed by a Mozilla/1.1 browser. If the file is not being accessed, the
function sends a short error message. The file something.picgroup contains
a list of lines, each of which specifies a file name followed by a content-type, for example, one.gif image/gif.

To load the shared object containing your function, add the following
line at the beginning of the obj.conf file:

Init fn=load-modules shlib=yourlibrary funcs=send-images

Also, add the following line to the mime.types file:

type=magnus-internal/picgroup exts=picgroup

To execute the custom SAF during the request-response process for an
object, add the following line to that object in the obj.conf file. send-images takes an optional parameter, delay,
which is not used for this example.