Chapter 2 Creating
Custom Server Application Functions
This chapter describes how to write your own NSAPI plug-ins that define
custom Server Application Functions (SAFs). The ability to create custom plug-ins enables you to modify or extend the Sun Java System Web Server’s built-in
functionality. For example, you can modify the server to handle user authorization
in a special way or generate dynamic HTML pages based on information in a
database.
This chapter has the following sections:
Before writing custom
SAFs, you must familiarize yourself with the request-handling process, as
described in detail in the Sun Java System Web Server 7.0 Update 1 Administrator’s Configuration File Reference. Also, before writing a custom SAF, check
to see whether a built-in SAF already accomplishes the tasks you have in mind.
See Appendix B, Alphabetical List of NSAPI Functions and Macros for a list of the predefined Init SAFs.
For information about predefined SAFs used in the obj.conf file,
see the Sun Java System Web Server 7.0 Update 1 Administrator’s Configuration File Reference.
For a complete list of the NSAPI routines for implementing custom
SAFs, see Chapter 6, NSAPI Function and Macro Reference.
Future Compatibility Issues
To keep your custom plug-ins upgradable, do the following:
-
Make sure plug-in users know how to edit the configuration
files, such as magnus.conf and obj.conf manually. The plug-in installation software
should not be used to edit these configuration files.
-
Keep the source code so you can recompile the plug-in.
SAF Interface
All SAFs whether custom or built-in have the same C interface
regardless of the request-handling step for which they are written. SAFs are
small functions intended for a specific purpose within a specific request-response step.
SAFs receive parameters from the directive that invokes them in the obj.conf file, from the server, and from previous SAFs.
The C interface
for a SAF is:
int function(pblock *pb, Session *sn, Request *rq);
The next section discusses the parameters in detail.
The SAF returns a result code that indicates whether and how it succeeded.
The server uses the result code from each function to determine how to proceed
with processing the request. For more information on the result codes, see Result Codes.
SAF Parameters
This section discusses the SAF parameters in detail.
pb (Parameter Block) Parameter
The 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 the following:
AuthTrans fn=basic-ncsa auth-type=basic dbm=users.db
|
In this case, the pb parameter passed to basic-ncsa contains name-value pairs that correspond to auth-type=basic and dbm=users.db.
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. For information on working
with parameter blocks, see Parameter Block Manipulation Routines.
sn (Session) Parameter
The 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. For a list of important fields, see Session Data Structure.
rq(Request) Parameter
The 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. For a list of important fields, see Request Data Structure.
Result Codes
Upon completion, a SAF returns a result code. The result code indicates
what the server should do next.
The result codes are:
-
REQ_PROCEED—Indicates that the SAF achieved its objective. For some request-response
steps (AuthTrans, NameTrans, Service, and Error), this code tells the server to proceed to the
next request-response step, skipping any other SAFs in the current step. For
the other request-response steps (Input, Output, Route, PathCheck, ObjectType,
and AddLog), the server proceeds to the next SAF in the
current step.
-
REQ_NOACTION—Indicates that the SAF took no action. The server continues
with the next SAF in the current server step.
-
REQ_ABORTED
Indicates that an error
occurred and an HTTP response should be sent to the client to indicate the
cause of the error. A SAF returning REQ_ABORTED should
also set the HTTP response status code. If the server finds an Error directive
matching the status code or reason phrase, the server executes the SAF specified.
If not, the server sends a default HTTP response with the status code and
reason phrase, in addition to a short HTML page reflecting the status code
and reason phrase for the user. The server then goes to the first AddLog directive.
-
REQ_EXIT—Indicates
the connection to the client was lost. This code should be returned when the SAF fails
in reading or writing to the client. The server then goes to the first AddLog directive.
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 Chapter 6, NSAPI Function and Macro Reference.
For examples of custom SAFs, see Chapter 4, 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.
- SolarisTM 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.
- 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 you need to use for
compilation of your source code.
- 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 Initdirective 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.
Overview of NSAPI C Functions
NSAPI provides a set of C functions that are used to implement SAFs.
These functions serve several purposes:
-
Provide platform independence across operating system and
hardware platforms
-
Improved performance
-
Thread-safe, a requirement for SAFs
-
Prevent memory leaks
-
Provide functionality necessary for implementing SAFs
Always use these NSAPI routines when defining new SAFs.
This section provides an overview of the function categories available
and some of the more commonly used routines. All of the public routines are
detailed in Chapter 6, NSAPI Function and Macro Reference.
The main categories of NSAPI functions are:
Parameter Block Manipulation Routines
The parameter block manipulation functions provide routines for locating,
adding, and removing entries in a pblock data structure:
-
pblock_findval returns
the value for a given name in a pblock. For more information, see pblock_findval() Function.
-
pblock_nvinsert adds
a new name-value pair entry to a pblock. For more information, see pblock_nvinsert() Function.
-
pblock_remove removes
a pblock entry by name from a pblock.
The entry is not disposed. Use param_free() Function to
free the memory used by the entry. For more information, see pblock_remove() Function.
-
param_free frees the
memory for the given pblock entry. For more information, see param_free() Function.
-
pblock_pblock2str creates
a new string containing all of the name-value pairs from a pblock in
the form “name=value name=value.” This function can be a useful for debugging.
For more information, see pblock_pblock2str() Function.
Protocol Utilities for Service SAFs
Protocol utilities provide functionality necessary to implement Service SAFs:
Memory Management
Memory management routines provide fast, platform-independent versions
of the standard memory management routines. These routines also prevent memory leaks by allocating
from a temporary memory,
called “pooled” memory for each request, and then disposing
the entire pool after each request. Wrappers enable standard memory routines to use permanent memory. To
disable the server's pooled memory allocator for debugging,use the built-in SAF pool-init. For more information,
see the Sun Java System Web Server 7.0 Update 1 Administrator’s Configuration File Reference.
File I/O
The file I/O functions provide platform-independent, thread-safe file
I/O routines.
Network I/O
Network I/O functions provide platform-independent, thread-safe network
I/O routines. These routines work with SSL when it is enabled.
Threads
Thread functions include functions for creating your own threads that
are compatible with the server’s threads. Routines also exist for critical sections
and condition variables.
-
systhread_start creates
a new thread. For more
information, see systhread_start() Function.
-
systhread_sleep puts
a thread to sleep for a given time. For more information, see systhread_sleep() Function.
-
crit_init creates a
new critical section variable.
For more information, see crit_init() Function.
-
crit_enter gains ownership
of a critical section.
For more information, see crit_enter() Function.
-
crit_exit surrenders
ownership of a critical section. For more information, see crit_exit() Function.
-
crit_terminate disposes
of a critical section variable.
For more information, see crit_terminate() Function.
-
condvar_init creates
a new condition variable.
For more information, see condvar_init() Function.
-
condvar_notify awakens
any threads blocked on a condition variable. For more information, see condvar_notify() Function.
-
condvar_wait blocks
on a condition variable.
For more information, see condvar_wait() Function.
-
condvar_terminate disposes
of a condition variable.
For more information, see condvar_terminate() Function.
-
prepare_nsapi_thread enables threads that are not
created by the server to act like server-created threads. For more information, see prepare_nsapi_thread() Function.
Utilities
Utility functions include platform-independent, thread-safe versions
of many standard library functions such as string manipulation, as well as new utilities
useful for NSAPI.
-
daemon_atrestart registers
a user function to be called when the server is sent a restart signal (HUP) or at shutdown.
For more information, see daemon_atrestart() Function.
-
daemon_atrestart gets the
local host name as a fully qualified domain name. For more information, see util_hostname() Function.
-
util_later_than compares
two dates. For more information,
see util_later_than() Function.
-
util_sprintf is the
same as the standard library routine sprintf(). For more information, see util_sprintf() Function.
-
util_strftime is the
same as the standard library routine strftime(). For more information, see util_strftime() Function.
-
util_uri_escape converts
the special characters in a string into URI-escaped format. For more information, see util_uri_escape() Function.
-
util_uri_unescapeconverts
the URI-escaped characters in a string back into special characters. For more information, see util_uri_unescape() Function.
Note –
You cannot use an embedded null in a string, because NSAPI functions
assume that a null is the end of the string. Therefore, passing Unicode-encoded content through an NSAPI
plug-in does not work.
Virtual Server
The virtual server functions provide routines for retrieving information
about virtual servers.
-
request_get_vsfinds
the virtual server to which a request is directed. For more information, see request_get_vs() Function.
-
vs_alloc_slot allocates
a new slot for storing a pointer to data specific to a certain virtual server. For more information, see vs_alloc_slot() Function.
-
vs_get_data finds the
value of a pointer to data for a given virtual server and slot. For more information, see vs_get_data() Function.
-
vs_get_default_httpd_objectobtains a pointer
to the default or
root
object from the virtual server's virtual server class configuration. For more information, see vs_get_default_httpd_object() Function.
-
vs_get_doc_rootfinds the document
root for a virtual server.
For more information, see vs_get_doc_root() Function.
-
vs_get_httpd_objset obtains
a pointer to the virtual server class configuration for a given virtual server. For more information, see
-
vs_get_id finds
the ID of a virtual server.
For more information, see vs_get_id() Function.
-
vs_get_mime_type determines
the MIME type that would be returned in the content-type: header
for the given URI. For
more information, see vs_get_mime_type() Function.
-
vs_lookup_config_var finds
the value of a configuration variable for a given virtual server. For more information, see vs_lookup_config_var() Function.
-
vs_register_cb enables a plug-in to register
functions that will receive notifications of virtual server initialization
and destruction events.
For more information, see vs_register_cb() Function.
-
vs_set_data sets
the value of a pointer to data for a given virtual server and slot. For more information, see vs_set_data() Function.
-
vs_translate_uri translates
a URI as though it were part of a request for a specific virtual server. For more information, see vs_translate_uri() Function.
Required Behavior of SAFs for Each Directive
When writing a new SAF, you should define it to accomplish certain actions,
depending on which stage of the request-handling process will invoke it. For
example, SAFs to be invoked during the 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 that
were previously inserted by an AuthTrans SAF.
This section outlines the expected behavior of SAFs used at each stage
in the request-handling process. The SAFs are described in the following sections:
For more detailed
information about these SAFs, see the Sun Java System Web Server 7.0 Update 1 Administrator’s Configuration File Reference.
Init() SAFs
-
Purpose: Initialize at startup.
-
Called at server startup and restart.
-
rq and sn are NULL.
-
Initialize any shared resources such as files and global variables.
-
Can register callback function with daemon_atrestart() to
clean up.
-
On error, insert error parameter into pb describing the error and return REQ_ABORTED.
-
If successful, return REQ_PROCEED.
AuthTrans() SAFs
-
Purpose: Verify any authorization information.
-
Return REQ_PROCEED if the user was successfully
and completely authenticated, REQ_NOACTION otherwise.
NameTrans() SAFs
-
Purpose: Convert logical URI to physical path.
-
Perform operations on logical path (ppath in rq->vars) to convert it into a full local file system path.
-
Return REQ_PROCEED if ppath in rq->vars contains the full local file system path, or REQ_NOACTION if not.
-
To redirect the client to another site, add url to rq->vars with full URL. For example, http://www.sun.com/. Call protocol_status() to set HTTP response status to PROTOCOL_REDIRECT, NULL. Return REQ_ABORTED.
PathCheck() SAFs
-
Purpose: Check path validity and user’s access rights.
-
Check auth-type, auth-user,
and/or auth-group in rq->vars.
-
Return REQ_PROCEED if user and group is authorized for this area, ppath in rq->vars.
-
If not authorized, insert 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.
ObjectType() SAFs
-
Purpose: Determine content-type of data.
-
If content-type in rq->srvhdrs already
exists, return REQ_NOACTION.
-
Determine the MIME type and create content-type in rq->srvhdrs
-
Return REQ_PROCEED if content-type is
created, REQ_NOACTION otherwise.
Input() SAFs
-
Purpose: Insert filters that process incoming (client-to-server)
data.
-
Input SAFs are executed when a plug-in
or the server first attempts to read entity body data from the client.
-
Input SAFs are executed at most once per
request.
-
Return REQ_PROCEED to indicate success,
or REQ_NOACTION to indicate it performed no action.
Output() SAFs
-
Purpose: Insert filters that process outgoing server-to-client data.
-
Output SAFs are executed when a plug-in
or the server first attempts to write entity body data from the client.
-
Output SAFs are executed at most once per
request.
-
Return REQ_PROCEED to indicate success,
or REQ_NOACTION to indicate it performed no action.
Service() SAFs
-
Purpose: Generate and send the response to the client.
-
A Service SAF is only called if each of
the optional parameters type, method,
and query specified in the directive in obj.conf match
the request.
-
Remove existing content-type from rq->srvhdrs. Insert correct content-type in rq->srvhdrs.
-
Create any other headers in rq->srvhdrs.
-
Call protocol_status to set HTTP response status. For more information, see protocol_status() Function.
-
Call protocol_start_response to send HTTP response and headers. For more information, see protocol_start_response() Function.
-
Generate and send data to the client using net_write. For more information,
see net_write() Function.
-
Return REQ_PROCEED if successful, REQ_EXIT on write error, REQ_ABORTED on other failures.
Error() SAFs
-
Purpose: Respond to an HTTP status error condition.
-
The Error SAF is only called if each of
the optional parameters code and reason specified
in the directive in obj.conf match the current error.
-
Error SAFs do the same as Service SAFs,
but only in response to an HTTP status error condition.
AddLog() SAFs
-
Purpose: Log the transaction to a log file.
-
AddLog SAFs can use any data available
in pb, sn, or rq to
log this transaction.
-
Return REQ_PROCEED.
CGI to NSAPI Conversion
.The CGI environment variables
are not available to NSAPI.
Therefore, if you need to convert a CGI variable into an SAF using NSAPI, you retrieve them from the NSAPI parameter blocks. The following table indicates how each CGI
environment variable can be obtained in NSAPI.
Keep in mind that your code must be thread-safe under NSAPI. You should
use NSAPI functions that are thread-safe. Also, you should use the NSAPI memory
management and other routines for speed and platform independence.
Table 2–2 Parameter Blocks
for CGI Variables
|
CGI getenv()
|
NSAPI
|
|
AUTH_TYPE
|
pblock_findval("auth-type", rq->vars);
|
|
AUTH_USER
|
pblock_findval("auth-user", rq->vars);
|
|
CONTENT_LENGTH
|
pblock_findval("content-length", rq->headers);
|
|
CONTENT_TYPE
|
pblock_findval("content-type", rq->headers);
|
|
GATEWAY_INTERFACE
|
"CGI/1.1"
|
|
HTTP_*
|
pblock_findval( "*", rq->headers); (* is lowercase;
dash replaces underscore)
|
|
PATH_INFO
|
pblock_findval("path-info", rq->vars);
|
|
PATH_TRANSLATED
|
pblock_findval("path-translated", rq->vars);
|
|
QUERY_STRING
|
pblock_findval("query", rq->reqpb);
|
|
REMOTE_ADDR
|
pblock_findval("ip", sn->client);
|
|
REMOTE_HOST
|
session_dns(sn) ? session_dns(sn) : pblock_findval("ip", sn->client);
|
|
REMOTE_IDENT
|
pblock_findval( "from", rq->headers);(not usually available)
|
|
REMOTE_USER
|
pblock_findval("auth-user", rq->vars);
|
|
REQUEST_METHOD
|
pblock_findval("method", req->reqpb);
|
|
SCRIPT_NAME
|
pblock_findval("uri", rq->reqpb);
|
|
SERVER_NAME
|
char *util_hostname();
|
|
SERVER_PORT
|
conf_getglobals()->Vport; (as a string)
|
|
SERVER_PROTOCOL
|
pblock_findval("protocol", rq->reqpb);
|
|
SERVER_SOFTWARE
|
system_version()
|
|
Sun Java System-specific:
|
|
CLIENT_CERT
|
pblock_findval("auth-cert", rq->vars) ;
|
|
HOST
|
char *session_maxdns(sn);(may be null)
|
|
HTTPS
|
security_active ? "ON" : "OFF";
|
|
HTTPS_KEYSIZE
|
pblock_findval("keysize", sn->client);
|
|
HTTPS_SECRETKEYSIZE
|
pblock_findval("secret-keysize", sn->client);
|
|
SERVER_URL
|
protocol_uri2url_dynamic("","", sn, rq);
|