httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@locus.apache.org
Subject cvs commit: apache-2.0/src/os/win32 mod_isapi.c
Date Tue, 03 Oct 2000 06:08:37 GMT
wrowe       00/10/02 23:08:37

  Modified:    htdocs/manual/mod mod_isapi.html directives.html
               src/os/win32 mod_isapi.c
  Log:
    Ok... I've been waiting to find out what happens when we commit to two
    trees at once.  To that end, this is the caching and rather stable 2.0
    mod_isapi, with the docs brought over from 1.3 and freshened a bit.
  
  Revision  Changes    Path
  1.7       +343 -40   httpd-docs-2.0/htdocs/manual/mod/mod_isapi.html
  
  Index: mod_isapi.html
  ===================================================================
  RCS file: /home/cvs/httpd-docs-2.0/htdocs/manual/mod/mod_isapi.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- mod_isapi.html	2000/08/09 04:50:12	1.6
  +++ mod_isapi.html	2000/10/03 06:08:34	1.7
  @@ -16,57 +16,360 @@
   
   <H1 ALIGN="CENTER">Module mod_isapi</H1>
   
  -<P>This module is contained in the <CODE>mod_isapi.c</CODE> file, and
is
  -   compiled in by default. It provides support for ISAPI Extensions when
  -   running under Microsoft Windows. Any document with a handler of
  -   <CODE>isapi-isa</CODE> will be processed by this module.</P>
  -
  -<H2>Purpose</H2>
  -
  -<P>This module implements the ISAPI handler extension API, version 2.0. 
  -   It allows Internet Server Applications (<EM>i.e.</EM>, ISAPI handlers) 
  -   to be used with Apache for Windows.</P>
  +<P>This module supports ISAPI Extensions within Apache for Windows.</P>
   
  +<P><A
  +HREF="module-dict.html#Status"
  +REL="Help"
  +><STRONG>Status:</STRONG></A> Base
  +<BR>
  +<A
  +HREF="module-dict.html#SourceFile"
  +REL="Help"
  +><STRONG>Source File:</STRONG></A> mod_isapi.c
  +<BR>
  +<A
  +HREF="module-dict.html#ModuleIdentifier"
  +REL="Help"
  +><STRONG>Module Identifier:</STRONG></A> isapi_module
  +<BR>
  +<A
  +HREF="module-dict.html#Compatibility"
  +REL="Help"
  +><STRONG>Compatibility:</STRONG></A> WIN32 only
  +</P>
  +
  +<H2>Summary</H2>
  +
  +<P>This module implements the Internet Server extension API. It allows 
  +   Internet Server extensions (<EM>e.g.</EM> ISAPI .dll modules) to be
  +   served by Apache for Windows, subject to the noted restrictions.</P>
  +
  +<P>ISAPI extension modules (.dll files) are written by third parties.  The 
  +   Apache Group does not author these modules, so we provide no support for 
  +   them.  Please contact the ISAPI's author directly if you are experiencing 
  +   problems running their ISAPI extention.  <STRONG>Please <EM>do not</EM>

  +   post such problems to Apache's lists or bug reporting pages.</STRONG></P>
  +
   <H2>Usage</H2>
  +
  +<P>In the server configuration file, use the AddHandler directive to
  +   associate ISAPI files with the <CODE>isapi-isa</CODE> handler, and map 
  +   it to the with their file extensions.  To enable any .dll file to be 
  +   processed as an ISAPI extention, edit the httpd.conf file and add the 
  +   following line:</P>
   
  -<P>In the server configuration file, add a handler called
  -   <CODE>isapi-isa</CODE>, and map it to files with a <CODE>.DLL</CODE>
  -   extension. In other words:</P>
   <PRE>
       AddHandler isapi-isa dll
  +</PRE>
  +
  +<P>There is no capability within the Apache server to leave a requested
  +   module loaded.  However, you may preload and keep a specific module loaded
  +   by using the following syntax in your httpd.conf:
  +
  +<PRE>
  +    ISAPICacheFile c:/WebWork/Scripts/ISAPI/mytest.dll
   </PRE>
  -<P>Now simply place the ISA DLLs into your document root, and they will
  -   be loaded when their URLs are accessed.</P>
   
  -<P>ISAPI Extensions are governed by the same restrictions as CGI
  -   scripts. That is, <CODE>Options ExecCGI</CODE> must be active in the
  -   directory that contains the ISA.</P>
  +<P>Whether or not you have preloaded an ISAPI extension, all ISAPI 
  +   extensions are governed by the same permissions and restrictions 
  +   as CGI scripts.  That is, <CODE>Options ExecCGI</CODE> must be set for
  +   the directory that contains the ISAPI .dll file.</P>
  +
  +<P>Review the <A HREF="#notes">Additional Notes</A> and the
  +   <A HREF="#journal">Programmer's Journal</A> for additional details and
  +   clarification of the specific ISAPI support offered by mod_isapi.</P>
  +
  +<H2>Directives</H2>
  +<UL>
  +<LI><A HREF="#isapifilecache">ISAPIFileCache</A>
  +<LI><A HREF="#isapireadaheadbuffer">ISAPIReadAheadBuffer</A>
  +<LI><A HREF="#isapilognotsupported">ISAPILogNotSupported</A>
  +<LI><A HREF="#isapiappendlogtoerrors">ISAPIAppendLogToErrors</A>
  +<LI><A HREF="#isapiappendlogtoquery">ISAPIAppendLogToQuery</A>
  +</UL>
  +<HR>
  +
  +<H2><A NAME="isapifilecache">ISAPIFileCache directive</A></H2>
  +<!--%plaintext &lt;?INDEX {\tt ISAPIFileCache} directive&gt; -->
  +<A
  + HREF="directive-dict.html#Syntax"
  + REL="Help"
  +><STRONG>Syntax:</STRONG></A> ISAPIFileCache <EM>file [file...]</EM><BR>
  +<A
  + HREF="directive-dict.html#Context"
  + REL="Help"
  +><STRONG>Context:</STRONG></A> server config<BR>
  +<A
  + HREF="directive-dict.html#Override"
  + REL="Help"
  +><STRONG>Override:</STRONG></A> None<BR>
  +<A
  + HREF="directive-dict.html#Status"
  + REL="Help"
  +><STRONG>Status:</STRONG></A> Base<BR>
  +<A
  + HREF="directive-dict.html#Module"
  + REL="Help"
  +><STRONG>Module:</STRONG></A> mod_isapi<BR>
  +<A
  +HREF="module-dict.html#Compatibility"
  +REL="Help"
  +><STRONG>Compatibility:</STRONG></A> Apache 2.0 and later, Win32 only<P>
  +
  +        Specifies a space-separated list of file names to be loaded
  +        when the Apache server is launched, and remain loaded until
  +        the server is shut down.  This directive may be repeated
  +        for every ISAPI .dll file desired.  The full path name of
  +        each file should be specified.
  +        <P>
  +<HR>
  +
  +<H2><A NAME="isapireadaheadbuffer">ISAPIReadAheadBuffer directive</A></H2>
  +<!--%plaintext &lt;?INDEX {\tt ISAPIReadAheadBuffer} directive&gt; -->
  +<A
  + HREF="directive-dict.html#Syntax"
  + REL="Help"
  +><STRONG>Syntax:</STRONG></A> ISAPIReadAheadBuffer <EM>size</EM><BR>
  +<A
  + HREF="directive-dict.html#Default"
  + REL="Help"
  +><STRONG>Default:</STRONG></A> 49152<BR>
  +<A
  + HREF="directive-dict.html#Context"
  + REL="Help"
  +><STRONG>Context:</STRONG></A> server config<BR>
  +<A
  + HREF="directive-dict.html#Override"
  + REL="Help"
  +><STRONG>Override:</STRONG></A> None<BR>
  +<A
  + HREF="directive-dict.html#Status"
  + REL="Help"
  +><STRONG>Status:</STRONG></A> Base<BR>
  +<A
  + HREF="directive-dict.html#Module"
  + REL="Help"
  +><STRONG>Module:</STRONG></A> mod_isapi<BR>
  +<A
  +HREF="module-dict.html#Compatibility"
  +REL="Help"
  +><STRONG>Compatibility:</STRONG></A> Apache 1.3.13 and later, Win32
