Implementing Required ISAPI Extension Functions

For an ISAPI extension to be used by IIS, it must provide a standard interface. Each extension DLL must implement and export two primary functions, GetExtensionVersion and HttpExtensionProc. A third function, TerminateExtension, is considered optional and is commonly used by extensions to perform cleanup operations.

Initialization Using GetExtensionVersion

Initialization is handled by the entry-point function GetExtensionVersion. This function's role is to perform all initialization, including the creation of worker threads, synchronization objects, and database connections, and to establish the version of ISAPI that was used to build the DLL.

Adding Functionality Using HttpExtensionProc

In general, an extension's functionality is exposed through the HttpExtensionProc entry-point function. This function receives a pointer to an EXTENSION_CONTROL_BLOCK structure, which contains data used for the required processing and is also used by the extension to communicate with IIS.

When HttpExtensionProc in employed, it should first send a response header to the client. The header provides the client with information, such as the content type that is returned. After the header is sent, any other processing can be performed through the various callback functions provided in the EXTENSION_CONTROL_BLOCK.

Termination Using TerminateExtension

When an extension is no longer needed, IIS removes it from memory. If the extension provides the TerminateExtension function, IIS calls it before removing the extension. Use of TerminateExtension is recommended to close down any threads that an extension initialized during processing.

After IIS finishes processing a request for an ISAPI extension, the connection can either be closed or kept open. A request can specify that the connection remain open by specifying the Connection: Keep-Alive header. If an ISAPI extension is designed to support Keep-Alive requests, this should be indicated to the client by calling the HSE_REQ_SEND_RESPONSE_HEADER server support function. The specified response header should contain Connection: Keep-Alive.

Note

If the request to IIS comes from a client browser that supports HTTP 1.1 (such as Internet Explorer version 4.0 or later), and if HTTP 1.1 is enabled, the HTTP connections remain open by default. This is functionally equivalent to both the client and the server including Connection: Keep-Alive headers with every HTTP request and response.

The following code demonstrates the sending of a Keep-Alive header.

DWORD SendHeaderToClient(LPEXTENSION_BLOCK pECB) 
{ 
  CHAR szHeader[] = "Content-type: test/html\r\n\r\n"; 
  DWORD hseStatus = HSE_STATUS_SUCCESS; 

  BOOL fReturn = pECB->ServerSupportFunction(pECB->ConnID,  
    HSE_REQ_SEND_RESPONSE_HEADER, 
    "Connection:Keep-Alive" // Telling the client not to close the connection. 
    NULL, 
    (LPDWORD) szHeader); 

  if (!fReturn) 
    hseStatus = HSE_STATUS_ERROR; 

  return hseStatus; 
} 

If the request indicates that the connection should remain open, subsequent requests can be made sequentially, a practice known as pipelining. When a client pipelines requests, there is no need to wait for earlier requests to be serviced before sending subsequent ones. IIS ensures that pipelined requests are returned to the client in the order in which they were received. Because IIS manages the ordering internally, an extension does not need to include any special processing for pipelined requests.

For more information about pipelined requests and transfer encoding, see RFC 2068, published by the World Wide Web Consortium.