Sun Java System Web Proxy Server 4.0.11 NSAPI Developer's Guide

Creating and Using Custom SAFs

Custom SAFs are functions in shared libraries that are loaded and called by the server.

ProcedureTo create a custom SAF

  1. Writing the Source Code using the NSAPI functions. Each SAF is written for a specific directive.

  2. Compiling and Linking the source code to create a shared library (.so, .sl, or .dll) file.

  3. Loading and Initializing the SAF by editing the magnus.conf file to perform the following actions:

    • Load the shared library file containing your custom SAFs

      • Initialize the SAFs if necessary

  4. Instructing the Server to Call the SAFs by editing obj.conf to call your custom SAFs at the appropriate time.

  5. Restarting the Server.

  6. Testing the SAF by accessing your server from a browser with a URL that triggers your function.

    The following sections describe these steps in greater detail.

Writing the Source Code

Write custom SAFs using NSAPI functions. For a summary of some of the most commonly used NSAPI functions, see Overview of NSAPI C Functions. For information about available routines, see Chapter 4, NSAPI Function Reference

For examples of custom SAFs, see nsapi/examples/ in the server root directory, and Chapter 3, Examples of Custom SAFs and Filters

The signature for all SAFs is:

int function(pblock *pb, Session *sn, Request *rq);

For more details on the parameters, see SAF Parameters.

The Sun Java System Web Proxy Server runs as a multi-threaded single process. UNIX platforms uses two processes, a parent and a child, for historical reasons. The parent process performs some initialization and forks the child process. The child process performs further initialization and handles all of the HTTP requests.

Keep the following guidelines in mind when writing your SAF:

If necessary, write an initialization function that performs initialization tasks required by your new SAFs. The initialization function has the same signature as other SAFs:

int function(pblock *pb, Session *sn, Request *rq);

SAFs work by obtaining certain types of information from their parameters. In most cases, parameter block (pblock) data structures provide the fundamental storage mechanism for these parameters. A pblock maintains its data as a collection of name-value pairs. For a summary of the most commonly used functions for working with pblock structures, see Parameter Block Manipulation Routines.

A SAF, definition does not specifically state which directive it is written for. However, each SAF must be written for a specific directive such as AuthTrans, Service, and so on. A SAF must conform behavior consistent wit the directive for which it was written. For more details, see Required Behavior of SAFs for Each Directive.

Compiling and Linking

Compile and link your code with the native compiler for the target platform. For UNIX, use the gmake command. For Windows, use the nmake command. For Windows, use Microsoft Visual C++ 6.0 or newer. You must have an import list that specifies all global variables and functions to access from the server binary. Use the correct compiler and linker flags for your platform. Refer to the example Makefile in the server_root/plugins/nsapi/examples directory.

This section provides following guidelines for compiling and linking.

Include Directory and nsapi.h File

Add the server_root/plugins/include (UNIX) or server_root\\plugins\\include (Windows) directory to your makefile to include the nsapi.h file.

Linker Libraries

Add the server_root/bin/https/lib (UNIX) or server_root\\bin\\https\\bin (Windows) library directory to your linker command.

The following table lists the relevant libraries.

Table 1–1 Linker Libraries




ns-httpd40.dll (in addition to the standard Windows libraries)


All other UNIX platforms

Linker Commands and Options for Generating a Shared Object

To generate a shared library, use the commands and options listed in the following table.

Table 1–2 Linker Commands and Options



SolarisTM Operating System (SPARC® Platform Edition)

ld -G or cc -G


link -LD


cc +Z -b -Wl,+s -Wl,-B,symbolic


cc -p 0 -berok -blibpath:$(LD_RPATH)


cc -shared


gcc -shared


cc -shared

Additional Linker Flags

Use the linker flags in the following table to specify which directories should be searched for shared objects during runtime to resolve symbols.

Table 1–3 Linker Flags



Solaris SPARC 

-R dir:dir


no flags, but the ns-httpd40.dll file must be in the system PATH variable






