obj.conf
file, from the server, and from previous SAFs.
Here is the C interface for a SAF:
The next section discusses the parameters in detail. The SAF returns a result code which indicates whether and how it succeeded. The server uses the result code from each function to determine how to proceed with processing the request. See the section "Result Codes" for details of the result codes.int function(pblock *
pb
, Session *
sn
, Request *
rq
);
pb (parameter block)
-- contains the parameters from the directive that invokes the SAF in the obj.conf
file.
sn (session)
-- contains information relating to a single TCP/IP session.
rq (request)
-- contains information relating to the current request.
pb
parameter is a pointer to a pblock
data structure that contains values specified by the directive that invokes the SAF. A pblock
data structure contains a series of name/value pairs.
For example, a directive that invokes the basic-nsca
function might look like:
AuthTrans fn=basic-ncsa auth-type=basic
dbm=/netscape/server4/userdb/rs
In this case, the pb
parameter passed to basic-ncsa
contains name/value pairs that correspond to auth-type=basic
and dbm=/netscape/server4/userdb/rs
.
NSAPI provides a set of functions for working with pblock
data structures. For example, pblock_findval()
returns the value for a given name in a pblock
. See "Parameter Block Manipulation Routines" for a summary of the most commonly used functions for working with parameter blocks.
sn
parameter is a pointer to a Session
data structure. This parameter contains variables related to an entire session (that is, the time between the opening and closing of the TCP/IP connection between the client and the server). The same sn
pointer is passed to each SAF called within each request for an entire session. The following list describes the most important fields in this data structure.
(See Chapter 5, "NSAPI Function Reference," for information about NSAPI routines for manipulating the Session
data structure):
pblock
containing information about the client such as its IP address, DNS name, or certificate. If the client does not have a DNS name or if it cannot be found, it will be set to the client's IP number. rq
parameter is a pointer to a request
data structure. This parameter contains variables related to the current request, such as the request headers, URI, and local file system path. The same request
pointer is passed to each SAF called in the request-response process for an HTTP request.
The following list describes the most important fields in this data structure (See Chapter 5, "NSAPI Function Reference," for information about NSAPI routines for manipulating the Request
data structure).
pblock
containing the server's "working" variables. This includes anything not specifically found in the following three pblocks. The contents of this pblock
vary depending on the specific request and the type of SAF. For example, an AuthTrans SAF may insert an auth-user
parameter into rq->vars
which can be used subsequently by a PathCheck SAF.pblock
containing elements of the HTTP request. This includes the HTTP method (GET, POST, ...), the URI, the protocol (normally HTTP/1.0), and the query string. This pblock
does not normally change throughout the request-response process.pblock
containing all the request headers (such as User-Agent, If-Modified-Since, ...) received from the client in the HTTP request. See Appendix G, "HyperText Transfer Protocol," for more information about request headers. This pblock
does not normally change throughout the request-response process.rq->srvhdrs
is a pointer to a pblock
containing the response headers (such as Server,
Date, Content-type, Content-length,...) to be sent to the client in the HTTP
response. See Appendix G, "HyperText Transfer Protocol," for more
information about response headers.
rq->directive_is_cacheable
/mfg/proc/item.txt
, and then another client requests /mfg/proc/item.txt
, the server's response is the same as long as /mfg/proc/item.txt
doesn't change between the requests. When the server can avoid calling the SAFs for a request, it can return the response faster.
The flag is set to 0 on entry to each SAF. If you do not set this flag to 1 before your SAF returns, the server does not try to cache the request, and each subsequent request calls your SAF again. If your SAF sets it to 1, and all other SAFs called for this request also set the flag, the server caches the request and does not call your SAF when another request is made for the same resource.
If your SAF performs access control, logging, depends on the client IP address, the user-agent, or any headers the client sends, it should not set directive_is_cacheable
. Otherwise you should set directive_is_cacheable
to 1.
During development, you may disable server caching by adding the following line at the top of the obj.conf
file:
Init fn=cache-init disable=true
Don't forget to stop and start the server after saving the file. This disables server caching so that your SAF will always be called.rq
parameter is the primary mechanism for passing along information throughout the request-response process. On input to a SAF, rq
contains whatever values were inserted or modified by previously executed SAFs. On output, rq
contains any modifications or additional information inserted by the SAF. Some SAFs depend on the existence of specific information provided at an earlier step in the process. For example, a PathCheck SAF retrieves values in rq->vars
which were previously inserted by an AuthTrans SAF.
REQ_ABORTED
should also set the HTTP response status code. If the server finds an Error
directive matching the status code or reason phrase, it executes the SAF specified. If not, the server sends a default HTTP response with the status code and reason phrase plus a short HTML page reflecting the status code and reason phrase for the user. The server then goes to the first AddLog
directive.AddLog
directive.using the NSAPI functions. Each SAF is written for a specific directive.
the source code to create a shared library (.so, .sl,
or.dll)
file.
by editing the obj.conf
file to:
-- Load the shared library file containing your custom SAF(s).
-- Initialize the SAF if necessary.
by editing obj.conf
to call your custom SAF(s) at the appropriate time.
by accessing your server from a browser with a URL that triggers your function.
nsapi/examples/
in the server root directory and also see Chapter 6, "Examples of Custom SAFs."
The signature for all SAFs is:
For more details on the parameters, see the section "SAF Parameters." The iPlanet Web Server runs as a multi-threaded single process. On Unix platforms there are actually 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 the HTTP requests. Keep these things in mind when writing your SAF. Write thread-safe code. Blocking may affect performance. Write small functions with parameters and configure them inint function(pblock *
pb
, Session *
sn
, Request *
rq
);
obj.conf
. Carefully check and handle all errors. Also log them so that 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 has the same signature as other SAFs:
SAFs expect to be able to obtain certain types of information from their parameters. In most cases, parameter block (int function(pblock *
pb
, Session *
sn
, Request *
rq
);
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."
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 Init
, AuthTrans
, Service
and so on). Each directive expects its SAFs to do particular things, and your SAF must conform to the expectations of the directive for which it was written. For details of what each directive expects of its SAFs, see the section "Required Behavior of SAFs for Each Directive."
nsapi/examples
directory. On Windows NT link to nshttpd3x.lib
or nshttpd40.lib
as appropriate in the plugins/lib
directory.
The include
directory in the server-root
directory in Enterprise Server 3.x or in server-root
/plugins
in iPlanet Web Server 4.x contains the NSAPI header file. All the NSAPI header information is now contained in one file called nsapi.h
.
New in iPlanet Web Server 4.0: For AIX only, plugins built for 3.x versions of the server must be relinked to work with 4.x versions. The files you need, which are in the server_root
/plugins/nsapi/examples/
directory, are as follows:
Makefile
file has the -G
option instead of the old -bM:SRE -berok -brtl -bnoentry
options.relink_36plugin
, modifies a plugin built for 3.x versions of the server to work with 4.x versions. The script's comments explain its use.ns-httpd
main executable, must be built with the -G
option, which specifies that symbols must be resolved at runtime.
Previous versions of Netscape Enterprise Server, however, were built on AIX 4.1, which did not support native runtime-linking. Enterprise Server had specific additional software (provided by IBM AIX development to Netscape) to enable plugins. No special runtime-linking directives were required to build plugins. Because of this, plugins that have been built for previous server versions on AIX will not work with iPlanet Web Server 4.x versions as they are.
However, they can easily be relinked to work with iPlanet Web Server 4.x versions. The relink_36plugin script relinks existing plugins. Only the existing plugin itself is required for the script; original source and .o files are not needed. More specific comments are in the script itself. Since all AIX versions from 4.2 onward natively support runtime-linking, no plugins for iPlanet Web Server versions 4.x and later will need to be relinked.
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]sharedlibnamefuncs="
SAF1,...,SAFn"
shlib
is the local file system path to the shared library (plugin).funcs
is a comma-separated list of function names to be loaded from the shared library. Function names are case-sensitive. You may use dash (-) in place of underscore (_) in function names. There should be no spaces in the function name list.funcs
list.animations.so
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 plugin:
If necessary, also add anInit fn=load-modules shlib=
[path]animations.sofuncs="
do_small_anim,do_big_anim,init_my_animations
"
Init
directive that calls the initialization function for the newly loaded plugin. For example, if you defined the function init_my_new_SAF()
to perform an operation on the maxAnimLoop
parameter, you would a directive such as the following to obj.conf
:
Init fn=init_my_animations
maxAnimLoop=5
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 Init
, AuthTrans
, and so on.function-name
is the name of the SAF to execute.nameN="valueN"
are the names and values of parameters which are passed to the SAF.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, and then in the new object you could invoke the new Service
function.
For example, suppose your plugin 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:/Netscape/server4/docs/animations/small, while all files to be treated as full screen animations reside in the directory D:/Netscape/server4/docs/animations/fullscreen.
To ensure that the new animation functions are invoked whenever a client sends a request for either a small or fullscreen animation, you would add NameTrans
directives to the default object to translate the appropriate URLs to the corresponding pathnames and also assign a name to the request.
NameTrans fn=pfx2dir from="/animations/small"
dir="D:/Netscape/server4/docs/animations/small" name="small_anim"
NameTrans fn=pfx2dir from="/animations/fullscreen"You also need to define objects that contain the
dir="D:/Netscape/server4/docs/animations/fullscreen"
name="fullscreen_anim"
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>
obj.conf
, you need to start and stop the server. On Unix you may execute the shell scripts stop
and start
in the servers home directory. Do not use restart
on Unix since the server will not reload your shared library after it has been loaded once.
On Windows NT you may use the Services Control Panel to stop and start the server. Once you have started the server with your shared library, you'll have to stop it before you can build your shared library again.
You can also use the Server Manager interface to re-load obj.conf
and to start and stop the server.
If there are problems during startup, check the error log.
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 Navigator you may hold the shift key while clicking the Reload button to ensure that the cache is not used. (Note that the shift-reload trick does not always force the client to fetch images from source if the images are already in the cache.)
You may also wish to disable the server cache using the cache-init
SAF.
Examine the access log and error log to help with debugging.
pblock
data structure include:
pblock_findval
returns the value for a given name in a pblock
.pblock_nvinsert
adds a new name-value entry to a pblock
.pblock_remove
removes a pblock
entry by name from a pblock
. The entry is not disposed. Use param_free
to free the memory used by the entry.param_free
frees the memory for the given pblock
entry.pblock_pblock2str
creates a new string containing all the name-value pairs from a pblock
in the form "name
=
value
name
=
value
." This can be a useful function for debugging.request_header
returns the value for a given request header name, reading the headers if necessary. This function must be used when requesting entries from the browser header pblock
(rq->headers
).protocol_status
sets the HTTP response status code and reason phraseprotocol_start_response
sends the HTTP response and all HTTP headers to the browser.pool-init
in Chapter 3, "Predefined SAFs and the Request Handling Process."
system_fopenRO
opens a file for read-only access.
system_fopenRW
opens a file for read-write access, creating the file if necessary.
system_fopenWA
opens a file for write-append access, creating the file if necessary.
system_fclose
closes a file.
system_fread
reads from a file.
system_fwrite
writes to a file.
system_fwrite_atomic
locks the given file before writing to it. This avoids interference between simultaneous writes by multiple processes or threads.
netbuf_grab
reads from a network buffer's socket into the network buffer.
netbuf_getc
gets a character from a network buffer.
net_write
writes to the network socket.
systhread_start
creates a new thread.
systhread_sleep
puts a thread to sleep for a given time.
crit_init
creates a new critical section variable.
crit_enter
gains ownership of a critical section.
crit_exit
surrenders ownership of a critical section.
crit_terminate
disposes of a critical section variable.
condvar_init
creates a new condition variable.
condvar_notify
awakens any threads blocked on a condition variable.
condvar_wait
blocks on a condition variable.
condvar_terminate
disposes of a condition variable.
daemon_atrestart
(Unix only) registers a user function to be called when the server is sent a restart signal (HUP) or at shutdown.
util_getline
gets the next line (up to a LF or CRLF) from a buffer.
util_hostname
gets the local hostname as a fully qualified domain name.
util_later_than
compares two dates.
util_sprintf
same as standard library routine sprintf()
.
util_strftime
same as standard library routine strftime()
.
util_uri_escape
converts the special characters in a string into URI escaped format.
util_uri_unescape
converts the URI escaped characters in a string back into special characters.
Init
stage must conform to different requirements than SAFs to be invoked during the Service
stage.
The rq
parameter is the primary mechanism for passing along information throughout the request-response process. On input to a SAF, rq
contains whatever values were inserted or modified by previously executed SAFs. On output, rq
contains any modifications or additional information inserted by the SAF. Some SAFs depend on the existence of specific information provided at an earlier step in the process. For example, a PathCheck SAF retrieves values in rq->vars
which were previously inserted by an AuthTrans SAF.
This section outlines the expected behavior of SAFs used at each stage in the request handling process.
rq
and sn
are NULL
.daemon_atrestart()
to clean up.error
parameter into pb
describing the error and return REQ_ABORTED
.REQ_PROCEED
.Authorization
header in rq->headers
which contains the authorization type and uu-encoded user and password information. If header was not sent return REQ_NOACTION
.auth-type
, plus auth-user
and/or auth-group
parameter in rq->vars
to be used later by PathCheck
SAFs.REQ_PROCEED
if the user was successfully authenticated, REQ_NOACTION
otherwise.ppath
in rq->vars
) to convert it into a full local file system path.REQ_PROCEED
if ppath
in rq->vars
contains the full local file system path, or REQ_NOACTION
if not.ppath
in rq->vars
to /URL
. Add url
to rq->vars
with full URL (for example., http://home.netscape.com/
). Return REQ_PROCEED
.auth-type
, auth-user
and/or auth-group
in rq->vars.
REQ_PROCEED
if user (and group) is authorized for this area (ppath
in rq->vars
).WWW-Authenticate
to rq->srvhdrs
with a value such as: Basic; Realm=\"Our private area\"
. Call protocol_status()
to set HTTP response status to PROTOCOL_UNAUTHORIZED
. Return REQ_ABORTED
.content-type
in rq->srvhdrs
already exists, return REQ_NOACTION
.content-type
in rq->srvhdrs
REQ_PROCEED
if content-type
is created, REQ_NOACTION
otherwisetype
, method
, and query
specified in the directive in obj.conf
match the request.content-type
from rq->srvhdrs
. Insert correct content-type
in rq->srvhdrs
. rq->srvhdrs
.protocol_status
to set HTTP response status.protocol_start_response
to send HTTP response and headers.net_write
.REQ_PROCEED
if successful, REQ_EXIT
on write error, REQ_ABORTED
on other failures.code
and reason
specified in the directive in obj.conf
match the current error.AddLog
SAFs can use any data available in pb
, sn
, or rq
to log this transaction.REQ_PROCEED
.Last Updated: 03/01/00 09:22:11
© Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.
[an error occurred while processing this directive]