[0001]
[0002]
[0003]
[0004]
[0005]
[0006]
[0007]
[0008]
[0009]
[0010]
[0011]
[0012]
[0013]
[0014]
[0015]
[0016]
[0017]
[0018]
[0019]
[0020]
[0021]
[0022]
[0023]
[0024]
[0025]
[0026]
[0027]
[0028]
[0029]
[0030]
[0031]
[0032]
[0033]
[0034]
[0035]
[0036]
[0037]
[0038]
[0039]
[0040]
[0041]
[0042]
[0043]
[0044]
[0045]
[0046]
[0047]
[0048]
[0049]
[0050]
[0051]
[0052]
[0053]
[0054]
[0055]
[0056]
[0057]
[0058]
[0059]
[0060]
[0061]
[0062]
[0063]
[0064]
[0065]
[0066]
[0067]
[0068]
[0069]
[0070]
[0071]
[0072]
[0073]
[0074]
[0075]
[0076]
[0077]
[0078]
[0079]
[0080]
[0081]
[0082]
[0083]
[0084]
[0085]
[0086]
[0087]
[0088]
[0089]
[0090]
[0091]
[0092]
[0093]
[0094]
[0095]
[0096]
[0097]
[0098]
[0099]
[0100]
[0101]
[0102]
[0103]
[0104]
[0105]
[0106]
[0107]
[0108]
[0109]
[0110]
[0111]
[0112]
[0113]
[0114]
[0115]
[0116]
[0117]
[0118]
[0119]
[0120]
[0121]
[0122]
[0123]
[0124]
[0125]
[0126]
[0127]
[0128]
[0129]
[0130]
[0131]
[0132]
[0133]
[0134]
[0135]
[0136]
[0137]
[0138]
[0139]
[0140]
[0141]
[0142]
[0143]
[0144]
[0145]
[0146]
[0147]
[0148]
[0149]
[0150]
[0151]
[0152]
[0153]
[0154]
[0155]
[0156]
[0157]
[0158]
[0159]
[0160]
[0161]
|1ISAPI|

|^ ISAPI (procounced |/eye-sap-ee||) was developed by Process Software
Corporation (the developer of Purveyor Encrypt Web Server available under VMS),
Microsoft Corporation and a small number of other vendors.  It has an software
infrastructure similar to CGI but a different architecture.  It is designed to
eliminate the expensive process creation overheads of CGI (under Unix, let
alone VMS), reduce latency for expensive-to-activate resources, and generally
improve server throughput, particularly on busy sites.

|^ Unlike standard CGI, which creates a child process to service each request,
ISAPI is designed to load additional sharable code (DLLs, or Dynamic Link
Libraries in MSWindows, shareable images under VMS) into the Web server's
process space. These are known as server |/extensions||. This radically reduces
the overheads of subsequent request processing and makes possible server
functionality that can maintain resources between requests (for instance keep
open a large database), again contributing to reduced latency and increased
throughput.

|^ Of course there is a down-side!  Loading foreign executable code into the
server compromises its integrity.  Poorly written extensions can seriously
impact server performance and in the worst-case even crash a server process.
The other significant concern is the multi-threaded environment of most
servers.  Extensions must be carefully constructed so as not to impact the
granularity of processing in a server and to be |/thread-safe||, not creating
circumstances where processing corruption or deadlock occurs.

|2CGIsapi|

|^ WASD provides an environment for executing ISAPI based extensions.  Unlike
classic ISAPI the DLLs are not loaded into server space but into autonomous
processes, in much the same way as CGIplus scripts are handled
(|link|CGIplus||).  This still offers significantly improved performance
through the persistance of the ISAPI extension between requests.  Measurements
show a potential five-fold, to in excess of ten-fold increase in throughput 
compared to an equivalent CGI script!  This is comparable to reported
performance differences between the two environments in the Microsoft IIS
environment.

|^ While the script process context does add more overhead than if the DLL was  
loaded directly into the server process space, it does have two significant
advantages.

|number|

|item| Buggy DLL code will generally not directly affect the integrity of the
server process.  At worst the script process may terminate.

|item| Each process services only the one request at a time.  This eliminates
the threading issues.

|!number|

