📄 ch25.htm
字号:
greater than <TT><FONT FACE="Courier">cbAvailableBytes</FONT></TT>,
<TT><FONT FACE="Courier">lpbData</FONT></TT> is only holding part
of the client's data, and you'll have to ferret out the rest of
the data with the <TT><FONT FACE="Courier">ReadClient()</FONT></TT>
callback function.
<P>
An additional possibility is that <TT><FONT FACE="Courier">cbTotalBytes</FONT></TT>
has a value of <TT><FONT FACE="Courier">0xFFFFFFFF</FONT></TT>.
This means that there's at least four gigabytes of client data
sitting out there, waiting to be read. What are the chances that
you're going to receive that much data? If you do expect it, you'll
be happy to know that you can keep calling <TT><FONT FACE="Courier">ReadClient()
</FONT></TT>until you get everything that's there. It's a good
thing API functions are fast.
<H4>The Callback Functions</H4>
<P>
Throughout some of these other functions, there have been references
to callback functions. These are the nice little hooks that let
you get information that the server supplies you with. The functions
are listed in Table 25.3, along with a brief description of each.
They are <TT><FONT FACE="Courier">GetServerVariable()</FONT></TT>,
<TT><FONT FACE="Courier">ReadClient()</FONT></TT>, <TT><FONT FACE="Courier">WriteClient()</FONT></TT>
and <TT><FONT FACE="Courier">ServerSupportFunction()</FONT></TT>.
<P>
<CENTER><B><FONT SIZE=2>Table 25.3. ISAPI DLL callback functions
and purposes.</FONT></B></CENTER>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Function</I></TD><TD WIDTH=356><I>Purpose</I>
</TD></TR>
<TR><TD WIDTH=234><TT><FONT FACE="Courier">GetServerVariabl</FONT></TT>e
</TD><TD WIDTH=356>Retrieves connection information or server details
</TD></TR>
<TR><TD WIDTH=234><TT><FONT FACE="Courier">ReadClient</FONT></TT>
</TD><TD WIDTH=356>Reads data from the client's HTTP request</TD>
</TR>
<TR><TD WIDTH=234><TT><FONT FACE="Courier">WriteClient</FONT></TT>
</TD><TD WIDTH=356>Sends data back to the client</TD></TR>
<TR><TD WIDTH=234><TT><FONT FACE="Courier">ServerSupportFunction </FONT></TT>
</TD><TD WIDTH=356>Provides access to general and server-specific functions
</TD></TR>
</TABLE></CENTER>
<P>
<H5><TT><FONT FACE="Courier">GetServerVariable</FONT></TT></H5>
<P>
<TT><FONT FACE="Courier">GetServerVariable</FONT></TT> is used
to return information that the server has in regards to a specific
HTTP connection, as well as server-specific information. This
is done by specifying the name of the server variable that contains
the data in <TT><FONT FACE="Courier">lpszVariableName</FONT></TT>.
On the way to the server, the Size indicator (<TT><FONT FACE="Courier">lpdwSize</FONT></TT>)
specifies how much space it has available in its buffer (<TT><FONT FACE="Courier">lpvBuffer</FONT></TT>).
On the way back, the Size indicator (<TT><FONT FACE="Courier">lpdwSize</FONT></TT>)
is set to the amount of bytes now contained in that buffer. If
the Size (<TT><FONT FACE="Courier">lpdwSize</FONT></TT>), going
in, is larger than the number of bytes left for reading, the Size
indicator (<TT><FONT FACE="Courier">lpdwSize</FONT></TT>) will
be set to the number of bytes that were placed in the buffer (<TT><FONT FACE="Courier">lpvBuffer</FONT></TT>).
Otherwise, the number should be the same going in and coming out.
Here are the details on how the <TT><FONT FACE="Courier">GetServerVariable()</FONT></TT>
function is defined:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">BOOL WINAPI GetServerVariable (<BR>
HCONN hConn,<BR>
LPSTR lpszVariableName,
<BR>
LPVOID lpvBuffer,
<BR>
LPDWORD lpdwSize);</FONT></TT>
</BLOCKQUOTE>
<P>
Tables 25.4 and 25.5 show the accepted parameters and possible
error returns for <TT><FONT FACE="Courier">GetServerVariable()</FONT></TT>,
respectively.<P>
<CENTER><B><FONT SIZE=2>Table 25.4. Accepted parameters for </FONT></B><TT><B><FONT SIZE=2 FACE="Courier">GetServerVariable</FONT></B></TT><B><FONT SIZE=2>
callback function.</FONT></B></CENTER>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Parameter</I></TD><TD WIDTH=81><I>Direction</I>
</TD><TD WIDTH=332><I>Purpose</I></TD></TR>
<TR><TD WIDTH=177><TT><FONT FACE="Courier">hConn</FONT></TT></TD>
<TD WIDTH=81>IN</TD><TD WIDTH=332>Connection handle (if request pertains to a connection), otherwise any non-NULL
</TD></TR>
<TR><TD WIDTH=177><TT><FONT FACE="Courier">lpszVariableName</FONT></TT>
</TD><TD WIDTH=81>IN </TD><TD WIDTH=332>Name of the variable being requested (See Table 25.6 for a list)
</TD></TR>
<TR><TD WIDTH=177><TT><FONT FACE="Courier">lpvBuffer</FONT></TT>
</TD><TD WIDTH=81>OUT </TD><TD WIDTH=332>Pointer to buffer that will receive the requested information
</TD></TR>
<TR><TD WIDTH=177><TT><FONT FACE="Courier">lpdwSize </FONT></TT>
</TD><TD WIDTH=81>IN/OUT</TD><TD WIDTH=332>Indicates the size of the <TT><FONT FACE="Courier">lpvBuffer</FONT></TT> buffer on execution; on completion is set to the resultant number of bytes transferred into <TT><FONT FACE="Courier">lpvBuffer</FONT></TT>
</TD></TR>
</TABLE></CENTER>
<BR>
<P>
<CENTER><B><FONT SIZE=2>Table 25.5. Possible error codes returned
if </FONT></B><TT><B><FONT SIZE=2 FACE="Courier">GetServerVariable</FONT></B></TT><B><FONT SIZE=2>
returns FALSE.</FONT></B></CENTER>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Error Code</I></TD><TD WIDTH=327><I>Meaning</I>
</TD></TR>
<TR><TD WIDTH=263><TT><FONT FACE="Courier">ERROR_INVALID_INDEX</FONT></TT>
</TD><TD WIDTH=327>Bad or unsupported variable identifier</TD>
</TR>
<TR><TD WIDTH=263><TT><FONT FACE="Courier">ERROR_INVALID_PARAMETER</FONT></TT>
</TD><TD WIDTH=327>Bad connection handle</TD></TR>
<TR><TD WIDTH=263><TT><FONT FACE="Courier">ERROR_INSUFFICIENT_BUFFER</FONT></TT>
</TD><TD WIDTH=327>More data than what is allowed for <TT><FONT FACE="Courier">lpvBuffer</FONT></TT>; necessary size now set in <TT><FONT FACE="Courier">lpdwSize</FONT></TT>
</TD></TR>
<TR><TD WIDTH=263><TT><FONT FACE="Courier">ERROR_MORE_DATA</FONT></TT>
</TD><TD WIDTH=327>More data than what is allowed for <TT><FONT FACE="Courier">lpvBuffer</FONT></TT>, but total size of data is unknown
</TD></TR>
<TR><TD WIDTH=263><TT><FONT FACE="Courier">ERROR_NO_DATA</FONT></TT>
</TD><TD WIDTH=327>The requested data isn't available</TD></TR>
</TABLE></CENTER>
<P>
<P>
Use of the <TT><FONT FACE="Courier">GetServerVariable()</FONT></TT>
callback function requires knowing exactly what variables are
available, and why you might want to get them. A brief description
of each of these variables can be found in Table 25.6 "Variable
Names and Purposes," but a more detailed explanation can
be found in <A HREF="ch3.htm" >Chapter 3</A>, as they are also
commonly encountered as CGI environment variables.<P>
<CENTER><B><FONT SIZE=2>Table
25.6. Variable names and purposes.</FONT></B></CENTER>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Name</I></TD><TD WIDTH=87><CENTER><I>Data Type</I>
</TD><TD WIDTH=288><I>Purpose</I></TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">AUTH_TYPE</FONT></TT>
</TD><TD WIDTH=87><CENTER>String</TD><TD WIDTH=288>Type of authentication in use; normally either none or basic
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">CONTENT_LENGTH</FONT></TT>
</TD><TD WIDTH=87><CENTER>Dword</TD><TD WIDTH=288>Number of bytes contained in <TT><FONT FACE="Courier">STDIN</FONT></TT> from a POST request
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">CONTENT_TYPE</FONT></TT>
</TD><TD WIDTH=87><CENTER>String</TD><TD WIDTH=288>Type of Content contained in <TT><FONT FACE="Courier">STDIN</FONT></TT>
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">GATEWAY_INTERFACE</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Revision of CGI spec that the server complies to
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">PATH_INFO</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Additional path information, if any, which comes before the <TT><FONT FACE="Courier">QUERY_STRING</FONT></TT> but after the script name
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">PATH_TRANSLATED</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288><TT><FONT FACE="Courier">PATH_INFO</FONT></TT> with any virtual path names expanded
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">QUERY_STRING</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Information following the ? in the URL
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">REMOTE_ADDR</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>IP address of the client (or client gateway/proxy)
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">REMOTE_HOST</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Hostname of client (or client gateway/proxy)
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">REMOTE_USER</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Username, if any, supplied by the client and authenticated by the server
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">REQUEST_METHOD</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>The HTTP request method, normally either GET or POST
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">UNMappeD_REMOTE_USER</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Username before any ISAPI filter mapped the user to an account name (the mapped name appears in <TT><FONT FACE="Courier">REMOTE_USER</FONT></TT>)
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">SCRIPT_NAME</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Name of the ISAPI DLL being executed
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">SERVER_NAME</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Name or IP address of server
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">SERVER_PORT</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>TCP/IP port that received the request
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">SERVER_PORT_SECURE</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>If the request is handled by a secure port, the string value will be one. Otherwise it will be zero.
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">SERVER_PROTOCOL</FONT></TT>
</TD><TD WIDTH=87><CENTER>string </TD><TD WIDTH=288>Name and version of information retrieval protocol (usually HTTP/1.0)
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">SERVER_SOFTWARE</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Name and version of the Web server running the ISAPI DLL
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">ALL_HTTP</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>All HTTP headers that are not placed in a previous variable. The format for these is <TT><FONT FACE="Courier">http_<header field name></FONT></TT>, and are contained within a null-terminated string,
each separated by a line feed.
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">HTTP_AccEPT</FONT></TT>
</TD><TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Semi-colon (;) concatenated list of all AccEPT statements from the client
</TD></TR>
<TR><TD WIDTH=215><TT><FONT FACE="Courier">URL</FONT></TT></TD>
<TD WIDTH=87><CENTER>string</TD><TD WIDTH=288>Provides the base portion of the URL (Version 2.0 only)
</TD></TR>
</TABLE></CENTER>
<P>
<H5><TT><FONT FACE="Courier">ReadClient</FONT></TT></H5>
<P>
<TT><FONT FACE="Courier">ReadClient</FONT></TT> does what you'd
expect it to-it keeps reading data from the body of the client's
HTTP request and placing it into a storage buffer. Just as <TT><FONT FACE="Courier">GetServerVariable()</FONT></TT>
and the other callback functions do, it uses the Buffer Size Indicator
(<TT><FONT FACE="Courier">lpdwSize</FONT></TT>) as an indicator
to show how big the buffer (<TT><FONT FACE="Courier">lpvBuffer</FONT></TT>)
initially was, and how big it is after it's finished. <TT><FONT FACE="Courier">ReadClient</FONT></TT>
has only two possible return values, and no specific associated
error codes; however, if the return of <TT><FONT FACE="Courier">ReadClient()</FONT></TT>
is True, but <TT><FONT FACE="Courier">lpdwSize</FONT></TT> is
0, the socket closes prematurely. The following code shows how
<TT><FONT FACE="Courier">ReadClient()</FONT></TT> would be defined:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">BOOL ReadClient (<BR>
HCONN hConn,<BR>
LPVOID lpvBuffer,
<BR>
LPDWORD lpdwSize);</FONT></TT>
</BLOCKQUOTE>
<P>
Table 25.7 details the expected parameters of the <TT><FONT FACE="Courier">ReadClient()</FONT></TT>
function.<P>
<CENTER><B><FONT SIZE=2>Table 25.7. Expected parameters
for </FONT></B><TT><B><FONT SIZE=2 FACE="Courier">ReadClient</FONT></B></TT><B><FONT SIZE=2>
callback function.</FONT></B></CENTER>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Parameter</I></TD><TD WIDTH=115><CENTER><I>Data Direction</I>
</TD><TD WIDTH=366><I>Purpose</I></TD></TR>
<TR><TD WIDTH=109><TT><FONT FACE="Courier">hConn</FONT></TT></TD>
<TD WIDTH=115><CENTER>IN</TD><TD WIDTH=366>Connection Handle (cannot be NULL)
</TD></TR>
<TR><TD WIDTH=109><TT><FONT FACE="Courier">lpvBuffer</FONT></TT>
</TD><TD WIDTH=115><CENTER>OUT</TD><TD WIDTH=366>Pointer to buffer for receiving client data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -