Sun Java System Web Server 6.1 SP9 NSAPI Programmer's Guide

ObjectType Example

The example in this section demonstrates how to implement html2shtml, a custom SAF that instructs the server to treat a .html file as a .shtml file if a .shtml version of the requested file exists.

A well-behaved ObjectType function checks if the content type is already set, and if so, does nothing except return REQ_NOACTION.


if(pblock_findval("content-type", rq->srvhdrs))
    return REQ_NOACTION;

The primary task an ObjectType directive needs to perform is to set the content type (if it is not already set). This example sets it to magnus-internal/parsed-html in the following lines:


/* Set the content-type to magnus-internal/parsed-html */
pblock_nvinsert("content-type", "magnus-internal/parsed-html",
    rq->srvhdrs);

The html2shtml function looks at the requested file name. If it ends with .html, the function looks for a file with the same base name, but with the extension .shtml instead. If it finds one, it uses that path and informs the server that the file is parsed HTML instead of regular HTML. Note that this requires an extra stat call for every HTML file accessed.

Installing the Example

To load the shared object containing your function, add the following line in the Init section of the magnus.conf file:

Init fn=load-modules shlib=yourlibrary funcs=html2shtml

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

ObjectType fn=html2shtml

Source Code

The source code for this example is in otype.c in the nsapi/examples/ or plugins/nsapi/examples subdirectory within the server root directory.

#include "nsapi.h"
#include <string.h>    /* strncpy */
#include "base/util.h"

#ifdef __cplusplus
extern "C"
#endif
NSAPI_PUBLIC int html2shtml(pblock *pb, Session *sn, Request *rq)
{
    /* No parameters */

    /* Work variables */
    pb_param *path = pblock_find("path", rq->vars);
    struct stat finfo;
    char *npath;
    int baselen;

    /* If the type has already been set, don't do anything */
    if(pblock_findval("content-type", rq->srvhdrs))
        return REQ_NOACTION;

    /* If path does not end in .html, let normal object types do
     * their job */
    baselen = strlen(path->value) - 5;
    if(strcasecmp(&path->value[baselen], ".html") != 0)
        return REQ_NOACTION;

    /* 1 = Room to convert html to shtml */
    npath = (char *) MALLOC((baselen + 5) + 1 + 1);
    strncpy(npath, path->value, baselen);
    strcpy(&npath[baselen], ".shtml");

    /* If it's not there, don't do anything */
    if(stat(npath, &finfo) == -1) {
        FREE(npath);
        return REQ_NOACTION;
    }
    /* Got it, do the switch */
    FREE(path->value);
    path->value = npath;

    /* The server caches the stat() of the current path. Update it. */
    (void) request_stat_path(NULL, rq);

    pblock_nvinsert("content-type", "magnus-internal/parsed-html",
                     rq->srvhdrs);
    return REQ_PROCEED;
}