Can ISAPI Filter change the Request's domain name?

Question:

Hi,

I would like to know if we can get the entire URL that is sent through the browser into the ISAPI filter DLL.

E.g. If I have a URL like - https://www.mysite.com/test

what I get into the DLL (using GetHeader) is "/test". But I need the entire URL as I want to make changes even to the domain name https://www.mysite.com).

Can we do this? I am sorry if I am asking the same questions that have already been asked, but I need to know this ugently.

Thanks!

Answer:

ISAPI Filter can access the entire request sent by the Browser, which includes the information you named (URL and Host [i.e. "domain name"]). However, it may not be in the form you expect because:

  1. The web browser does not necessarily send the exact typed text to the web server
  2. GetHeader("url") does not retrieve what is typed into the web browser

The following is an abridged version of the BNF definition of a HTTP Request:

        HTTP-message   = Request | Response     ; HTTP/1.1 messages

        Request       = Request-Line              ; Section 5.1
                        *(( general-header        ; Section 4.5
                         | request-header         ; Section 5.3
                         | entity-header ) CRLF)  ; Section 7.1
                        CRLF
                        [ message-body ]          ; Section 4.3

       Request-Line   = Method SP Request-URI SP HTTP-Version CRLF

       Request-URI    = "*" | absoluteURI | abs_path | authority

       request-header = ...
                      | Host                     ; Section 14.23

Given your example URL of https://www.mysite.com/test , the web browser can send a couple of different valid requests. I color code what retrieves what:

Example 1:

 GET https://www.mysite.com/test HTTP/1.1\r\n
\r\n

Example 2:

 GET /test HTTP/1.1\r\n
Host: www.mysite.com\r\n
\r\n

In particular, GetHeader("url") only retrieves the Request-URI (colored in red) and GetHeader("host:") only retrieves the Host header (colored in green). In other words, GetHeader() does not retrieving the "logical URL" typed into the web browser; it retrieves specific parts of the request as identified by BNF.

Since you want to know the logical "domain" and "URL" of the request, you will have to retrieve the data via ISAPI and parse it yourself according to HTTP specifications. I suggest you read the HTTP 1.1 RFC for all of the proper details since ISAPI just gives you access to the data - you have to make logical sense of it yourself.

Now, as to your question about using ISAPI Filter to "change the domain name"... an ISAPI Filter can only change the domain name as it appears in the Host: header. It cannot alter IIS request processing nor server variables based on the website.

This means that if the original request came in for domain "original.com", it will be processed by the metadata associated with the "original.com" website. Even if the ISAPI Filter uses SetHeader() changes the Host: header to "new.com" or sets the URL to https://www.new.com/test, the SERVER_NAME and request is still processed by "original.com" - you only see the Host header change in the ALL_RAW and HTTP_HOST server variables.

In other words, it is not possible to transparently and easily change/re-route requests between different websites... unless you use a SF_NOTIFY_READ_RAW_DATA filter. But, you really do not want to do that for many reasons - on IIS6, you lose Worker Process Isolation Mode, and you also have to know HTTP backwards and forwards to write it correctly for all possible cases without crashing.

//David