only<P>
  +
  +
  +        Defines the maximum size of the Read Ahead Buffer sent to 
  +        ISAPI extentions when they are initally invoked.  All 
  +        remaining data must be retrieved using the ReadClient 
  +        callback; some ISAPI extensions may not support the
  +        ReadClient function.  Refer questions to the ISAPI extention's 
  +        author.
  +        <P>
  +<HR>
  +
  +<H2><A NAME="isapilognotsupported">ISAPILogNotSupported directive</A></H2>
  +<!--%plaintext &lt;?INDEX {\tt ISAPILogNotSupported} directive&gt; -->
  +<A
  + HREF="directive-dict.html#Syntax"
  + REL="Help"
  +><STRONG>Syntax:</STRONG></A> ISAPILogNotSupported <EM>on|off</EM><BR>
  +<A
  + HREF="directive-dict.html#Default"
  + REL="Help"
  +><STRONG>Default:</STRONG></A> on<BR>
  +<A
  + HREF="directive-dict.html#Context"
  + REL="Help"
  +><STRONG>Context:</STRONG></A> server config<BR>
  +<A
  + HREF="directive-dict.html#Override"
  + REL="Help"
  +><STRONG>Override:</STRONG></A> None<BR>
  +<A
  + HREF="directive-dict.html#Status"
  + REL="Help"
  +><STRONG>Status:</STRONG></A> Base<BR>
  +<A
  + HREF="directive-dict.html#Module"
  + REL="Help"
  +><STRONG>Module:</STRONG></A> mod_isapi<BR>
  +<A
  +HREF="module-dict.html#Compatibility"
  +REL="Help"
  +><STRONG>Compatibility:</STRONG></A> Apache 1.3.13 and later, Win32
