ServerSupportFunction

The ServerSupportFunction function is a callback function supplied in the EXTENSION_CONTROL_BLOCK (ECB). It supports several auxiliary functions not covered by other callback functions in the ECB.

BOOL ServerSupportFunction(

    HCONN ConnID,

 

    DWORD dwHSERequest,

 

    LPVOID lpvBuffer,

 

    LPDWORD lpdwSize,

 

    LPDWORD lpdwDataType

 

   );

 

Parameters

ConnID

A logical connection identifier for identifying the client to whom the response data should be sent.

dwHSERequest

A DWORD containing the HTTP Server Extension Request type, which indicates the requested functions by the ISAPI application. The various values are:

HSE_REQ_SEND_URL_REDIRECT_RESP

This sends a 302 (URL Redirect) message to the client. No further processing is needed after the call. This operation is similar to specifying "URI: <URL>" in a CGI script header. The lpvBuffer variable should point to a null-terminated string of URL. The variable lpdwSize should have the size of lpvBuffer. The variable lpdwDataType is ignored.

HSE_REQ_SEND_URL

This sends the data specified by the URL to the client as if the client had requested that URL. The null-terminated URL pointed to by lpvBuffer must be on the server and must not specify protocol information (that is, it must begin with a  / ). No further processing is required after this call. The parameter lpdwSize points to a DWORD holding the size of lpvBuffer. The parameter lpdwDataType is ignored.

HSE_REQ_SEND_RESPONSE_HEADER

This sends a complete HTTP server response header including the status, server version, message time, and MIME version. The ISAPI application should append other HTTP headers such as the content type and content length, followed by an extra  \r\n . This function only takes textual data, up to the first '\0' terminator

HSE_REQ_MAP_URL_TO_PATH

The lpvBuffer parameter is a pointer to the buffer that contains the logical path on entry and the physical path on exit. The lpdwSize parameter is a pointer to the DWORD containing the size of the buffer passed in lpvBuffer on entry, and the number of bytes placed in the buffer on exit. The lpdwDataType parameter is ignored.

HSE_REQ_DONE_WITH_SESSION

If the server extension wants to hold on to the session because of extended processing requirements, it needs to tell the server when the session is finished so the server can close it and free the related structures. The parameters lpvBuffer, lpdwSize, and lpdwDataType are all ignored.

lpvBuffer

A pointer to the buffer that contains the primary argument required for the support function requested.

lpdwSize

A pointer to a DWORD that contains the size of data that is passed in the buffer pointed to by lpvBuffer. This parameter may be unused for several of the support function options.

lpdwDataType

A pointer to a DWORD containing a pointer, flags, or secondary arguments required for the specified support function.

Return Values

If the function is successful, a value of TRUE is returned. If an error occurs, a value of FALSE is returned. The GetLastError function can be called to determine the cause of the error.

Remarks

The ServerSupportFunction function provides several support functions that are not covered directly by ECB or the standard callback function. The following list describes the various requests that can be made using the ServerSupportFunction function:

  1.  dwHSERRequest: HSE_REQ_IO_COMPLETION

lpvBuffer

A pointer to callback function PFN_HSE_IO_COMPLETION.

lpdwSize

This is ignored.

LpdwDataType

A pointer of type (PVOID) which is used as the context.

 

This option lets the ISAPI application set a callback function and context to use for handling asynchronous I/O operations. The callback function is used only if the function pointer passed is non-NULL. Any context value is allowed. If multiple calls are made for this option, the values used in the most recent call to ServerSupportFunction will be used (all old values will be lost). The callback function is defined as:

typedef VOID  (WINAPI * PFN_HSE_IO_COMPLETION)(

    IN EXTENSION_CONTROL_BLOCK * pECB,

    IN PVOID    pContext,

    IN DWORD    cbIO,

    IN DWORD    dwError );

 

In case of errors during asynchronous I/O processing, the server makes a single call to the callback function. It is the responsibility of the ISAPI application to do the cleanup during the call.

  2.  dwHSERRequest: HSE_REQ_TRANSMIT_FILE

lpvBuffer

A pointer to the HSE_TF_INFO object.

LpdwSize

This is ignored.

LpdwDataType

