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 */
};