Click here to Skip to main content
15,867,330 members
Articles / Desktop Programming / MFC

How to Make an ISAPI Redirection Filter

Rate me:
Please Sign up or sign in to vote.
4.36/5 (20 votes)
10 Sep 20034 min read 410.9K   2.9K   52   62
How to build a simple ISAPI Filter

Introduction

Redirecting web traffic is a fairly common task, we can redirect from HTML, from ASP (or other scripting engines) and from ISAPI. This tutorial will demonstrate how to reduce server workload by redirecting from ISAPI using MFC using a “redirection filter”. This example will redirect a requested page, while retaining the URL the user sees in their browser.

Html Redirect

The code to redirect a page looks something like the following:

HTML
<META http-equiv="refresh" content="5; URL=http://somewhere.com/page.asp">

ASP Redirect

The ASP code to redirect looks like:

ASP.NET
response.redirect "chrismaunderfanclub.com"

The first relies on you having each page set up to redirect, the second is done via ASP which means it requires use of the scripting engine (server hit).

ISAPI Redirection Filter

We can reduce the server load by using ISAPI filters in C++. This will have the same effect – the downside is that you need to know how to use Visual Studio to do it. The upside is that you don’t use ASP. This filter will change the URL of the file IIS thinks it wants to return, without changing the URL the user sees in their browser.

The Project

Open Visual Studio (I use version 6.0). Make a new project and select “ISAPI Extension Wizard”.

New ISAPI Project

Give your project a name. I’m using “redirector”, click "OK". You should now be presented with the following:

Image 2

Tick “Generate Filter Object” and un-tick “Generate a Server Extension Object”. In case, I’ll also link statically.

Click Next...

Image 3

Because we only want to redirect the actual page and not the page the user thinks it is, we’ll tick “Post-processing of the request headers” and select the notification priority we want the filter to have, in this case, we’ll select “high” to make sure it gets attention before any other filters. Click “Finish” and Visual Studio will now prepare the project for you.

The Code

We will now add our code to redirect all requests from .cfm to .asp. The function of interest is in redirector.cpp and is called OnPreprocHeaders and it looks something like the following:

C++
DWORD CRedirectorFilter::OnPreprocHeaders(
                             CHttpFilterContext* pCtxt, 
                             PHTTP_FILTER_PREPROC_HEADERS pHeaderInfo
                         )
{
    return SF_STATUS_REQ_NEXT_NOTIFICATION;
}

This function is called when the server has preprocessed the client headers. In this example, we want to modify the URL that IIS thinks it wants to return. We’ll try something simple - replacing all Coldfusion (.cfm) extensions with .asp. Why? Perhaps we’re using ASP instead of ColdFusion and don’t want to change the links on the pages themselves.

We need to find out which page has been requested, and then replace .cfm with .asp if necessary. To do this, we need to use the HTTP_FILTER_PREPROC_HEADERS pointer, pHeaderInfo, and the filter context pointer pCtxt.

We want to see the URL requested, to do this, we can ask IIS what the URL was by way of the GetHeader function.

C++
DWORD CRedirectorFilter::OnPreprocHeaders(
                             CHttpFilterContext* pCtxt, 
                             PHTTP_FILTER_PREPROC_HEADERS pHeaderInfo
                         )
{
    char buffer[256]
    DWORD buffSize = sizeof(buffer);
    BOOL  bHeader=pHeaderInfo->GetHeader(pCtxt->m_pFC, "url",
                                             buffer, &buffSize); 
    ...
}

Once we have the URL, we can decide whether to redirect it. I’m going to cheat a little here and use CString to deal with the string code, you can use whatever string code you like:

C++
DWORD CRedirectorFilter::OnPreprocHeaders(
                             CHttpFilterContext* pCtxt,
                             PHTTP_FILTER_PREPROC_HEADERS pHeaderInfo
                         )
{
    char buffer[256];
    DWORD buffSize = sizeof(buffer);
    BOOL bHeader = pHeaderInfo->GetHeader(pCtxt->m_pFC, "url",
                                              buffer, &buffSize); 
    CString urlString(buffer);
    urlString.MakeLower(); // for this exercise 
    if (urlString.Find(".cfm") != -1) //we want to redirect this file
    {
        urlString.Replace(".cfm",".asp");
        char *newUrlString= urlString.GetBuffer(urlString.GetLength());
        pHeaderInfo->SetHeader(pCtxt->m_pFC, "url", newUrlString);
        return SF_STATUS_REQ_HANDLED_NOTIFICATION;
    }
    //we want to leave this alone and let IIS handle it
    return SF_STATUS_REQ_NEXT_NOTIFICATION;
}

Now, build the file and with any luck, there will be no errors!

Adding the Filter to IIS

Next, you will want to add the filter to IIS, or Personal Web Service if you are using it. I’m now going to describe how to add the filter to Personal Web Service.

So, go to Administrative tools (in Windows 2000) and select Internet Services Manger, something like the following will now appear:

Image 4

Right click on “Default Web Site” (or whatever web server you want to add it to) and select “properties”, the following windows should then appear.

Image 5

From the tabs, click on “ISAPI Filters”.

Image 6

