[MSDN]Creating Simple ISAPI Filters

博客介绍了IIS使用ISAPI过滤器需提供标准接口,每个过滤器应用要实现并导出GetFilterVersion和HttpFilterProc两个主要函数。给出用C++创建简单ISAPI过滤器的示例,该过滤器可将HTML响应数据转为大写,还说明了处理请求和响应的具体逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

来自MSDN:  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iissdk/iis/creating_simple_isapi_filters.asp
For an ISAPI filter to be used by IIS, it must provide a standard interface. To provide a standard interface, each filter application must implement and export two primary functions, GetFilterVersion and HttpFilterProc. A third function, TerminateFilter, is considered optional and is commonly used by filters to perform cleanup operations.

Example Code

The following example shows you how to use the C++ programming language to create a simple ISAPI filter. This filter converts HTML response data to uppercase letters if the client requests it. The request is made by specifying an extra subdirectory in the URL called "UC," which doesn't actually exist on the server, but which is used by the filter to indicate that uppercase letters have been requested. The extra subdirectory is removed from the request before the HTTP server receives the request.

When a request is received, the filter inspects the subdirectories that are specified in the URL. If the nonexistent subdirectory is "UC" or "uc", the subdirectory is removed from the request, and the filter saves a value in its pFilterContext field, that indicates that the response data should be converted to uppercase letters.

When the filter entry point is later called for the response, it checks the pFilterContext field and converts the data if the mime-type of the response indicates that its an HTML file. This avoids conversions on binary data.

This code example is taken from the UpCase sample files that are included with the IIS section of the Platform SDK. It can also be downloaded from Platform SDK Update.

[C++]
/*
  Copyright (c) Microsoft Corporation
  Module Name: upcase.c
*/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <httpfilt.h>

BOOL WINAPI __stdcall GetFilterVersion(HTTP_FILTER_VERSION *pVer)
{
  /* Specify the types and order of notification */

  pVer->dwFlags = (SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_URL_MAP |  SF_NOTIFY_SEND_RAW_DATA | SF_NOTIFY_ORDER_DEFAULT);

  pVer->dwFilterVersion = HTTP_FILTER_REVISION;

  strcpy(pVer->lpszFilterDesc, "Upper case conversion filter, Version 1.0");

  return TRUE;
}

DWORD WINAPI __stdcall HttpFilterProc(HTTP_FILTER_CONTEXT *pfc, DWORD NotificationType, VOID *pvData)
{
  CHAR *pchIn, *pPhysPath;
  DWORD  cbBuffer,  cbtemp;
  PHTTP_FILTER_URL_MAP pURLMap;
  PHTTP_FILTER_RAW_DATA  pRawData;

  switch (NotificationType)  {

    case SF_NOTIFY_URL_MAP :

      /* Check the URL for a subdirectory in the form of /UC/ or /uc/ */

      pURLMap  =  (PHTTP_FILTER_URL_MAP)pvData;

      pPhysPath  =  pURLMap->pszPhysicalPath;

      pfc->pFilterContext  =  0;

      for ( ; *pPhysPath; pPhysPath++) 
      {
        /* Ensure that there are at least 4 characters (checking for "/UC/") left in the URL before checking */

        if (strlen(pPhysPath) > 3) 
        {
          if (*pPhysPath == '//' && (*(pPhysPath + 1) == 'u' || *(pPhysPath + 1) == 'U') && (*(pPhysPath + 2) == 'c' || *(pPhysPath + 2) == 'C') && *(pPhysPath + 3) ==  '//')
          {
            /* Now that we've found it, remove it by collapsing everything down */

            for ( ; *(pPhysPath + 3) ; pPhysPath++)
              *pPhysPath = *(pPhysPath + 3);

            /* NULL terminate the string */

            *pPhysPath = '/0'; 

            /* And set the flag to let the SF_NOTIFY_SEND_RAW_DATA handler know to uppercase the content */

            pfc->pFilterContext  =  (VOID  *)1;

            /* Break us out of the loop - note that this will only find the first instance of /UC/ in the URL */

            break;
          }
        }
      }

      break;

    case SF_NOTIFY_SEND_RAW_DATA :

      if (pfc->pFilterContext)
      {
        pRawData = (PHTTP_FILTER_RAW_DATA)pvData;

        pchIn  =  (BYTE  *)pRawData->pvInData;

        cbBuffer = 0;

        if (pfc->pFilterContext  == (VOID *)1)
        {
          /* 
          As this is the first block, scan through it until 2 CRLFs are seen, to pass
          all of the headers.
          */

          for ( ; cbBuffer < pRawData->cbInData - 2; cbBuffer++)
          {
            if (pchIn[cbBuffer]  == '/n' && pchIn[cbBuffer + 2]  == '/n')
            {
              cbBuffer += 3;

              break;
            }

            cbBuffer++;
          }

          for (cbtemp = 0; cbtemp < (cbBuffer - 3); cbtemp++) 
          {
            if (pchIn[cbtemp] == '/' && pchIn[cbtemp + 1] == 'h' && pchIn[cbtemp + 2] == 't' && pchIn[cbtemp + 3] == 'm')
            {
              pfc->pFilterContext  =  (VOID  *)2;

              break;
            }
          }

          if (cbtemp ==  cbBuffer)
            pfc->pFilterContext  =  0; /* not an  html file */
        }

        /* Now uppercase everything */

        if (pfc->pFilterContext)
          for ( ; cbBuffer < pRawData->cbInData; cbBuffer++)
            pchIn[cbBuffer] = (pchIn[cbBuffer] >= 'a' && pchIn[cbBuffer] <= 'z') ? (pchIn[cbBuffer] - 'a' + 'A') : pchIn[cbBuffer];
      }

      break;

    default :

      break;        
  }
  
  return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值