Creating and Using Custom SAFs

                                                                                                                                                                                                                                                                                                                                      Back to [Book]     [Topic]

Creating and Using Custom SAFs

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

The general steps to create a custom SAF are as follows:

The following sections describe these steps in greater detail.

Writing the Source Code for a Custom SAF

Write your custom SAFs using NSAPI functions. For a summary of some of the most commonly used NSAPI functions, see Overview of NSAPI C Functions and for available routines, see NSAPI Function and Macro Reference.

For examples of custom SAFs, see Examples of Custom SAFs and Filters.

The signature for all SAFs is as follows:

int function(pblock *_pb_, Session *_sn_, Request *_rq_);

For more details on the parameters, see SAF Parameters.

You must register your SAFs with the server. SAFs may be registered using the funcs parameter of the load-modules Init SAF or by a call to func_insert. A plug-in may define a nspai_module_init function that is used to call func_insert and perform any other initialization tasks. For more information, see nsapi_module_init() Function and func_insert() Function.

The server runs as a multi-threaded single process. On UNIX platforms, the server runs 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 in mind when writing your SAF:

  • Write thread-safe code
  • Blocking can affect performance
  • Write small functions with parameters and configure the parameters in obj.conf
  • Carefully check and handle all errors and log the errors so you can determine the source of problems and fix them

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

int nsapi_module_init(pblock *_pb_, Session *_sn_, Request *_rq_);

SAFs should to be able to obtain certain types of information from their parameters. In most cases, parameter block (pblock) data structures provide the fundamental storage mechanism for these parameters. 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.

When defining a SAF, you do 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. Each directive requires its SAFs to behave in particular ways, and your SAF must conform to the requirements of the directive for which it was written. For details on what each directive requires of its SAFs, 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 install-dir/samples/nsapi directory.

Adhere to the following guidelines for compiling and linking.

Including Directory and nsapi.h File

Add the install-dir/include (UNIX) or install-dir\include (Windows) directory to your makefile to include the nsapi.h file.

Libraries

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

The following table lists the library that you need to link to.

Table 2-1 Libraries

Platform Library
Windows ns-httpd40.dll in addition to the standard Windows libraries
HP-UX libns-httpd40.sl
All other UNIX platforms libns-httpd40.so

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 2-2 Commands and Options

Platform Commands and Options
Solaris Operating System (SPARC Platform Edition) ld -G or cc -G
Windows link -LD
HP-UX cc +Z -b -Wl,+s -Wl,-B,symbolic
AIX cc -p 0 -berok -blibpath:$(LD_RPATH)
Compaq cc -shared
Linux gcc -shared
IRIX 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 2-3 Linker Flags

Platform Linker Flags
Solaris SPARC -R dir:dir
Windows no flags, but the ns-httpd40.dll file must be in the system PATH variable
HP-UX -Wl,+b,dir,dir
AIX -blibpath:dir:dir
Compaq -rpath dir:dir
Linux -Wl,-rpath,dir:dir
IRIX -Wl,-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 what you need to use for compilation of your source code.

Table 2-4 Compiler Flags

Solaris SPARC -DXP_UNIX -D_REENTRANT -KPIC -DSOLARIS
Windows -DXP_WIN32 -DWIN32 /MD
HP-UX -DXP_UNIX -D_REENTRANT -DHPUX
AIX -DXP_UNIX -D_REENTRANT -DAIX $(DEBUG)
Compaq -DXP_UNIX -KPIC
Linux -DXP_UNIX -D_REENTRANT -fPIC
IRIX -o32 -exceptions -DXP_UNIX -KPIC
Compiling and Linking in 64–bit Mode

On the Solaris platform, the server can run in either 32–bit or 64–bit mode. Because a 32–bit shared library cannot be used in a 64–bit process and conversely, you may want to compile and link two separate shared libraries. By default, the Sun compiler and linker produce 32–bit binaries. To compile and link your plug-in for 64–bit mode on Solaris SPARC, you must use Sun Workshop 5.0 or higher with the -xarch=v9 flag. To compile and link your plug-in for 64–bit mode on Solaris x86, you must use Sun Java Studio 11 or higher with the -xarch=amd64 flag.