Now, assuming there are no filters already present, the box in the middle should be clear (as this example shows) Click the “Add” button…

Image 7

Give your filter a “name”, and use the browse button to locate the redirection filter .dll file.

Image 8

Click “OK” and the filter will now appear, if you want your filter to have higher priority than others that may appear in the list, use the buttons on the left hand side to organize the correct order.

Image 9

Click “OK”. The tabbed dialog will disappear.

Next, we want to stop and start the web service. Right click on the “Default Web Site”, select “Stop” then right click again and select “Start”.

Alternatively, you can click the black square on the rebar to stop the service, and click the “Start item” (black triangle) to restart it.

Testing It

Make a file test.asp and place it in your wwwroot directory of inetpub. Open your web browser and open location http://localhost/test.cfm. If all goes well, then the contents of test.asp will be displayed in the browser.

That’s it, you’re done!

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
Software Developer (Senior) TMR
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalproblem in redirecting the .aspx pages using vc++ Pin
prakash.ss836-Oct-09 22:03
prakash.ss836-Oct-09 22:03 
Generalhi problem with using this Pin
prakash.ss8323-Sep-09 21:56
prakash.ss8323-Sep-09 21:56 
Generalhttps redirection Pin
zorkzero25-Jun-09 5:15
zorkzero25-Jun-09 5:15 
QuestionHow to rewrite a url and also use 301 redirect Pin
sumit mahajan13-Mar-09 13:53
sumit mahajan13-Mar-09 13:53 
AnswerRe: How to rewrite a url and also use 301 redirect Pin
bryce16-Mar-09 0:00
bryce16-Mar-09 0:00 
GeneralRe: How to rewrite a url and also use 301 redirect Pin
sumit mahajan16-Mar-09 11:02
sumit mahajan16-Mar-09 11:02 
GeneralRe: How to rewrite a url and also use 301 redirect Pin
bryce16-Mar-09 18:24
bryce16-Mar-09 18:24 
Ahh well what you want thats not what the article describes as it's purpose.
So that it doesnt work for you in the way you want isnt really surprising.

But i take it you want me to provide a solution to your work related website?

bryce

MCAD

---
To paraphrase Fred Dagg - the views expressed in this post are bloody good ones.
--


Publitor, making Pubmed easy.
http://www.sohocode.com/publitor


Our kids books :The Snot Goblin, and Book 2 - the Snotgoblin and Fluff




GeneralRe: How to rewrite a url and also use 301 redirect Pin
sumit mahajan17-Mar-09 2:39
sumit mahajan17-Mar-09 2:39 
GeneralRe: How to rewrite a url and also use 301 redirect Pin
sumit mahajan21-Mar-09 9:25
sumit mahajan21-Mar-09 9:25 
GeneralRe: How to rewrite a url and also use 301 redirect Pin
bryce23-Mar-09 13:30
bryce23-Mar-09 13:30 
GeneralRe: How to rewrite a url and also use 301 redirect Pin
sumit mahajan24-Mar-09 11:06
sumit mahajan24-Mar-09 11:06 
GeneralRe: How to rewrite a url and also use 301 redirect Pin
bryce25-Mar-09 15:28
bryce25-Mar-09 15:28 
GeneralRe: How to rewrite a url and also use 301 redirect Pin
Neelesh K J Jain30-Mar-09 9:39
Neelesh K J Jain30-Mar-09 9:39 
AnswerRe: How to rewrite a url and also use 301 redirect Pin
sumit mahajan30-Jul-09 5:41
sumit mahajan30-Jul-09 5:41 
QuestionHow to write an ISAPI filter to give 404 instead of 403 Pin
munishsehgal18-Oct-08 23:48
munishsehgal18-Oct-08 23:48 
AnswerRe: How to write an ISAPI filter to give 404 instead of 403 Pin
bryce16-Mar-09 0:01
bryce16-Mar-09 0:01 
QuestionHow to change the port in the header? Pin
Sara Al-Kady27-Jul-08 1:51
Sara Al-Kady27-Jul-08 1:51 
GeneralRedirect to specific page based on referrer Pin
labrys5-Jun-08 4:47
labrys5-Jun-08 4:47 
QuestionDynamic redirect? Pin
gawain_the_stout2-Oct-07 10:46
gawain_the_stout2-Oct-07 10:46 
AnswerRe: Dynamic redirect? Pin
bryce4-Oct-07 13:30
bryce4-Oct-07 13:30 
QuestionDebugging ISAPI Filter? Pin
Lang Deng3-Aug-07 14:19
Lang Deng3-Aug-07 14:19 
AnswerRe: Debugging ISAPI Filter? Pin
bryce4-Aug-07 2:52
bryce4-Aug-07 2:52 
GeneralRe: Debugging ISAPI Filter? Pin
Lang Deng6-Aug-07 11:05
Lang Deng6-Aug-07 11:05 
GeneralRe: Debugging ISAPI Filter? Pin
bryce6-Aug-07 11:21
bryce6-Aug-07 11:21 
GeneralRe: Debugging ISAPI Filter? Pin
Lang Deng6-Aug-07 13:28
Lang Deng6-Aug-07 13:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.