HOWTO: Make XSLISAPI2.DLL work on IIS 6.0

Overview

This is an "in-progress" blog entry where I document the steps necessary to get XSLISAPI2.DLL to work on IIS 6.0. This has been requested several times on the microsoft.public.inetserver.iis and microsoft.public.platformsdk.internet.server.isapi-dev newsgroups, so I decided to do a little investigation on what is going on with this ISAPI and IIS 6.0 and have a running documentary of the investigation.

Since the source code of the filter is completely given in the download (you can download and compile yourself), I presume it is user-supported.

If you'd permit me a moment for a side-comment -- notice how openly available source does not always work out -- even though the source code is openly available and there has been several itches that people have wanted to scratch, without the motivated people to SUPPORT the source code, the concept will not make it.

Ok, digression aside, let us look at what is going on within this ISAPI Filter and how to make it work on IIS 6.0

Observations

I have only read through about 30% of the ISAPI Filter source code, and I can say that this ISAPI Filter has several flaws in it, some of which are exposed by IIS 6.0, and they prevent it from functioning. The issues (and resolution) are:

  1. In IISFilter.cpp::CheckVFileForSSL() , the filter incorrectly assumes that the AccessSSLFlags property is set for any given URL and then fails if it is not. This is simply not a valid assumption and can cause custom error behavior on IIS to be strange.
  2. Notice that the filter affects 404 responses when the URL extension is not 3 or 4 characters. Try /pagerror.gif , /pagerror.gif1 , and /pagerror.gif12 and you will notice the difference.
  3. The Filter tries to determine the file extension of the URL in SF_NOTIFY_PREPROC_HEADERS, which is completely wrong. It is simply not possible, especially if there is another ISAPI Filter that changes the URL. One can come up with a legitimate ISAPI Filter which will break this filter, and there is no band-aid fix for this flaw.
  4. Global.h::g_szSourceFile is set to "SSXSLSRCFILE:" and is subsequently used in two places, IISFilter.cpp::LogFilterEvent() and IISFilter.cpp::HttpFilterProc() . However, the code is incorrect in IISFilter.cpp::LogFilterEvent() and takes advantage of an IIS5 bug (fixed in IIS6). Namely, "HTTP_SSXSLSRCFILE:" is not a valid request header name for a call to HTTP_FILTER_CONTEXT::GetServerVariable(). It needs to be "HTTP_SSXSLSRCFILE" (without the ":"). The quick fix, of course, is to introduce a g_szSourceFile2 variable alongside g_szSourceFile, without the trailing ":", and use it ONLY in IISFilter.cpp::LogFilterEvent()
  5. <TBD> as people help iterate through any remaining issues from IIS by providing me comments on what is/not working, what configuration is necessary, and any sample files to reproduce the issue. I do not know what XSLISAPI2.DLL is supposed to do; I can only help on the ISAPI Filter portion.

Work-around Steps

  1. Download xslisapi.exe from: https://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=2EA4F409-65D6-4101-8D4E-ADD53D4521C7
  2. Extract the files to anywhere that is not web-accessible
  3. Edit Global.h to include:
    const char g_szSourceFile2[] = "SSXSLSRCFILE";
  4. Edit IISFilter.cpp::LogFilterEvent() to use g_szSourceFile2 instead of g_szSourceFile.
    *** Important: Leave the one in IISFilter::HttpFilterProc() alone. It is correct ***
    char szSrcFileEnvVariable[6 + sizeof(g_szSourceFile2)];
    wsprintfA(szSrcFileEnvVariable,"HTTP_%s",g_szSourceFile2);
  5. If you do NOT have SSL set up, use the following (where ### is the ID of your website):
    CSCRIPT %SYSTEMDRIVE%\Inetpub\adminscripts\adsutil.vbs SET W3SVC/###/ROOT/AccessSSLFlags 0
  6. <TBD> For remaining issues.

//David