|^ WASD implements the ISAPI environment as an instance of its CGIplus
environment.  CGIplus shares two significant characteristics with ISAPI,
persistance and a CGI-like environment.  This allows a simple CGIplus
|/wrapper| script to be used to load and interface with the ISAPI DLL. After
being loaded the ISAPI-compliant code cannot tell the difference between the
WASD environment and any other vanilla ISAPI one!

|^ This wrapper is known as |*CGIsapi| (pronounced |/.see-gee-eye-sap-ee||).

|^ Wrapping another layer does introduce overhead not present in
the native CGIplus itself, however measurements indicate in |/the real
world| (tm) performance of the two is quite comparable. See
|link%|../features/##Server Performance++in++WASD Features|
for further information.  The advantage of ISAPI over CGIplus is not
performance but the fact it's a well documented interface.  Writing a script to
that specification may be an easier option, particularly for sites with a
mixture or history of different Web servers, than learning the CGIplus
interface (simple as CGIplus is).

|2Writing ISAPI Scripts|

|^ This section is by-no-means a tutorial on how to write for ISAPI.

|^ First, get a book on ISAPI.  Second, ignore most of it!  Generally these
tomes concentrate on the Microsoft environment.  Still, information on the
basic behaviour of ISAPI extensions and the Internet Server API is valuable. 
Other resources are available at no cost from the Microsoft and Process
Software Corporation sites.

|^ Have a look at the WASD example DLL and its build procedure in
|link%=|/wasd_root/src/cgiplus/*isapi*.*?httpd=index&readme=no|\
WASD_ROOT:[SRC.CGIPLUS]|

|^ The CGIsapi wrapper,
|link%=|/wasd_root/src/cgiplus/cgisapi.c|WASD_ROOT:[SRC.CGIPLUS]CGISAPI.C||,
is relatively straight-forward, relying on CGIplus for IPC with the parent
server process.  A brief description of the detail of the implementation is
provided in the source code.

|^ CGIsapi has a simple facility to assist with debugging DLLs. When enabled,
information on passed parameters is output whenever a call is made to an ISAPI
function.  This debugging can be toggled on and off whenever desired.  Once
enabled DLL debugging remains active through multiple uses of a CGISAPI
instance, or until disabled, or until the particular CGISAPI process' lifetime
expires.  Check detail in the CGIsapi source code description.

|0CGIsapi Considerations||

|^ The wrapper is designed to be ISAPI 1.0 compliant.  It should also be
vanilla ISAPI 2.0 compliant (not the Microsoft WIN32 variety, so don't think
you'll necessarily be able to grab all those IIS extensions and just recompile
and use ;^)

|^ With CGIsapi multiple instances of any one extension may be active on the
one  server (each in an autonomous process, unlike a server-process-space
loaded extension where only one would ever be active at any one time).  Be
aware this could present different concurrency issues than one multiple or
single threaded instance.

|^ When CGIplus processes are idle they can be run-down at any time by the
server at expiry of lifetime or to free up required server resources.  For this
reason ISAPI extensions (scripts) should finalize the processing of
transactions when finished, not leave anything in a state where its unexpected
demise might corrupt resources or otherwise cause problems (which is fairly
good general advice anyway |=.;^)|  That is, when finished tidy up as much as
is necessary.

|^ CGIsapi loaded extensions can exit at any time they wish.  The process
context allows this.  Of course, normally a server-process-space loaded
instance would not be able to do so!

|^ For other technical detail refer to the description with the source code.

|note|
|0Hint!|
Whenever developing ISAPI extensions don't forget that after compiling,
the old version must be purged from the server before trying out the new!!!
|^ Scripting processes may be purged or deleted using (
"Techncial Overview, Server Command Line Control"):
|code|
$ HTTPD /DO=DCL=DELETE
$ HTTPD /DO=DCL=PURGE
|!code|
|!note|

|2Server Configuration|

|^ Ensure the following are in the appropriate sections of WASD_CONFIG_GLOBAL.

|code|
[DclScriptRunTime]
.DLL  $CGI-BIN:[000000]CGISAPI.EXE

[AddType]
.DLL  application/octet-stream  -  ISAPI extension DLL
|!code|

|^ Ensure this rule exists in the scripting section of WASD_CONFIG_MAP.

|code|
exec+ /isapi/* /cgi-bin/*
|!code|

|^ With this rule DLLs may be accessed using something like

|code|
http://host.name.domain/isapi/isapiexample.dll
|!code|