only<P>
  +
  +        Logs all requests for unsupported features from ISAPI extentions
  +        in the server error log.  While this should be turned off once
  +        all desired ISAPI modules are functioning, it defaults to on
  +        to help administrators track down problems.
  +        <P>
  +<HR>
  +
  +<H2><A NAME="isapiappendlogtoerrors">ISAPIAppendLogToErrors directive</A></H2>
  +<!--%plaintext &lt;?INDEX {\tt ISAPIAppendLogToErrors} directive&gt; -->
  +<A
  + HREF="directive-dict.html#Syntax"
  + REL="Help"
  +><STRONG>Syntax:</STRONG></A> ISAPIAppendLogToErrors <EM>on|off</EM><BR>
  +<A
  + HREF="directive-dict.html#Default"
  + REL="Help"
  +><STRONG>Default:</STRONG></A> off<BR>
  +<A
  + HREF="directive-dict.html#Context"
  + REL="Help"
  +><STRONG>Context:</STRONG></A> server config<BR>
  +<A
  + HREF="directive-dict.html#Override"
  + REL="Help"
  +><STRONG>Override:</STRONG></A> None<BR>
  +<A
  + HREF="directive-dict.html#Status"
  + REL="Help"
  +><STRONG>Status:</STRONG></A> Base<BR>
  +<A
  + HREF="directive-dict.html#Module"
  + REL="Help"
  +><STRONG>Module:</STRONG></A> mod_isapi<BR>
  +<A
  +HREF="module-dict.html#Compatibility"
  +REL="Help"
  +><STRONG>Compatibility:</STRONG></A> Apache 1.3.13 and later, Win32
only<P>
  +
  +        Record HSE_APPEND_LOG_PARAMETER requests from ISAPI extentions
  +        to the server error log.
  +        <P>
  +<HR>
  +
  +<H2><A NAME="isapiappendlogtoquery">ISAPIAppendLogToQuery directive</A></H2>
  +<!--%plaintext &lt;?INDEX {\tt ISAPIAppendLogToQuery} directive&gt; -->
  +<A
  + HREF="directive-dict.html#Syntax"
  + REL="Help"
  +><STRONG>Syntax:</STRONG></A> ISAPIAppendLogToQuery <EM>on|off</EM><BR>
  +<A
  + HREF="directive-dict.html#Default"
  + REL="Help"
  +><STRONG>Default:</STRONG></A> off<BR>
  +<A
  + HREF="directive-dict.html#Context"
  + REL="Help"
  +><STRONG>Context:</STRONG></A> server config<BR>
  +<A
  + HREF="directive-dict.html#Override"
  + REL="Help"
  +><STRONG>Override:</STRONG></A> None<BR>
  +<A
  + HREF="directive-dict.html#Status"
  + REL="Help"
  +><STRONG>Status:</STRONG></A> Base<BR>
  +<A
  + HREF="directive-dict.html#Module"
  + REL="Help"
  +><STRONG>Module:</STRONG></A> mod_isapi<BR>
  +<A
  +HREF="module-dict.html#Compatibility"
  +REL="Help"
  +><STRONG>Compatibility:</STRONG></A> Apache 1.3.13 and later, Win32