Issues With Using C++ in a NSAPI Plug-in

NSAPI plug-ins are typically written using the C programming language. Using the C++ programming language in an NSAPI plug-in raises special compatibility issues.

On Solaris, the server is built using the new C++ 5 ABI. If your shared library uses C++ , it must be compiled with Sun Workshop 5.0 or higher. Sun Java Studio 11 or higher is recommended. Do not use the -compat=4 option when compiling and linking a shared library that uses C++ . When running in 32–bit mode on Solaris SPARC, the server provides some backward compatibility for the old C+ + 4 ABI or Sun Workshop 4.2. This backward compatibility may be removed at some future date. For all new NSAPI plug-ins, use the new C++ 5 ABI or Sun Workshop 5.0 or later versions.

On Linux, Web Server is built using the gcc 3.2 C+ + ABI. If your shared library uses C++ , compile with gcc 3.2.x. Because of the volatility of the gcc C+ + ABI, avoid using C+ + in NSAPI plug-ins on Linux.

Load and Initialize the SAF

For each shared library (plug-in) containing custom SAFs to be loaded into the server, add an Init directive that invokes the load-modules SAF to magnus.conf. The load-modules SAF loads the shared library and calls the shared library's nsapi_module_init function. For more information, see nsapi_module_init() Function.

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

Init fn=load-modules
     [shlib=_path_]
     [funcs="_SAF1_,...,_SAFn_"]
     [name1="_value1_"]...[nameN="_valueN_"]
  • shlib is the local file system path to the shared library (plug-in).
  • funcs is an optional comma-separated list of function names to be loaded from the shared library. Function names are case sensitive. You may use a dash ( - ) in place of an underscore (_) in function names. Do not use a space in the function name list.
    If the new SAFs require initialization, omit the funcs parameter and instead define an nsapi_module_init function in your shared library. Any custom parameters on the Init directive will be passed to nsapi_module_init in the pb parameter block.
  • nameN="valueN" are the optional names and values of parameters passed to the shared library's nsapi_module_init function in the pb parameter block.

Instruct the Server to Call the SAFs

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_"]
  • Directive is one of the server directives, such as AuthTrans, Service, and so on.
  • function-name is the name of the SAF to execute.
  • nameN="valueN" are the names and values of parameters that are passed to the SAF.

Depending on the purpose of the new SAF, 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 gets 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:/docs/animations/small, while all files to be treated as full-screen animations reside in the directory D:/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"
          dir="D:/docs/animations/small" 
          name="small_anim"
NameTrans fn=pfx2dir 
          from="/animations/fullscreen"
          dir="D:/docs/animations/fullscreen"
          name="fullscreen_anim"     

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>
<Object name="fullscreen_anim">
Service fn=do_big_anim speed=20
</Object>     

Restarting the Server

After modifying obj.conf, you need to restart the server. A restart is required for all plug-ins that implement SAFs and/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 Mozilla Firefox, hold the shift key while clicking the Reload button to ensure that the cache is not used.

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

Labels

java java Delete
server server Delete
sun sun Delete
webserver webserver Delete
application application Delete
system system Delete
guide guide Delete
webserver70 webserver70 Delete
sunjava sunjava Delete
developers developers Delete
web web Delete
developersguide developersguide Delete
nsapiguide nsapiguide Delete
webtier webtier Delete
+nsapiguide +nsapiguide Delete
nsapidevelopersguide nsapidevelopersguide Delete
nsapi nsapi Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Sign up or Log in to add a comment or watch this page.


The individuals who post here are part of the extended Sun Microsystems community and they might not be employed or in any way formally affiliated with Sun Microsystems. The opinions expressed here are their own, are not necessarily reviewed in advance by anyone but the individual authors, and neither Sun nor any other party necessarily agrees with them.

Copyright 1994-2009 Sun Microsystems, Inc.
Powered by Atlassian Confluence
Sun Guidelines on Public Discourse Privacy Policy Terms of Use Trademarks Site Map Employment Investor Relations Contact