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.