akosut 97/07/22 12:25:21
Modified: src ApacheCore.dsp ApacheCore.mak src/nt modules.c Added: src/nt mod_isapi.c Log: Add nt/mod_isapi.c, which implements most of the ISAPI Extension 2.0 specification. It has a temporary cap of the input buffer at 48k, until a better solution can be found. Reviewed by: Brian Behlendorf, Randy Terbush, Dean Gaudet, Sameer Parekh Revision Changes Path 1.3 +4 -0 apache/src/ApacheCore.dsp Index: ApacheCore.dsp =================================================================== RCS file: /export/home/cvs/apache/src/ApacheCore.dsp,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ApacheCore.dsp 1997/07/20 15:30:00 1.2 +++ ApacheCore.dsp 1997/07/22 19:25:17 1.3 @@ -197,6 +197,10 @@ # End Source File # Begin Source File +SOURCE=.\nt\mod_isapi.c +# End Source File +# Begin Source File + SOURCE=.\mod_log_config.c # End Source File # Begin Source File 1.9 +218 -3 apache/src/ApacheCore.mak Index: ApacheCore.mak =================================================================== RCS file: /export/home/cvs/apache/src/ApacheCore.mak,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ApacheCore.mak 1997/07/20 15:30:01 1.8 +++ ApacheCore.mak 1997/07/22 19:25:17 1.9 @@ -76,6 +76,7 @@ [EMAIL PROTECTED] "$(INTDIR)\mod_env.obj" [EMAIL PROTECTED] "$(INTDIR)\mod_imap.obj" [EMAIL PROTECTED] "$(INTDIR)\mod_include.obj" + [EMAIL PROTECTED] "$(INTDIR)\mod_isapi.obj" [EMAIL PROTECTED] "$(INTDIR)\mod_log_config.obj" [EMAIL PROTECTED] "$(INTDIR)\mod_mime.obj" [EMAIL PROTECTED] "$(INTDIR)\mod_negotiation.obj" @@ -143,6 +144,7 @@ "$(INTDIR)\mod_env.obj" \ "$(INTDIR)\mod_imap.obj" \ "$(INTDIR)\mod_include.obj" \ + "$(INTDIR)\mod_isapi.obj" \ "$(INTDIR)\mod_log_config.obj" \ "$(INTDIR)\mod_mime.obj" \ "$(INTDIR)\mod_negotiation.obj" \ @@ -232,6 +234,8 @@ [EMAIL PROTECTED] "$(INTDIR)\mod_imap.sbr" [EMAIL PROTECTED] "$(INTDIR)\mod_include.obj" [EMAIL PROTECTED] "$(INTDIR)\mod_include.sbr" + [EMAIL PROTECTED] "$(INTDIR)\mod_isapi.obj" + [EMAIL PROTECTED] "$(INTDIR)\mod_isapi.sbr" [EMAIL PROTECTED] "$(INTDIR)\mod_log_config.obj" [EMAIL PROTECTED] "$(INTDIR)\mod_log_config.sbr" [EMAIL PROTECTED] "$(INTDIR)\mod_mime.obj" @@ -306,6 +310,7 @@ "$(INTDIR)\mod_env.sbr" \ "$(INTDIR)\mod_imap.sbr" \ "$(INTDIR)\mod_include.sbr" \ + "$(INTDIR)\mod_isapi.sbr" \ "$(INTDIR)\mod_log_config.sbr" \ "$(INTDIR)\mod_mime.sbr" \ "$(INTDIR)\mod_negotiation.sbr" \ @@ -361,6 +366,7 @@ "$(INTDIR)\mod_env.obj" \ "$(INTDIR)\mod_imap.obj" \ "$(INTDIR)\mod_include.obj" \ + "$(INTDIR)\mod_isapi.obj" \ "$(INTDIR)\mod_log_config.obj" \ "$(INTDIR)\mod_mime.obj" \ "$(INTDIR)\mod_negotiation.obj" \ @@ -443,6 +449,11 @@ ".\multithread.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_ALLOC=\ + ".\sfio.h"\ "$(INTDIR)\alloc.obj" "$(INTDIR)\alloc.sbr" : $(SOURCE) $(DEP_CPP_ALLOC)\ @@ -478,6 +489,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_BUFF_=\ + ".\sfio.h"\ "$(INTDIR)\buff.obj" "$(INTDIR)\buff.sbr" : $(SOURCE) $(DEP_CPP_BUFF_)\ @@ -549,6 +565,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_HTTP_=\ + ".\sfio.h"\ "$(INTDIR)\http_bprintf.obj" "$(INTDIR)\http_bprintf.sbr" : $(SOURCE)\ @@ -594,6 +615,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_HTTP_C=\ + ".\sfio.h"\ "$(INTDIR)\http_config.obj" "$(INTDIR)\http_config.sbr" : $(SOURCE)\ @@ -647,6 +673,11 @@ ".\rfc1413.h"\ ".\scoreboard.h"\ ".\util_md5.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_HTTP_CO=\ + ".\sfio.h"\ "$(INTDIR)\http_core.obj" "$(INTDIR)\http_core.sbr" : $(SOURCE)\ @@ -686,6 +717,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_HTTP_L=\ + ".\sfio.h"\ "$(INTDIR)\http_log.obj" "$(INTDIR)\http_log.sbr" : $(SOURCE) $(DEP_CPP_HTTP_L)\ @@ -743,6 +779,11 @@ ".\nt\service.h"\ ".\regex\regex.h"\ ".\scoreboard.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_HTTP_M=\ + ".\sfio.h"\ "$(INTDIR)\http_main.obj" "$(INTDIR)\http_main.sbr" : $(SOURCE)\ @@ -788,6 +829,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_date.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_HTTP_P=\ + ".\sfio.h"\ "$(INTDIR)\http_protocol.obj" "$(INTDIR)\http_protocol.sbr" : $(SOURCE)\ @@ -835,6 +881,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\scoreboard.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_HTTP_R=\ + ".\sfio.h"\ "$(INTDIR)\http_request.obj" "$(INTDIR)\http_request.sbr" : $(SOURCE)\ @@ -862,6 +913,8 @@ ".\conf.h"\ ".\md5.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ "$(INTDIR)\md5c.obj" "$(INTDIR)\md5c.sbr" : $(SOURCE) $(DEP_CPP_MD5C_)\ @@ -903,6 +956,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_A=\ + ".\sfio.h"\ "$(INTDIR)\mod_access.obj" "$(INTDIR)\mod_access.sbr" : $(SOURCE)\ @@ -950,6 +1008,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_AC=\ + ".\sfio.h"\ "$(INTDIR)\mod_actions.obj" "$(INTDIR)\mod_actions.sbr" : $(SOURCE)\ @@ -985,6 +1048,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_AL=\ + ".\sfio.h"\ "$(INTDIR)\mod_alias.obj" "$(INTDIR)\mod_alias.sbr" : $(SOURCE)\ @@ -1030,6 +1098,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_AS=\ + ".\sfio.h"\ "$(INTDIR)\mod_asis.obj" "$(INTDIR)\mod_asis.sbr" : $(SOURCE) $(DEP_CPP_MOD_AS)\ @@ -1071,6 +1144,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_AU=\ + ".\sfio.h"\ "$(INTDIR)\mod_auth.obj" "$(INTDIR)\mod_auth.sbr" : $(SOURCE) $(DEP_CPP_MOD_AU)\ @@ -1118,6 +1196,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_AUT=\ + ".\sfio.h"\ "$(INTDIR)\mod_autoindex.obj" "$(INTDIR)\mod_autoindex.sbr" : $(SOURCE)\ @@ -1153,6 +1236,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_B=\ + ".\sfio.h"\ "$(INTDIR)\mod_browser.obj" "$(INTDIR)\mod_browser.sbr" : $(SOURCE)\ @@ -1202,6 +1290,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_C=\ + ".\sfio.h"\ "$(INTDIR)\mod_cgi.obj" "$(INTDIR)\mod_cgi.sbr" : $(SOURCE) $(DEP_CPP_MOD_C)\ @@ -1249,6 +1342,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_D=\ + ".\sfio.h"\ "$(INTDIR)\mod_dir.obj" "$(INTDIR)\mod_dir.sbr" : $(SOURCE) $(DEP_CPP_MOD_D)\ @@ -1285,6 +1383,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_DL=\ + ".\sfio.h"\ "$(INTDIR)\mod_dll.obj" "$(INTDIR)\mod_dll.sbr" : $(SOURCE) $(DEP_CPP_MOD_DL)\ @@ -1321,6 +1424,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_E=\ + ".\sfio.h"\ "$(INTDIR)\mod_env.obj" "$(INTDIR)\mod_env.sbr" : $(SOURCE) $(DEP_CPP_MOD_E)\ @@ -1368,6 +1476,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_I=\ + ".\sfio.h"\ "$(INTDIR)\mod_imap.obj" "$(INTDIR)\mod_imap.sbr" : $(SOURCE) $(DEP_CPP_MOD_I)\ @@ -1415,6 +1528,13 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_IN=\ + ".\config.h"\ + ".\modules\perl\mod_perl.h"\ + ".\sfio.h"\ "$(INTDIR)\mod_include.obj" "$(INTDIR)\mod_include.sbr" : $(SOURCE)\ @@ -1423,6 +1543,44 @@ !ENDIF +SOURCE=.\nt\mod_isapi.c +DEP_CPP_MOD_IS=\ + ".\alloc.h"\ + ".\buff.h"\ + ".\conf.h"\ + ".\http_config.h"\ + ".\http_core.h"\ + ".\http_log.h"\ + ".\http_protocol.h"\ + ".\http_request.h"\ + ".\httpd.h"\ + ".\nt\readdir.h"\ + ".\regex\regex.h"\ + ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_IS=\ + ".\sfio.h"\ + + +!IF "$(CFG)" == "ApacheCore - Win32 Release" + + +"$(INTDIR)\mod_isapi.obj" : $(SOURCE) $(DEP_CPP_MOD_IS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "ApacheCore - Win32 Debug" + + +"$(INTDIR)\mod_isapi.obj" "$(INTDIR)\mod_isapi.sbr" : $(SOURCE)\ + $(DEP_CPP_MOD_IS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + SOURCE=.\mod_log_config.c !IF "$(CFG)" == "ApacheCore - Win32 Release" @@ -1452,6 +1610,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_L=\ + ".\sfio.h"\ "$(INTDIR)\mod_log_config.obj" "$(INTDIR)\mod_log_config.sbr" : $(SOURCE)\ @@ -1489,6 +1652,11 @@ ".\mod_mime.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_M=\ + ".\sfio.h"\ "$(INTDIR)\mod_mime.obj" "$(INTDIR)\mod_mime.sbr" : $(SOURCE) $(DEP_CPP_MOD_M)\ @@ -1532,6 +1700,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_N=\ + ".\sfio.h"\ "$(INTDIR)\mod_negotiation.obj" "$(INTDIR)\mod_negotiation.sbr" : $(SOURCE)\ @@ -1567,6 +1740,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MOD_U=\ + ".\sfio.h"\ "$(INTDIR)\mod_userdir.obj" "$(INTDIR)\mod_userdir.sbr" : $(SOURCE)\ @@ -1603,6 +1781,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_MODUL=\ + ".\sfio.h"\ "$(INTDIR)\modules.obj" "$(INTDIR)\modules.sbr" : $(SOURCE) $(DEP_CPP_MODUL)\ @@ -1632,6 +1815,8 @@ ".\conf.h"\ ".\multithread.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ "$(INTDIR)\multithread.obj" "$(INTDIR)\multithread.sbr" : $(SOURCE)\ @@ -1642,12 +1827,12 @@ !ENDIF SOURCE=.\nt\readdir.c -DEP_CPP_READD=\ - ".\nt\readdir.h"\ - !IF "$(CFG)" == "ApacheCore - Win32 Release" +DEP_CPP_READD=\ + ".\nt\readdir.h"\ + "$(INTDIR)\readdir.obj" : $(SOURCE) $(DEP_CPP_READD) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) @@ -1655,6 +1840,10 @@ !ELSEIF "$(CFG)" == "ApacheCore - Win32 Debug" +DEP_CPP_READD=\ + ".\nt\readdir.h"\ + {$(INCLUDE)}"sys\types.h"\ + "$(INTDIR)\readdir.obj" "$(INTDIR)\readdir.sbr" : $(SOURCE) $(DEP_CPP_READD)\ "$(INTDIR)" @@ -1694,6 +1883,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\rfc1413.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_RFC14=\ + ".\sfio.h"\ "$(INTDIR)\rfc1413.obj" "$(INTDIR)\rfc1413.sbr" : $(SOURCE) $(DEP_CPP_RFC14)\ @@ -1724,6 +1918,8 @@ ".\multithread.h"\ ".\nt\service.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ "$(INTDIR)\service.obj" "$(INTDIR)\service.sbr" : $(SOURCE) $(DEP_CPP_SERVI)\ @@ -1760,6 +1956,11 @@ ".\httpd.h"\ ".\nt\readdir.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_UTIL_=\ + ".\sfio.h"\ "$(INTDIR)\util.obj" "$(INTDIR)\util.sbr" : $(SOURCE) $(DEP_CPP_UTIL_)\ @@ -1787,6 +1988,8 @@ ".\conf.h"\ ".\regex\regex.h"\ ".\util_date.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ "$(INTDIR)\util_date.obj" "$(INTDIR)\util_date.sbr" : $(SOURCE)\ @@ -1824,6 +2027,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_md5.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_UTIL_M=\ + ".\sfio.h"\ "$(INTDIR)\util_md5.obj" "$(INTDIR)\util_md5.sbr" : $(SOURCE) $(DEP_CPP_UTIL_M)\ @@ -1873,6 +2081,11 @@ ".\nt\readdir.h"\ ".\regex\regex.h"\ ".\util_script.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_UTIL_S=\ + ".\sfio.h"\ "$(INTDIR)\util_script.obj" "$(INTDIR)\util_script.sbr" : $(SOURCE)\ @@ -1898,6 +2111,8 @@ DEP_CPP_UTIL_SN=\ ".\conf.h"\ ".\regex\regex.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ "$(INTDIR)\util_snprintf.obj" "$(INTDIR)\util_snprintf.sbr" : $(SOURCE)\ 1.4 +3 -0 apache/src/nt/modules.c Index: modules.c =================================================================== RCS file: /export/home/cvs/apache/src/nt/modules.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- modules.c 1997/07/18 23:54:29 1.3 +++ modules.c 1997/07/22 19:25:20 1.4 @@ -23,6 +23,7 @@ extern module imap_module; extern module action_module; extern module browser_module; +extern module isapi_module; module *prelinked_modules[] = { &core_module, @@ -43,6 +44,7 @@ &imap_module, &action_module, &browser_module, + &isapi_module, NULL }; module *preloaded_modules[] = { @@ -64,5 +66,6 @@ &imap_module, &action_module, &browser_module, + &isapi_module, NULL }; 1.1 apache/src/nt/mod_isapi.c Index: mod_isapi.c =================================================================== /* ==================================================================== * Copyright (c) 1995-1997 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. * * 5. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ /* * mod_isapi.c - Internet Server Application (ISA) module for Apache * by Alexei Kosut <[EMAIL PROTECTED]> * * This module implements Microsoft's ISAPI, allowing Apache (when running * under Windows) to load Internet Server Applications (ISAPI extensions). * It implements all of the ISAPI 2.0 specification, except for the * "Microsoft-only" extensions dealing with asynchronous I/O. All ISAPI * extensions that use only synchronous I/O and are compatible with the * ISAPI 2.0 specification should work (most ISAPI 1.0 extensions should * function as well). * * To load, simply place the ISA in a location in the document tree. * Then add an "AddHandler isapi-isa dll" into your config file. * You should now be able to load ISAPI DLLs just be reffering to their * URLs. Make sure the ExecCGI option is active in the directory * the ISA is in. */ #include "../httpd.h" #include "../http_config.h" #include "../http_core.h" #include "../http_protocol.h" #include "../http_request.h" #include "../http_log.h" #include "../util_script.h" /* We use the exact same header file as the original */ #include <HttpExt.h> module isapi_module; /* Our "Connection ID" structure */ typedef struct { LPEXTENSION_CONTROL_BLOCK ecb; request_rec *r; int status; } isapi_cid; /* Declare the ISAPI functions */ BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName, LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer); BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes, DWORD dwReserved); BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize); BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest, LPVOID lpvBuffer, LPDWORD lpdwSize, LPDWORD lpdwDataType); int isapi_handler (request_rec *r) { LPEXTENSION_CONTROL_BLOCK ecb = pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK)); HSE_VERSION_INFO *pVer = pcalloc(r->pool, sizeof(HSE_VERSION_INFO)); HINSTANCE isapi_handle; BOOL (*isapi_version)(HSE_VERSION_INFO *); /* entry point 1 */ DWORD (*isapi_entry)(LPEXTENSION_CONTROL_BLOCK); /* entry point 2 */ BOOL (*isapi_term)(DWORD); /* optional entry point 3 */ isapi_cid *cid = pcalloc(r->pool, sizeof(isapi_cid)); table *e = r->subprocess_env; int retval; /* Use similar restrictions as CGIs */ if (!(allow_options(r) & OPT_EXECCGI)) return FORBIDDEN; if (S_ISDIR(r->finfo.st_mode)) return FORBIDDEN; if (r->finfo.st_mode == 0) return NOT_FOUND; /* Load the module */ if (!(isapi_handle = LoadLibraryEx(r->filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH))) { log_reason("Could not load DLL", r->filename, r); return SERVER_ERROR; } if (!(isapi_version = (void *)(GetProcAddress(isapi_handle, "GetExtensionVersion")))) { log_reason("DLL could not load GetExtensionVersion()", r->filename, r); FreeLibrary(isapi_handle); return SERVER_ERROR; } if (!(isapi_entry = (void *)(GetProcAddress(isapi_handle, "HttpExtensionProc")))) { log_reason("DLL could not load HttpExtensionProc()", r->filename, r); FreeLibrary(isapi_handle); return SERVER_ERROR; } isapi_term = (void *)(GetProcAddress(isapi_handle, "TerminateExtension")); /* Run GetExtensionVersion() */ if ((*isapi_version)(pVer) != TRUE) { log_reason("ISAPI GetExtensionVersion() failed", r->filename, r); FreeLibrary(isapi_handle); return SERVER_ERROR; } /* Set up variables */ add_common_vars(r); add_cgi_vars(r); /* Set up connection ID */ ecb->ConnID = (HCONN)cid; cid->ecb = ecb; cid->r = r; cid->status = 0; ecb->cbSize = sizeof(struct _EXTENSION_CONTROL_BLOCK); ecb->dwVersion = MAKELONG(0, 2); ecb->dwHttpStatusCode = 0; strcpy(ecb->lpszLogData, ""); ecb->lpszMethod = r->method; ecb->lpszQueryString = table_get(e, "QUERY_STRING"); ecb->lpszPathInfo = table_get(e, "PATH_INFO"); ecb->lpszPathTranslated = table_get(e, "PATH_TRANSLATED"); ecb->lpszContentType = table_get(e, "CONTENT_TYPE"); /* Set up client input */ if ((retval = setup_client_block(r, REQUEST_CHUNKED_ERROR))) { if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD); FreeLibrary(isapi_handle); return retval; } if (should_client_block(r)) { /* Unlike IIS, which limits this to 48k, we read the whole * sucker in. I suppose this could be bad for memory if someone * uploaded the complete works of Shakespeare. Well, WebSite * does the same thing. */ long to_read = atol(table_get(e, "CONTENT_LENGTH")); long read; /* Actually, let's cap it at 48k, until we figure out what * to do with this... we don't want a Content-Length: 1000000000 * taking out the machine. */ if (to_read > 49152) { if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD); FreeLibrary(isapi_handle); return HTTP_REQUEST_ENTITY_TOO_LARGE; } ecb->lpbData = pcalloc(r->pool, 1 + to_read); if ((read = get_client_block(r, ecb->lpbData, to_read)) < 0) { if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD); FreeLibrary(isapi_handle); return SERVER_ERROR; } /* Although its not to spec, IIS seems to null-terminate * its lpdData string. So we will too. To make sure * cbAvailable matches cbTotalBytes, we'll up the latter * and equalize them. */ ecb->cbAvailable = ecb->cbTotalBytes = read + 1; ecb->lpbData[read] = '\0'; } else { ecb->cbTotalBytes = 0; ecb->cbAvailable = 0; ecb->lpbData = NULL; } /* Set up the callbacks */ ecb->GetServerVariable = &GetServerVariable; ecb->WriteClient = &WriteClient; ecb->ReadClient = &ReadClient; ecb->ServerSupportFunction = &ServerSupportFunction; /* All right... try and load the sucker */ retval = (*isapi_entry)(ecb); /* Set the status (for logging) */ if (ecb->dwHttpStatusCode) r->status = ecb->dwHttpStatusCode; /* Check for a log message - and log it */ if (ecb->lpszLogData && strcmp(ecb->lpszLogData, "")) log_reason(ecb->lpszLogData, r->filename, r); /* All done with the DLL... get rid of it */ if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD); FreeLibrary(isapi_handle); switch(retval) { case HSE_STATUS_SUCCESS: case HSE_STATUS_SUCCESS_AND_KEEP_CONN: /* Ignore the keepalive stuff; Apache handles it just fine without * the ISA's "advice". */ if (cid->status) /* We have a special status to return */ return cid->status; return OK; case HSE_STATUS_PENDING: /* We don't support this */ log_reason("ISAPI asynchronous I/O not supported", r->filename, r); case HSE_STATUS_ERROR: default: return SERVER_ERROR; } } BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName, LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer) { request_rec *r = ((isapi_cid *)hConn)->r; table *e = r->subprocess_env; char *result; /* Mostly, we just grab it from the environment, but there are * a couple of special cases */ if (!strcasecmp(lpszVariableName, "UNMAPPED_REMOTE_USER")) { /* We don't support NT users, so this is always the same as * REMOTE_USER */ result = table_get(e, "REMOTE_USER"); } else if (!strcasecmp(lpszVariableName, "SERVER_PORT_SECURE")) { /* Apache doesn't support secure requests inherently, so * we have no way of knowing. We'll be conservative, and say * all requests are insecure. */ result = "0"; } else if (!strcasecmp(lpszVariableName, "URL")) { result = r->uri; } else { result = table_get(e, lpszVariableName); } if (result) { if (strlen(result) > *lpdwSizeofBuffer) { *lpdwSizeofBuffer = strlen(result); SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } strncpy(lpvBuffer, result, *lpdwSizeofBuffer); return TRUE; } /* Didn't find it */ SetLastError(ERROR_INVALID_INDEX); return FALSE; } BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes, DWORD dwReserved) { request_rec *r = ((isapi_cid *)ConnID)->r; int writ; /* written, actually, but why shouldn't I make up words? */ /* We only support synchronous writing */ if (dwReserved && dwReserved != HSE_IO_SYNC) { log_reason("ISAPI asynchronous I/O not supported", r->filename, r); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if ((writ = rwrite(Buffer, *lpwdwBytes, r)) == EOF) { SetLastError(ERROR); /* XXX: Find the right error code */ return FALSE; } *lpwdwBytes = writ; return TRUE; } BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize) { /* Doesn't need to do anything; we've read all the data already */ return TRUE; } BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest, LPVOID lpvBuffer, LPDWORD lpdwSize, LPDWORD lpdwDataType) { isapi_cid *cid = (isapi_cid *)hConn; request_rec *subreq, *r = cid->r; char *data; switch (dwHSERequest) { case HSE_REQ_SEND_URL_REDIRECT_RESP: /* Set the status to be returned when the HttpExtensionProc() * is done. */ table_set (r->headers_out, "Location", lpvBuffer); cid->status = cid->r->status = cid->ecb->dwHttpStatusCode = REDIRECT; return TRUE; case HSE_REQ_SEND_URL: /* Read any additional input */ if (r->remaining > 0) { char argsbuffer[HUGE_STRING_LEN]; while (get_client_block(r, argsbuffer, HUGE_STRING_LEN)); } /* Reset the method to GET */ r->method = pstrdup(r->pool, "GET"); r->method_number = M_GET; /* Don't let anyone think there's still data */ table_unset(r->headers_in, "Content-Length"); internal_redirect((char *)lpvBuffer, r); return TRUE; case HSE_REQ_SEND_RESPONSE_HEADER: r->status_line = lpvBuffer ? lpvBuffer : pstrdup(r->pool, "200 OK"); sscanf(r->status_line, "%d", &r->status); cid->ecb->dwHttpStatusCode = r->status; /* Now fill in the HTTP headers, and the rest of it. Ick. * lpdwDataType contains a string that has headers (in MIME * format), a blank like, then (possibly) data. We need * to parse it. * * Easy case first: */ if (!lpdwDataType) { send_http_header(r); return TRUE; } /* Make a copy - don't disturb the original */ data = pstrdup(r->pool, (char *)lpdwDataType); /* We *should* break before this while loop ends */ while (*data) { char *value, *lf = strchr(data, '\n'); int p; if (!lf) { /* Huh? Invalid data, I think */ log_reason("ISA sent invalid headers", r->filename, r); SetLastError(ERROR); /* XXX: Find right error */ return FALSE; } /* Get rid of \n and \r */ *lf = '\0'; p = strlen(data); if (p > 0 && data[p-1] == '\r') data[p-1] = '\0'; /* End of headers */ if (*data == '\0') { data = lf + 1; /* Reset data */ break; } if (!(value = strchr(data, ':'))) { SetLastError(ERROR); /* XXX: Find right error */ log_reason("ISA sent invalid headers", r->filename, r); return FALSE; } *value++ = '\0'; while (*value && isspace(*value)) ++value; /* Check all the special-case headers. Similar to what * scan_script_header() does (see that function for * more detail) */ if (!strcasecmp(data, "Content-Type")) { /* Nuke trailing whitespace */ char *endp = value + strlen(value) - 1; while (endp > value && isspace(*endp)) *endp-- = '\0'; r->content_type = pstrdup (r->pool, value); } else if (!strcasecmp(data, "Content-Length")) { table_set(r->headers_out, data, value); } else if (!strcasecmp(data, "Transfer-Encoding")) { table_set(r->headers_out, data, value); } else if (!strcasecmp(data, "Set-Cookie")) { table_add(r->err_headers_out, data, value); } else { table_merge(r->err_headers_out, data, value); } /* Reset data */ data = lf + 1; } /* All the headers should be set now */ send_http_header(r); /* Any data left should now be sent directly */ rputs(data, r); return TRUE; case HSE_REQ_MAP_URL_TO_PATH: /* Map a URL to a filename */ subreq = sub_req_lookup_uri(pstrndup(r->pool, (char *)lpvBuffer, *lpdwSize), r); GetFullPathName(subreq->filename, *lpdwSize - 1, (char *)lpvBuffer, NULL); /* IIS puts a trailing slash on directories, Apache doesn't */ if (S_ISDIR (subreq->finfo.st_mode)) { int l = strlen((char *)lpvBuffer); ((char *)lpvBuffer)[l] = '\\'; ((char *)lpvBuffer)[l + 1] = '\0'; } return TRUE; case HSE_REQ_DONE_WITH_SESSION: /* Do nothing... since we don't support async I/O, they'll * return from HttpExtensionProc soon */ return TRUE; /* We don't support all this async I/O, Microsoft-specific stuff */ case HSE_REQ_IO_COMPLETION: case HSE_REQ_TRANSMIT_FILE: log_reason("ISAPI asynchronous I/O not supported", r->filename, r); default: SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } } handler_rec isapi_handlers[] = { { "isapi-isa", isapi_handler }, { NULL} }; module isapi_module = { STANDARD_MODULE_STUFF, NULL, /* initializer */ NULL, /* create per-dir config */ NULL, /* merge per-dir config */ NULL, /* server config */ NULL, /* merge server config */ NULL, /* command table */ isapi_handlers, /* handlers */ NULL, /* filename translation */ NULL, /* check_user_id */ NULL, /* check auth */ NULL, /* check access */ NULL, /* type_checker */ NULL, /* logger */ NULL /* header parser */ };