[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] [0162] [0163] [0164] [0165] [0166] [0167] [0168] [0169] [0170] [0171] [0172] [0173] [0174] [0175] [0176] [0177] [0178] [0179] [0180] [0181] [0182] [0183] [0184] [0185] [0186] [0187] [0188] [0189] [0190] [0191] [0192] [0193] [0194] [0195] [0196] [0197] [0198] [0199] [0200] [0201] [0202] [0203] [0204] [0205] [0206] [0207] [0208] [0209] [0210] [0211] [0212] [0213] [0214] [0215] [0216] [0217] [0218] [0219] [0220] [0221] [0222] [0223] [0224] [0225] [0226] [0227] [0228] [0229] [0230] [0231] [0232] [0233] [0234] [0235] [0236] [0237] [0238] [0239] [0240] [0241] [0242] [0243] [0244] [0245] [0246] [0247] [0248] [0249] [0250] [0251] [0252] [0253] [0254] [0255] [0256] [0257] [0258] [0259] [0260] [0261] [0262] [0263] [0264] [0265] [0266] [0267] [0268] [0269] [0270] [0271] [0272] [0273] [0274] [0275] [0276] [0277] [0278] [0279] [0280] [0281] [0282] [0283] [0284] [0285] [0286] [0287] [0288] [0289] [0290] [0291] [0292] [0293] [0294] [0295] [0296] [0297] [0298] [0299] [0300] [0301] [0302] [0303] [0304] [0305] [0306] [0307] [0308] [0309] [0310] [0311] [0312] [0313] [0314] [0315] [0316] [0317] [0318] [0319] [0320] [0321] [0322] [0323] [0324] [0325] [0326] [0327] [0328] [0329] [0330] [0331] [0332] [0333] [0334] [0335] [0336] [0337] [0338] [0339] [0340] [0341] [0342] [0343] [0344] [0345] [0346] [0347] [0348] [0349] [0350] [0351] [0352] [0353] [0354] [0355] [0356] [0357] [0358] [0359] [0360] [0361] [0362] [0363] [0364] [0365] [0366] [0367] [0368] [0369] [0370] [0371] [0372] [0373] [0374] [0375] [0376] [0377] [0378] [0379] [0380] [0381] [0382] [0383] [0384] [0385] [0386] [0387] [0388] [0389] [0390] [0391] [0392] [0393] [0394] [0395] [0396] [0397] [0398] [0399] [0400] [0401] [0402] [0403] [0404] [0405] [0406] [0407] [0408] [0409] [0410] [0411] [0412] [0413] [0414] [0415] [0416] [0417] [0418] [0419] [0420] [0421] [0422] [0423] [0424] [0425] [0426] [0427] [0428] [0429] [0430] [0431] [0432] [0433] [0434] [0435]
<!DOCTYPE html> <!-- WASDOC AXP-2.0.0 (CGILIB AXP-1.9.9) --> <!-- wasDOC Copyright (C) 2019,2020 Mark G.Daniel - Apache-2.0 licenced --> <!-- 3-NOV-2021 02:57 --> <noscript>NOTE: SOME FUNCTIONALITY EMPLOYS JAVASCRIPT</noscript> <div id="erreport1" style="display:none;"></div> <script> function errorReport(string) { for (var cnt = 1; cnt <= 2; cnt++) { var err = document.getElementById('erreport'+cnt); err.style.display = 'block'; err.innerHTML += string; } } </script> <style type="text/css"> html { font-family: arial, verdana, sans-serif; font-size:12pt; margin:1em; } h1 { font-size:124%; font-style:bold; margin-top:1em; margin-bottom:0.5em; } h2 { font-size:120%; font-style:bold; margin-top:1.1em; margin-bottom:0.4em; } h3 { font-size:116%; font-style:bold; margin-top:1.0em; margin-bottom:0.3em; } h4 { font-size:112%; font-style:bold; margin-top:1.1em; margin-bottom:0.3em; } h5 { font-size:112%; font-style:bold; margin-top:1.1em; margin-bottom:0.3em; } h6 { font-size:112%; font-style:bold; padding:0; margin:0; } h1 .text { text-decoration:underline; } h1 .numb { padding-right:0.8em; } h1 .numb:empty { display:none; padding-right:0; } h2 .numb { padding-right:0.8em; } h2 .numb:empty { display:none; padding-right:0; } h3 .numb { padding-right:0.8em; } h3 .numb:empty { display:none; padding-right:0; } h4 .numb { padding-right:0.8em; } h4 .numb:empty { display:none; padding-right:0; } h5 .numb { display:none; padding-right:0; } h6 .numb { display:none; padding-right:0; } kbd { font-family:monospace; } noscript { font-size:1.2em; } p { line-height:1.1em; margin-top:1em; margin-bottom:1em; } .chunk { font-size:130%; text-decoration:underline; } .head {} .high {} .bold { font-weight:bold; } .center { text-align:center; } .italic { font-style:italic; } .left { text-align:left; } .nowrap { white-space:nowrap; } .prewrap { white-space:pre; } .right { text-align:right; } .strike { text-decoration:line-through; } .under { text-decoration:underline; } .backlight { background-color:#f2f2f2; } .display0 { display:none; } img { max-width:100%; } .imglink { } .link { } .blank { } .list { margin-bottom:1em; } .list li { margin-top:0.5em; } .list0 li { margin-top:0; } .item {} .tabl { border-collapse:collapse; text-align:left; margin:0.4em 2em 0.5em 2em; } .tabu { border-collapse:collapse; text-align:right; margin:0.4em 2em 0.5em 2em; } .tabr { vertical-align:top; } .tabh { padding:0.2em 0 0 2em; margin:0; } .tabd { padding:0.1em 0 0 2em; margin:0; } .tabh:first-of-type, td:first-of-type { padding-left:0; } .tabu .tabh, .tabu .tabd { border:1px solid gray; padding:0.2em 0.3em 0.2em 0.3em; } .tab0 { border:none; visibility:hidden; max-width:1em; white-space:nowrap; overflow:hidden; } .tabauto { margin-left:auto; margin-right:auto; } .tabr:empty { height:0.2em; } .tabu .tabh:empty, .tabu .tabd:empty { border:none; visibility:hidden; } .error { font-size:110%; color:black; background-color:yellow; font-family:sans-serif; font-weight:bold; font-style:normal; width:95%; border:solid 1px gray; padding:0.5em 1em 0.5em 1em; } .error::before { content:'\026a0\00a0'; } .image { } .page { width:98%; border:1px dashed gray; margin:1.5em 0 1.8em 0; } .epage { width:98%; border:1px dashed black; margin:1.5em 0 1.8em 0; } .monosp { font-family:monospace; } .ppage { display:none; } .simple { list-style-type:none; } .valtop { vertical-align:top; } .valmid { vertical-align:middle; } .valbot { vertical-align:bottom; } .code { border-style:solid; border-width:0 0 0 1px; padding-left:1em; font-family:monospace; white-space:pre; } .block { } .blockof { margin:0.4em 2em 0.5em 2em; } .example { border-style:dashed; border-width:0 0 0 1px; padding-left:1em; margin-top:0.5em; margin-bottom:0.5em; white-space:pre; } .indent { margin-left:2em; margin-right:2em; } .noindent { margin-left:0; margin-right:0; } .inblock { display:inline-block; } .mono { white-space:pre; font-family:monospace; } .note { margin:0.4em 2em 0.5em 2em; page-break-inside:avoid; } .note h5 { margin-top:0 } .note_hr { width:80%; border:1px solid gray; } .prop { padding-left:1em; margin-top:0.5em; margin-bottom:0.5em; } .quote { border-style:dashed; border-width:0 0 0 1px; padding-left:1em; margin-top:0.5em; margin-bottom:0.5em; } .this { display:none; } a:link,a:visited { color:black; text-decoration:none; } a:hover,a:active { text-decoration:underline; } a:focus { outline:0; } :target:before { content:''; display:block; height:0.1em; margin:-0.1em; } a.link:link, a.link:visited,a.link:active { color:midnightBlue; text-decoration:underline; text-decoration-style:solid; } .TOC1cols1 { width:80%; max-width:80%; } .TOC1cols2 { column-count:2; width:80%; max-width:80%; } .TOC1cols3 { column-count:3; max-width:90%; max-width:90%; } .TOC1cols4 { column-count:4; max-width:100%; max-width:100%; } .TOC1table { margin-left:2em; white-space:nowrap; break-inside:auto; } .TOC1table tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; } .TOC1table td+td { padding:0 0 0 0.5em; } .TOC1table .numb { width:3em; max-width:3em; } .TOC1table .sepr { width:5em; max-width:6em; overflow:hidden; } .TOC1table .majr { font-weight:bold; } .TOC1table .text { white-space:normal; } /* These are due to Firefox (at least <= 76) recalcitrant multi-column handling. Web search "Split table into css columns, issue in Firefox" (stackoverflow). "Good grief, Charlie Brown!" */ .TOC1cols2 table, .TOC1cols2 tbody, .TOC1cols2 tr, .TOC1cols3 table, .TOC1cols3 tbody, .TOC1cols3 tr, .TOC1cols4 table, .TOC1cols4 tbody, .TOC1cols4 tr { display:block; padding:0; } .TOC2cols1 { width:60%; max-width:60%; } .TOC2cols2 { column-count:2; width:70%; max-width:70%; } .TOC2cols3 { column-count:3; width:80%; max-width:80%; } .TOC2cols4 { column-count:4; width:90%; max-width:90%; } .TOC2table { margin-left:2em; white-space:nowrap; break-inside:auto; } .TOC2table tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; } .TOC2table .numb { font-weight:bold; padding-right:0.5em; } .TOC2table .text { width:100%; white-space:normal; } /* see "recalcitrant" above */ .TOC2cols2 table, .TOC2cols2 tbody, .TOC2cols2 tr, .TOC2cols3 table, .TOC2cols3 tbody, .TOC2cols3 tr, .TOC2cols4 table, .TOC2cols4 tbody, .TOC2cols4 tr { display:block; padding:0; } .NAVtable { margin:0.1em 0 0 2em; } .NAVtable td { font-size:110%; font-weight:bold; padding:0; margin:0; } .NAVtable a { padding:0 0.5em 0 0.5em; text-decoration:none; } .IDXcols1 { width:80%; max-width:80%; } .IDXcols2 { column-count:2; width:90%; max-width:90%; } .IDXcols3 { column-count:3; width:95%; max-width:95%; } .IDXcols4 { column-count:4; width:100%; max-width:100%; } .IDXtable { margin:1em 0 1em 2em; white-space:nowrap; break-inside:auto; } .IDXtable tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; } .IDXtable .alpha { font-weight:bold; min-width:2em; } .IDXtable .text { width:100%; white-space:normal; } .IDXtable .para:before { content:'\00b6\00a0'; } /* see "recalcitrant" above */ .IDXcols2 table, .IDXcols2 tbody, .IDXcols2 tr, .IDXcols3 table, .IDXcols3 tbody, .IDXcols3 tr, .IDXcols4 table, .IDXcols4 tbody, .IDXcols4 tr { display:block; padding:0; } .insight { background-color:cyan; font-family:monospace; padding:0 0.2em 0 0.2em; margin:0 0.2em 0 0.2em; font-size:100%; font-style:normal; font-weight:normal; text-decoration:none; } .wasdoc { font-family: "Lucida Console", Monaco, monospace; letter-spacing:-0.07em; } @media screen { .blank::after { content:"\2924"; } .print { display:none; } } @media print { table { page-break-inside:avoid; } .noprint { display:none; } .page { border:none; page-break-after: always; } .epage { display:none; } .ppage { page-break-after:always; } .NAVtable { display:none; } .NAVprint { display:block!important; } } @page { margin:2cm 1cm 2cm 1cm; } </style> <!-- source:0000_SCRIPTING.WASDOC --> <style type="text/css">._smiley::after { font-size:150%; vertical-align:middle; content:'\263a' }</style> <style type="text/css">._frowny::after { font-size:150%; vertical-align:middle; content:'\2639' }</style> <a id="0." href="#"></a> <title>WASD Scripting Environment – ISAPI</title> <a id="7." href="#"></a> <a id="7.isapi" href="#"></a> <a id="isapi" href="#"></a> <h1 class="head chunk">WASD Scripting Environment</h1> <h1 class="head"><span class="numb">7.</span><span class="text">ISAPI</span></h1> <table class="TOC2table"> <tr><td><a href="scripting007.html#7.1.cgisapi"><span class="numb">7.1</span><span class="text">CGIsapi</span></a> <tr><td><a href="scripting007.html#7.2.writingisapiscripts"><span class="numb">7.2</span><span class="text">Writing ISAPI Scripts</span></a> <tr><td><a href="scripting007.html#7.3.serverconfiguration"><span class="numb">7.3</span><span class="text">Server Configuration</span></a> </table> </div> <table class="NAVtable NAVprint"><tr> <td><a href="javascript:window.history.back();">↩︎</a> <td><a href="scripting006.html#6.">↖︎</a> <td><a href="scripting000.html#0.">↑︎</a> <td><a href="scripting008.html#8.">↘︎</a> <td><a href="javascript:window.history.forward();">↪︎</a> </table> <p> ISAPI (procounced <span class="high italic">eye-sap-ee</span>) 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. <p> 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 <span class="high italic">extensions</span>. 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. <p> 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 <span class="high italic">thread-safe</span>, not creating circumstances where processing corruption or deadlock occurs. <a id="7.1" href="#"></a> <a id="7.1.cgisapi" href="#"></a> <a id="cgisapi" href="#"></a> <h2 class="head"><span class="numb">7.1</span><span class="text">CGIsapi</span></h2> <p> 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 (<a class="link" href="scripting003.html#3.cgiplus">3. CGIplus</a>). 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. <p> 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. <ol class="list"> <li class="item"> Buggy DLL code will generally not directly affect the integrity of the server process. At worst the script process may terminate. <li class="item"> Each process services only the one request at a time. This eliminates the threading issues. </ol> <p> 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 <span class="high italic">wrapper</span> 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! <p> This wrapper is known as <span class="high bold">CGIsapi</span> (pronounced <span class="high italic">see-gee-eye-sap-ee</span>). <p> Wrapping another layer does introduce overhead not present in the native CGIplus itself, however measurements indicate in <span class="high italic">the real world</span> (tm) performance of the two is quite comparable. See <a class="link blank" target="_blank" href="../features/#serverperformance">Server Performance</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a> 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). <a id="7.2" href="#"></a> <a id="7.2.writingisapiscripts" href="#"></a> <a id="writingisapiscripts" href="#"></a> <h2 class="head"><span class="numb">7.2</span><span class="text">Writing ISAPI Scripts</span></h2> <p> This section is by-no-means a tutorial on how to write for ISAPI. <p> 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. <p> Have a look at the WASD example DLL and its build procedure in <a class="link blank monosp" target="_blank" href="/wasd_root/src/cgiplus/*isapi*.*?httpd=index&readme=no">WASD_ROOT:[SRC.CGIPLUS]</a> <p> The CGIsapi wrapper, <a class="link blank monosp" target="_blank" href="/wasd_root/src/cgiplus/cgisapi.c">WASD_ROOT:[SRC.CGIPLUS]CGISAPI.C</a>, 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. <p> 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. <a id="7.2.0.0.1" href="#"></a> <a id="7.2.cgisapiconsiderations" href="#"></a> <a id="cgisapiconsiderations" href="#"></a> <h5 class="head"><span class="text">CGIsapi Considerations</span></h5> <p> 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 ;^) <p> 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. <p> 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 <span class="high monosp">;^)</span> That is, when finished tidy up as much as is necessary. <p> 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! <p> For other technical detail refer to the description with the source code. <div class="note"> <a id="7.2.0.0.2" href="#"></a> <a id="7.2.hint" href="#"></a> <a id="hint" href="#"></a> <h5 class="head center"><span class="text">Hint!</span></h5> <hr class="note_hr"> Whenever developing ISAPI extensions don't forget that after compiling, the old version must be purged from the server before trying out the new!!! <p> Scripting processes may be purged or deleted using ( "Techncial Overview, Server Command Line Control"): <div class="blockof code">$ HTTPD /DO=DCL=DELETE $ HTTPD /DO=DCL=PURGE </div> <hr class="note_hr"> </div> <a id="7.3" href="#"></a> <a id="7.3.serverconfiguration" href="#"></a> <a id="serverconfiguration" href="#"></a> <h2 class="head"><span class="numb">7.3</span><span class="text">Server Configuration</span></h2> <p> Ensure the following are in the appropriate sections of WASD_CONFIG_GLOBAL. <div class="blockof code">[DclScriptRunTime] .DLL $CGI-BIN:[000000]CGISAPI.EXE [AddType] .DLL application/octet-stream - ISAPI extension DLL </div> <p> Ensure this rule exists in the scripting section of WASD_CONFIG_MAP. <div class="blockof code">exec+ /isapi/* /cgi-bin/* </div> <p> With this rule DLLs may be accessed using something like <div class="blockof code">http://host.name.domain/isapi/isapiexample.dll </div> <!-- source:0800_DECNET.WASDOC --> <table class="NAVtable NAVprint"><tr> <td><a href="javascript:window.history.back();">↩︎</a> <td><a href="scripting006.html#6.">↖︎</a> <td><a href="scripting000.html#0.">↑︎</a> <td><a href="scripting008.html#8.">↘︎</a> <td><a href="javascript:window.history.forward();">↪︎</a> </table>