-rpath dir:dir





On UNIX, you can also set the library search path using the LD_LIBRARY_PATH environment variable, which must be set when you start the server.

Compiler Flags

The following table lists the flags and defines you need to use for compilation of your source code.

Table 1–4 Compiler Flags and Defines



Solaris SPARC 













-o32 -exceptions -DXP_UNIX -KPIC

All platforms 


The following table lists the optional flags and defines you can use.

Table 1–5 Optional Flags and Defines






Needed for the proxy utilities function include file putil.h

Loading and Initializing the SAF

For each shared library (plug-in) containing custom SAFs to be loaded into the Sun Java System Web Proxy Server, add an Init directive that invokes the load-modules SAF to obj.conf.

The syntax for a directive that calls load-modules is:

Init fn=load-modules shlib=[path]sharedlibname funcs="SAF1,...,SAFn"

For example, if you created a shared library that defines two SAFs do_small_anim() and do_big_anim() and also defines the initialization function init_my_animations, you would add the following directive to load the plug-in:

Init fn=load-modules funcs="do_small_anim,do_big_anim,

If necessary, also add an Init directive that calls the initialization function for the newly loaded plug-in. For example, if you defined the function init_my_new_SAF() to perform an operation on the maxAnimLoop parameter, you would add a directive such as the following to magnus.conf:

Init fn=init_my_animations maxAnimLoop=5

Instructing the Server to Call the SAFs

Next, add directives to obj.conf to instruct the server to call each custom SAF at the appropriate time. The syntax for directives is:

Directive fn=function-name [name1="value1"]...[nameN="valueN"]

Depending on what your new SAF does, you might need to add just one directive to obj.conf, or you might need to add more than one directive to provide complete instructions for invoking the new SAF.

For example, if you define a new AuthTrans or PathCheck SAF, you could just add an appropriate directive in the default object. However, if you define a new Service SAF to be invoked only when the requested resource is in a particular directory or has a new kind of file extension, you would need to take extra steps.

If your new Service SAF is to be invoked only when the requested resource has a new kind of file extension, you might need to add an entry to the MIME types file so that the type value is set properly during the ObjectType stage. Then you could add a Service directive to the default object that specifies the desired type value.

If your new Service SAF is to be invoked only when the requested resource is in a particular directory, you might need to define a NameTrans directive that generates a name or ppath value that matches another object. Then, in the new object, you could invoke the new Service function.

For example, suppose your plug-in defines two new SAFs, do_small_anim() and do_big_anim(), which both take speed parameters. These functions run animations. All files to be treated as small animations reside in the directory D:/<Install_Root>/<Instance_Directory>/docs/animations/small, while all files to be treated as full-screen animations reside in the directory D:/<Install_Root>/<Instance_Directory>/docs/animations/fullscreen.

To ensure that the new animation functions are invoked whenever a client sends a request for either a small or full-screen animation, you would add NameTrans directives to the default object to translate the appropriate URLs to the corresponding path names and also assign a name to the request.

NameTrans fn=pfx2dir from="/animations/small"
NameTrans fn=pfx2dir from="/animations/fullscreen"

You also need to define objects that contain the Service directives that run the animations and specify the speed parameter.

<Object name="small_anim">
Service fn=do_small_anim speed=40
<Object name="fullscreen_anim">
Service fn=do_big_anim speed=20


Restarting the Server

After modifying obj.conf, you need to restart the server. A restart is required for all plug-ins that implement SAFs or filters.

Testing the SAF

Test your SAF by accessing your server from a browser with a URL that triggers your function. For example, if your new SAF is triggered by requests to resources in http://server-name/animations/small, try requesting a valid resource that starts with that URI.

You should disable caching in your browser so that the server is sure to be accessed. In Netscape NavigatorTM, Press the Shift key while clicking the Reload button to ensure that the cache is not used. If the images are already in the cache, this action does not always force the client to fetch images from the source.

You might also want to disable the server cache using the cache-init SAF.

Examine the access log and error log to help with debugging.