only<P>
  +
  +        Record HSE_APPEND_LOG_PARAMETER requests from ISAPI extentions
  +        to the query field (appended to the CustomLog %q component).
  +        <P>
  +<HR>
   
  -<H2>Notes</H2>
  +<H2><A NAME="notes">Additional Notes</A></H2>
   
   <P>Apache's ISAPI implementation conforms to all of the ISAPI 2.0
  -   specification, except for the "Microsoft-specific" extensions dealing
  -   with asynchronous I/O.  Apache's I/O model does not allow asynchronous
  +   specification, except for some "Microsoft-specific" extensions dealing
  +   with asynchronous I/O. Apache's I/O model does not allow asynchronous
      reading and writing in a manner that the ISAPI could access. If an ISA
  -   tries to access async I/O, a message will be place in the error log,
  -   to help with debugging.
  -
  -<P>Some servers, like Microsoft IIS, load the ISA into the server, and
  -   keep it loaded until memory usage is too high, and it is
  -   unloaded. Apache currently loads and unloads the ISA for each
  -   request. This is inefficient, but Apache's request model makes this
  -   method the only method that currently works. A future release may use
  -   a more effective loading method.
  -
  -<P>Apache 1.3a1 currently limits POST and PUT input to 48k per
  -   request. This is to work around a problem with the ISAPI implementation
  -   that could result in a denial of service attack. It is expected that
  -   support for larger uploads will be added soon.
  -
  -<P>Also, remember that while Apache supports ISAPI Extensions, it does
  -   not support ISAPI Filters. Support for filters may be added at a later
  -   date, but no support is planned at this time.</P>
  -
  +   tries to access unsupported features, including async I/O, a message is
  +   placed in the error log to help with debugging. Since these messages
  +   can become a flood, the directive <CODE>ISAPILogNotSupported Off</CODE>
  +   exists to quiet this noise.</P>
  +
  +<P>Some servers, like Microsoft IIS, load the ISAPI extension into the server
  +   and keep it loaded until memory usage is too high, or unless configuration
  +   options are specified.  Apache currently loads and unloads the ISAPI
  +   extension each time it is requested, unless the ISAPICacheFile directive
  +   is specified.  This is inefficient, but Apache's memory model makes this
  +   the most effective method.  Many ISAPI modules are subtly incompatible 
  +   with the Apache server, and unloading these modules helps to ensure the
  +   stability of the server.</P>
  +
  +<P>Also, remember that while Apache supports ISAPI Extensions, it 
  +   <STRONG>does not support ISAPI Filters.</STRONG>  Support for filters may

  +   be added at a later date, but no support is planned at this time.</P>
  +
  +<H2><A NAME="journal">Programmer's Journal</A></H2>
  +
  +<P>If you are programming Apache 2.0 mod_isapi modules, you must limit your
  +   calls to ServerSupportFunction to the following directives:</P>
  +
  +<DL>
  +  <DT>HSE_REQ_SEND_URL_REDIRECT_RESP
  +    <DD>Redirect the user to another location.<BR>
  +        This must be a fully qualified URL (e.g. http://server/location).
  +  <DT>HSE_REQ_SEND_URL
  +    <DD>Redirect the user to another location.<BR>
  +        This cannot be a fully qualified URL, you are not allowed
  +        to pass the protocol or a server name (e.g. simply /location).<BR>
  +        This redirection is handled by the server, not the browser.<BR>
  +        <STRONG>Warning:</STRONG> in their recent documentation, Microsoft

  +        appears to have abandoned the distinction between the two 
  +        HSE_REQ_SEND_URL functions.  Apache continues to treat them as two 
  +        distinct functions with different requirements and behaviors.
  +  <DT>HSE_REQ_SEND_RESPONSE_HEADER
  +    <DD>Apache accepts a response body following the header if it follows
  +        the blank line (two consecutive newlines) in the headers string 
  +        argument.  This body cannot contain NULLs, since the headers
  +        argument is NULL terminated.
  +  <DT>HSE_REQ_DONE_WITH_SESSION
  +    <DD>Apache considers this a no-op, since the session will be finished
  +        when the ISAPI returns from processing.
  +  <DT>HSE_REQ_MAP_URL_TO_PATH
  +    <DD>Apache will translate a virtual name to a physical name.
  +  <DT>HSE_APPEND_LOG_PARAMETER
  +    <DD>This logged message may be captured in any of the following logs:
  +      <UL>
  +        <LI>in the \"%{isapi-parameter}n\" component in a CustomLog directive
  +        <LI>in the %q log component with the ISAPIAppendLogToQuery On directive
  +        <LI>in the error log with the ISAPIAppendLogToErrors On directive
  +      </UL>
  +        The first option, the %{isapi-parameter}n component, is always available
  +        and prefered.
  +  <DT>HSE_REQ_IS_KEEP_CONN
  +    <DD>Will return the negotiated Keep-Alive status.
  +  <DT>HSE_REQ_SEND_RESPONSE_HEADER_EX
  +    <DD>Will behave as documented, although the fKeepConn flag is ignored.
  +  <DT>HSE_REQ_IS_CONNECTED
  +    <DD>Will report false if the request has been aborted.
  +</DL>
  +
  +<P>Apache returns FALSE to any unsupported call to ServerSupportFunction, and
  +   sets the GetLastError value to ERROR_INVALID_PARAMETER.</P>
  +
  +<P>ReadClient retrieves the request body exceeding the initial buffer 
  +   (defined by ISAPIReadAheadBuffer).  Based on the ISAPIReadAheadBuffer 
  +   setting (number of bytes to buffer prior to calling the ISAPI handler) 
  +   shorter requests are sent complete to the extension when it is invoked.
  +   If the request is longer, the ISAPI extension must use ReadClient to
  +   retrieve the remaining request body.</P>
  +
  +<P>WriteClient is supported, but only with the HSE_IO_SYNC flag or
  +   no option flag (value of 0).  Any other WriteClient request will
  +   be rejected with a return value of FALSE, and a GetLastError
  +   value of ERROR_INVALID_PARAMETER.</P>
  +
  +<P>GetServerVariable is supported, although extended server variables do not
  +   exist (as defined by other servers.)  All the usual Apache CGI environment 
  +   variables are available from GetServerVariable, as well as the ALL_HTTP 
  +   and ALL_RAW values.</P>
  +
  +<P>Apache 2.0 mod_isapi supports additional features introduced in later
  +   versions of the ISAPI specification, as well as limited emulation of
  +   async I/O and the TransmitFile semantics.  Apache also supports preloading
  +   ISAPI .dlls for performance, neither of which were not available under
  +   Apache 1.3 mod_isapi.</P>
   <!--#include virtual="footer.html" -->
   </BODY>
   </HTML>
  
  
  
  1.69      +5 -0      httpd-docs-2.0/htdocs/manual/mod/directives.html
  
  Index: directives.html
  ===================================================================
  RCS file: /home/cvs/httpd-docs-2.0/htdocs/manual/mod/directives.html,v
  retrieving revision 1.68
  retrieving revision 1.69
  diff -u -r1.68 -r1.69
  --- directives.html	2000/09/29 20:21:24	1.68
  +++ directives.html	2000/10/03 06:08:34	1.69
  @@ -129,6 +129,11 @@
   <LI><A HREF="core.html#include">Include</A>
   <LI><A HREF="mod_autoindex.html#indexignore">IndexIgnore</A>
   <LI><A HREF="mod_autoindex.html#indexoptions">IndexOptions</A>
  +<LI><A HREF="mod_isapi.html#isapiappendlogtoerrors">ISAPIAppendLogToErrors</A>
  +<LI><A HREF="mod_isapi.html#isapiappendlogtoquery">ISAPIAppendLogToQuery</A>
  +<LI><A HREF="mod_isapi.html#isapifilecache">ISAPIFileCache</A>
  +<LI><A HREF="mod_isapi.html#isapilognotsupported">ISAPILogNotSupported</A>
  +<LI><A HREF="mod_isapi.html#isapireadaheadbuffer">ISAPIReadAheadBuffer</A>
   <LI><A HREF="core.html#keepalive">KeepAlive</A>
   <LI><A HREF="core.html#keepalivetimeout">KeepAliveTimeout</A>
   <LI><A HREF="mod_negotiation.html#languagepriority">LanguagePriority</A>
  
  
  
  1.24      +145 -54   apache-2.0/src/os/win32/mod_isapi.c
  
  Index: mod_isapi.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/os/win32/mod_isapi.c,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- mod_isapi.c	2000/10/02 22:52:20	1.23
  +++ mod_isapi.c	2000/10/03 06:08:36	1.24
  @@ -135,6 +135,7 @@
   /* Our loaded isapi module description structure */
   
   typedef struct {
  +    const char *filename;
       HINSTANCE handle;
       HSE_VERSION_INFO *pVer;
       PFN_GETEXTENSIONVERSION GetExtensionVersion;
  @@ -158,20 +159,19 @@
       HANDLE complete;
   } isapi_cid;
   
  -apr_status_t isapi_load(request_rec *r, isapi_loaded** isa);
  -BOOL isapi_unload(isapi_loaded* isa, int force);
  +static BOOL isapi_unload(isapi_loaded* isa, int force);
   
   static apr_status_t cleanup_isapi_server_config(void *sconfv)
   {
       isapi_server_conf *sconf = sconfv;
       size_t n;
  -    isapi_loaded *isa;
  +    isapi_loaded **isa;
    
       n = sconf->loaded->nelts;
  -    isa = (isapi_loaded *)sconf->loaded->elts;
  +    isa = (isapi_loaded **)sconf->loaded->elts;
       while(n--) {
  -        if (isa->handle)
  -            isapi_unload(isa, TRUE); 
  +        if ((*isa)->handle)
  +            isapi_unload(*isa, TRUE); 
           ++isa;
       }
       CloseHandle(sconf->lock);
  @@ -180,7 +180,7 @@
   
   static void *create_isapi_server_config(apr_pool_t *p, server_rec *s)
   {
  -    isapi_server_conf *sconf = apr_palloc(p, sizeof(isapi_server_conf*));
  +    isapi_server_conf *sconf = apr_palloc(p, sizeof(isapi_server_conf));
       sconf->loaded = apr_make_array(p, 20, sizeof(isapi_loaded*));
       sconf->lock = CreateMutex(NULL, FALSE, NULL);
   
  @@ -194,11 +194,74 @@
   
       return sconf;
   }
  +
  +static int compare_loaded(const void *av, const void *bv)
  +{
  +    const isapi_loaded **a = av;
  +    const isapi_loaded **b = bv;
  +
  +    return strcmp((*a)->filename, (*b)->filename);
  +}
   
  -static apr_status_t isapi_load(request_rec *r, isapi_loaded** isa)
  +static void isapi_post_config(apr_pool_t *p, apr_pool_t *plog,
  +                              apr_pool_t *ptemp, server_rec *s)
   {
  +    isapi_server_conf *sconf = ap_get_module_config(s->module_config, 
  +                                                    &isapi_module);
  +    isapi_loaded **elts = (isapi_loaded **)sconf->loaded->elts;
  +    int nelts = sconf->loaded->nelts;
  +
  +    /* sort the elements of the main_server, by filename */
  +    qsort(elts, nelts, sizeof(isapi_loaded*), compare_loaded);
  +
  +    /* and make the virtualhosts share the same thing */
  +    for (s = s->next; s; s = s->next) {
  +	ap_set_module_config(s->module_config, &isapi_module, sconf);
  +    }
  +}
  +
  +static apr_status_t isapi_load(apr_pool_t *p, isapi_server_conf *sconf, 
  +                               request_rec *r, const char *fpath, 
  +                               isapi_loaded** isa)
  +{
  +    isapi_loaded **found = (isapi_loaded **)sconf->loaded->elts;
       char *fspec;
  -    char *p;
  +    char *ch;
  +    int n;
  +
  +    for (n = 0; n < sconf->loaded->nelts; ++n) {
  +        if (strcasecmp(fpath, (*found)->filename) == 0) {
  +            break;
  +        }
  +        ++found;
  +    }
  +    
  +    if (n < sconf->loaded->nelts) 
  +    {
  +        *isa = *found;
  +        if ((*isa)->handle) 
  +        {
  +            ++(*isa)->refcount;
  +            return APR_SUCCESS;
  +        }
  +        /* Otherwise we fall through and have to reload the resource
  +         * into this existing mod_isapi cache bucket.
  +         */
  +    }
  +    else
  +    {
  +        *isa = apr_pcalloc(p, sizeof(isapi_module));
  +        (*isa)->filename = fpath;
  +        (*isa)->pVer = apr_pcalloc(p, sizeof(HSE_VERSION_INFO));
  +    
  +        /* TODO: These need to become overrideable, so that we
  +         * assure a given isapi can be fooled into behaving well.
  +         */
  +        (*isa)->timeout = INFINITE; /* microsecs */
  +        (*isa)->fakeasync = TRUE;
  +        (*isa)->reportversion = MAKELONG(0, 5); /* Revision 5.0 */
  +    }
  +        
       /* Per PR2555, the LoadLibraryEx function is very picky about slashes.
        * Debugging on NT 4 SP 6a reveals First Chance Exception within NTDLL.
        * LoadLibrary in the MS PSDK also reveals that it -explicitly- states
  @@ -206,41 +269,21 @@
        *
        * Transpose '\' for '/' in the filename.
        */
  -    p = fspec = apr_pstrdup(r->pool, r->filename);
  -    while (*p) {
  -        if (*p == '/')
  -            *p = '\\';
  -        ++p;
  +    ch = fspec = apr_pstrdup(p, fpath);
  +    while (*ch) {
  +        if (*ch == '/')
  +            *ch = '\\';
  +        ++ch;
       }
   
  -    /* TODO: Critical section
  -     *
  -     * Warning: cid should not be allocated from pool if we 
  -     * cache the isapi process in-memory.
  -     *
  -     * This code could use cacheing... everything that follows
  -     * should only be performed on the first isapi dll invocation, 
  -     * not with every HttpExtensionProc()
  -     */
  -    *isa = apr_pcalloc(r->pool, sizeof(isapi_module));
  -    (*isa)->pVer = apr_pcalloc(r->pool, sizeof(HSE_VERSION_INFO));
  -    (*isa)->refcount = 1;
  +    (*isa)->handle = LoadLibraryEx(fspec, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
   
  -    /* TODO: These may need to become overrideable, so that we
  -     * assure a given isapi can be fooled into behaving well.
  -     */
  -    (*isa)->timeout = INFINITE; /* microsecs */
  -    (*isa)->fakeasync = TRUE;
  -    (*isa)->reportversion = MAKELONG(0, 5); /* Revision 5.0 */
  -    
  -    if (!((*isa)->handle = LoadLibraryEx(r->filename, NULL,
  -                                         LOAD_WITH_ALTERED_SEARCH_PATH))) 
  +    if (!(*isa)->handle)
       {
           apr_status_t rv = GetLastError();
           ap_log_rerror(APLOG_MARK, APLOG_ALERT, GetLastError(), r,
  -                      "ISAPI %s failed to load", r->filename);
  +                      "ISAPI %s failed to load", fpath);
           (*isa)->handle = NULL;
  -        (*isa)->refcount = 0;
           return rv;
       }
   
  @@ -250,10 +293,9 @@
           apr_status_t rv = GetLastError();
           ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                         "ISAPI %s is missing GetExtensionVersion()",
  -                      r->filename);
  +                      fpath);
           FreeLibrary((*isa)->handle);
           (*isa)->handle = NULL;
  -        (*isa)->refcount = 0;
           return rv;
       }
   
  @@ -263,10 +305,9 @@
           apr_status_t rv = GetLastError();
           ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                         "ISAPI %s is missing HttpExtensionProc()",
  -                      r->filename);
  +                      fpath);
           FreeLibrary((*isa)->handle);
           (*isa)->handle = NULL;
  -        (*isa)->refcount = 0;
           return rv;
       }
   
  @@ -280,13 +321,14 @@
           apr_status_t rv = GetLastError();
           ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                         "ISAPI %s call GetExtensionVersion() failed", 
  -                      r->filename);
  +                      fpath);
           FreeLibrary((*isa)->handle);
           (*isa)->handle = NULL;
  -        (*isa)->refcount = 0;
           return rv;
       }
   
  +    ++(*isa)->refcount;
  +
       return APR_SUCCESS;
   }
   
  @@ -312,6 +354,8 @@
   
   apr_status_t isapi_handler (request_rec *r)
   {
  +    isapi_server_conf *sconf = ap_get_module_config(r->server->module_config, 
  +                                                    &isapi_module);
       apr_table_t *e = r->subprocess_env;
       apr_status_t rv;
       isapi_loaded *isa;
  @@ -332,8 +376,10 @@
       if (r->finfo.filetype != APR_REG)
           return HTTP_FORBIDDEN;
   
  -    /* Load and cache or retrieve the cached extention */
  -    if (isapi_load(r, &isa) != APR_SUCCESS)
  +    /* Load the isapi extention without caching (sconf == NULL) 
  +     * but note that we will recover an existing cached module.
  +     */
  +    if (isapi_load(r->pool, sconf, r, r->filename, &isa) != APR_SUCCESS)
           return HTTP_INTERNAL_SERVER_ERROR;
           
       /* Set up variables */
  @@ -1068,15 +1114,60 @@
       return NULL;
   }
   
  +static const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy, 
  +                                       const char *filename)
  +
  +{
  +    isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config, 
  +                                                    &isapi_module);
  +    isapi_loaded *isa, **newisa;
  +    apr_finfo_t tmp;
  +    apr_status_t rv;
  +    char *fspec;
  +    
  +    fspec = ap_os_case_canonical_filename(cmd->pool, filename);
  +    if (apr_stat(&tmp, fspec, cmd->temp_pool) != APR_SUCCESS) { 
  +	ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
  +	    "ISAPI: unable to stat(%s), skipping", filename);
  +	return NULL;
  +    }
  +    if (tmp.filetype != APR_REG) {
  +	ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
  +	    "ISAPI: %s isn't a regular file, skipping", filename);
  +	return NULL;
  +    }
  +
  +    /* Load the extention as cached (passing sconf) */
  +    rv = isapi_load(cmd->pool, sconf, NULL, fspec, &isa); 
  +    if (rv != APR_SUCCESS) {
  +        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server,
  +                     "ISAPI: unable to cache %s, skipping", filename);
  +	return NULL;
  +    }
  +
  +    /* Add to cached list of loaded modules */
  +    newisa = apr_push_array(sconf->loaded);
  +    *newisa = isa;
  +    
  +    return NULL;
  +}
  +
  +static void isapi_hooks(void)
  +{
  +    ap_hook_post_config(isapi_post_config, NULL, NULL, AP_HOOK_MIDDLE);
  +}
  +
   static const command_rec isapi_cmds[] = {
  -{ "ISAPIReadAheadBuffer", isapi_cmd_readaheadbuffer, NULL, RSRC_CONF, TAKE1, 
  -  "Maximum bytes to initially pass to the ISAPI handler" },
  -{ "ISAPILogNotSupported", isapi_cmd_lognotsupported, NULL, RSRC_CONF, TAKE1, 
  -  "Log requests not supported by the ISAPI server" },
  -{ "ISAPIAppendLogToErrors", isapi_cmd_appendlogtoerrors, NULL, RSRC_CONF, TAKE1, 
  -  "Send all Append Log requests to the error log" },
  -{ "ISAPIAppendLogToQuery", isapi_cmd_appendlogtoquery, NULL, RSRC_CONF, TAKE1, 
  -  "Append Log requests are concatinated to the query args" },
  +AP_INIT_TAKE1("ISAPIReadAheadBuffer", isapi_cmd_readaheadbuffer, NULL, RSRC_CONF,
  +  "Maximum bytes to initially pass to the ISAPI handler"),
  +AP_INIT_TAKE1("ISAPILogNotSupported", isapi_cmd_lognotsupported, NULL, RSRC_CONF,
  +  "Log requests not supported by the ISAPI server"),
  +AP_INIT_TAKE1("ISAPIAppendLogToErrors", isapi_cmd_appendlogtoerrors, NULL, RSRC_CONF,
  +  "Send all Append Log requests to the error log"),
  +AP_INIT_TAKE1("ISAPIAppendLogToQuery", isapi_cmd_appendlogtoquery, NULL, RSRC_CONF,
  +  "Append Log requests are concatinated to the query args"),
  +AP_INIT_ITERATE("ISAPICacheFile", isapi_cmd_cachefile, NULL, RSRC_CONF,
  +  "Cache the specified ISAPI extension in-process"),
   { NULL }
   };
   
  @@ -1093,5 +1184,5 @@
      NULL,                        /* merge server config */
      isapi_cmds,                  /* command apr_table_t */
      isapi_handlers,              /* handlers */
  -   NULL                         /* register hooks */
  +   isapi_hooks                  /* register hooks */
   };
  
  
  

Mime
View raw message