This is ignored.

 

This option lets the ISAPI application use TransmitFile to send a file (faster) to the client. The server performs this operation asynchronously. The application should either submit a callback function (and context) by setting the values in the HSE_TF_INFO object passed in or should call the ServerSupportFucntion function with HSE_REQ_IO_COMPLETION.

If none of the above is done, this call will fail and the server will return an error (ERROR_INVALID_PARAMETER). Also, the application should specify the file handle in the structure that is passed in.

If all parameters are present, the server submits this operation to its internal asynchronous I/O queue and returns to the caller. At this point, the ISAPI application can return HSE_STATUS_PENDING (if returning from HttpExtenionProc) and later use HSE_DONE_WITH_SESSION when the callback occurs indicating that the I/O was completed.

typedef struct _HSE_TF_INFO 

 

    //

    // callback and context information

    // the callback function will be called when IO is completed.

    // the context specified will be used during such callback.

    //

    // These values (if non-NULL) will override the one set by calling

    //  ServerSupportFunction() with HSE_REQ_IO_COMPLETION

    //

    PFN_HSE_IO_COMPLETION   pfnHseIO;

    PVOID  pContext;

 

    // file should have been opened with FILE_FLAG_SEQUENTIAL_SCAN

    HANDLE hFile;

 

    //

    // HTTP header and status code

    // These fields are used only if HSE_IO_SEND_HEADERS

    //  is present in dwFlags

    //

    LPCSTR pszStatusCode; // HTTP Status Code  eg: "200 OK"

 

    DWORD  BytesToWrite; // value of "0" means send entire file

    DWORD  Offset;         // offset value within file to start from

 

    PVOID  pHead;        // pointer to Headers to be sent before file

    DWORD  HeadLength;   // header length

    PVOID  pTail;        // pointer to Tail to be sent after file data

    DWORD  TailLength;   // tail length

 

    DWORD  dwFlags;      // includes HSE_IO_DISCONNET_AFTER_SEND, ...

 

} HSE_TF_INFO, * LPHSE_TF_INFO;

 

A special flag, HSE_IO_DISCONNECT_AFTER_SEND, can be used if the application is mainly concerned with transmitting the file and closing the connection. This flag enables the server to optimally reuse its internal buffers and sockets for future connections. Thus, it improves the perceived latency by optimally using system features. However, the application will not be able to do any further data transmission if this flag is indicated, because the session to the client will be torn down.

Another special flag, HSE_IO_SEND_HEADER, can be used for transmitting custom header information to the client. The ISAPI application can store the status code (for example,  200 OK ) in the pszStatusCode member of the HSE_TF_INFO structure. When the header flag is turned on, the Internet server will automatically construct the appropriate HTTP header and send it to the client along with the file contents.

If this flag is used for header transmission, then the ISAPI application should not send its own header using the ServerSupportFunction(HSE_REQ_SEND_RESPONSE_HEADERS) function. In addition to the status code, the application can also include a special head buffer for each data chunk that it transmits from a file.

The file handle specified, hFile, should be opened using the Win32 CreateFile function with the FILE_FLAG_SEQUENTIAL_SCAN and FILE_FLAG_OVERLAPPED turned on. The head and tail buffers specified by pHead and pTail are optional.

Asynchronous I/O Support

Previous versions of this documentation have supported synchronous I/O operations using the callback functions, ReadClient and WriteClient. However, the ability to support asynchronous operations is important because it frees up a server pool thread from being blocked in completing the I/O operation. In addition, the Internet server engine already has built-in support to manage asynchronous I/O operations using the completion ports and server thread pool.

Support for asynchronous I/O operations were initially planned for a later version of this documentation. However, because of the need to support asynchronous I/O operations, a Microsoft-specific extension has been provided in this documentation. Thus, asynchronous write operations are supported in this documentation using the existing callback function WriteClient, with a special flag indicating that the operation has to be performed asynchronously. In addition, this documentation also provides a mechanism for requesting that the server transmit a file using the TransmitFile function. This function is a Win32 function that supports fast transmission of a file-from-file system over any stream sockets. It is supported in the Microsoft Windows Sockets implementation in Windows NT 3.51 and later.