⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch25.htm

📁 CGI programming is the hottest stuff to look out for in this book
💻 HTM
📖 第 1 页 / 共 5 页
字号:
</TD></TR>
<TR><TD WIDTH=109><TT><FONT FACE="Courier">lpdwSize</FONT></TT>
</TD><TD WIDTH=115><CENTER>IN/OUT</TD><TD WIDTH=366>Size of available buffer/number of bytes placed in buffer
</TD></TR>
</TABLE></CENTER>
<P>
<H5><TT><FONT FACE="Courier">WriteClient</FONT></TT></H5>
<P>
<TT><FONT FACE="Courier">WriteClient</FONT></TT> writes information
back to the client from information stored in the buffer. The
Buffer Size indicator (<TT><FONT FACE="Courier">lpdwSize</FONT></TT>),
in this case, functions as a record of how many bytes are supposed
to be written to the client from the buffer, and how many were.
Since this might be used for binary data, it does not assume that
the data will be in the form of a null-terminated string like
the <TT><FONT FACE="Courier">ServerSupportFunction</FONT></TT>
does. A sample definition of the <TT><FONT FACE="Courier">WriteClient</FONT></TT>
function follows.
<BLOCKQUOTE>
<TT><FONT FACE="Courier">BOOL WriteClient(<BR>
&nbsp;&nbsp;&nbsp;&nbsp;HCONN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hConn,
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;LPVOID&nbsp;&nbsp;&nbsp;&nbsp;lpvBuffer,
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;LPDWORD&nbsp;&nbsp;&nbsp;&nbsp;lpdwSize,
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;dwReserved);</FONT></TT>
</BLOCKQUOTE>
<P>
Table 25.8 shows what parameters are accepted for the <TT><FONT FACE="Courier">WriteClient</FONT></TT>
callback function. (An additional reserved parameter is set aside
for  changes in the function's behavior that might be implemented
in the future.)<P>
<CENTER><B><FONT SIZE=2>Table 25.8. Expected parameters
for the </FONT></B><TT><B><FONT SIZE=2 FACE="Courier">WriteClient</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=356><I>Purpose</I></TD></TR>
<TR><TD WIDTH=119><TT><FONT FACE="Courier">hConn</FONT></TT></TD>
<TD WIDTH=115><CENTER>IN</TD><TD WIDTH=356>Connection Handle (cannot be NULL)
</TD></TR>
<TR><TD WIDTH=119><TT><FONT FACE="Courier">lpvBuffer</FONT></TT>
</TD><TD WIDTH=115><CENTER>IN</TD><TD WIDTH=356>Pointer to data being written to client
</TD></TR>
<TR><TD WIDTH=119><TT><FONT FACE="Courier">lpdwSize</FONT></TT>
</TD><TD WIDTH=115><CENTER>IN/OUT</TD><TD WIDTH=356>Number of bytes being sent; number of bytes actually sent
</TD></TR>
<TR><TD WIDTH=119><TT><FONT FACE="Courier">dwReserved</FONT></TT>
</TD><TD WIDTH=115><CENTER></TD><TD WIDTH=356>Unspecified-reserved for future use
</TD></TR>
</TABLE></CENTER>
<P>
<H5><TT><FONT FACE="Courier">ServerSupportFunction</FONT></TT>
</H5>
<P>
The final callback function, <TT><FONT FACE="Courier">ServerSupportFunction</FONT></TT>,
is one of the most powerful. It sends a Service Request Code to
the server itself, which is a value that the server translates
into a request to execute an internal function. An example of
such a function would be redirecting the client's browser to a
new URL, something that the server knows how to do without any
help. This allows some standard operations to be performed, but
it also gives server manufacturers a method for allowing developers
to have easy access to a specialized internal function. Be it
a built-in search routine, an update of user databases, or anything
else, this function can call anything the server will allow. The
actual list of what each server will allow varies, of course,
but the definitions for the individual functions have a fixed
order. Any service request code with a value of 1000 or less is
a reserved value, used for mandatory <TT><FONT FACE="Courier">ServerSupportFunction</FONT></TT>
codes and defined in the <TT><FONT FACE="Courier">HttpExt.h</FONT></TT>
file. Anything with a Service Request Code of 1001 or greater
is a general purpose server function, and should be able to be
found in the servers own <TT><FONT FACE="Courier">*Ext.H</FONT></TT>
file. For example, Process Software's Purveyor maintains a <TT><FONT FACE="Courier">Prvr_Ext.h</FONT></TT>
file listing some additional supported functions, which have been
included in Table 25.11.  The <TT><FONT FACE="Courier">ServerSupportFunction</FONT></TT>
definition follows.
<BLOCKQUOTE>
<TT><FONT FACE="Courier">BOOL ServerSupportFunction (<BR>
&nbsp;&nbsp;&nbsp;&nbsp;HCONN&nbsp;&nbsp;&nbsp;&nbsp;hConn,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;dwHSERequest,
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;LPVOID&nbsp;&nbsp;&nbsp;&nbsp;lpvBuffer,
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;LPDWORD&nbsp;&nbsp;&nbsp;&nbsp;lpdwSize,
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;LPDWORD&nbsp;&nbsp;&nbsp;&nbsp;lpdwDataType);</FONT></TT>
</BLOCKQUOTE>
<P>
Tables 25.9 and 25.10 list the acceptable parameters and the standard
defined values for service request codes for the <TT><FONT FACE="Courier">ServerSupportFunction</FONT></TT>,
respectively.
<P>
<CENTER><B><FONT SIZE=2>Table 25.9. Expected parameters
in the </FONT></B><TT><B><FONT SIZE=2 FACE="Courier">ServerSupportFunction</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=337><I>Purpose</I></TD></TR>
<TR><TD WIDTH=138><TT><FONT FACE="Courier">hconn</FONT></TT></TD>
<TD WIDTH=115><CENTER>IN</TD><TD WIDTH=337>Connection Handle (cannot be null)
</TD></TR>
<TR><TD WIDTH=138><TT><FONT FACE="Courier">dwHSERequest</FONT></TT>
</TD><TD WIDTH=115><CENTER>IN</TD><TD WIDTH=337>Service Request code (See Table 25.10 for default values)
</TD></TR>
<TR><TD WIDTH=138><TT><FONT FACE="Courier">lpvBuffer</FONT></TT>
</TD><TD WIDTH=115><CENTER>IN</TD><TD WIDTH=337>Buffer for optional status string or other information passing
</TD></TR>
<TR><TD WIDTH=138><TT><FONT FACE="Courier">lpdwSize</FONT></TT>
</TD><TD WIDTH=115><CENTER>IN/OUT</TD><TD WIDTH=337>Size of optional status string when sent; bytes of status string sent, including NULL term
</TD></TR>
<TR><TD WIDTH=138><TT><FONT FACE="Courier">lpdwDataType</FONT></TT>
</TD><TD WIDTH=115><CENTER>IN</TD><TD WIDTH=337>Optional null-terminated string with headers or data to be appended and sent with the header generated by the service request (If NULL, header is terminated by <TT><FONT FACE="Courier">\r\n</FONT></TT>)
</TD></TR>
</TABLE></CENTER>
<P>
<CENTER><B><FONT SIZE=2>Table 25.10. Defined values for standard
service requests.</FONT></B></CENTER>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Service Request</I></TD><TD WIDTH=295><I>Action</I>
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_REQ_SEND_URL_REDIRECT_RESP</FONT></TT>
</TD><TD WIDTH=295>Sends a URL Redirect (302) message to the client. The buffer (<TT><FONT FACE="Courier">lpvBuffer</FONT></TT>) should contain the null-terminated URL, which does not need to be resident on the server. No further processing is needed after 
this call.
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_REQ_SEND_URL</FONT></TT>
</TD><TD WIDTH=295>Sends the data to the client specified by the null-terminated buffer (<TT><FONT FACE="Courier">lpvBuffer</FONT></TT>), as if the client had requested that URL. The URL cannot specify any protocol information (for example, it must be 
<TT><FONT FACE="Courier">/document.htm</FONT></TT> instead of <TT><FONT FACE="Courier">http://server.com/document.htm</FONT></TT>).
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_REQ_SEND_RESPONSE_HEADER</FONT></TT>
</TD><TD WIDTH=295>Sends a complete HTTP server response header, which includes the status code, server version, message time, and MIME version. The <TT><FONT FACE="Courier">DataType</FONT></TT> buffer (<TT><FONT FACE="Courier">lpdwDataType</FONT></TT>) 
should contain additional headers such as content type and length, along with a CRLF (Carriage Return/Line Feed (<TT><FONT FACE="Courier">\r\n)</FONT></TT>) combination and any data. It will read text data only, and it will stop at the first \0 
termination.
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_REQ_MAP_URL_TO_PATH</FONT></TT>
</TD><TD WIDTH=295>The buffer (<TT><FONT FACE="Courier">lpvBuffer</FONT></TT>) points to the logical path to the URL on entry, and it returns with the physical path. The Size buffer contains the number of bytes being sent in, and is adjusted to the number 
of bytes sent back on return.
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_REQ_DONE_WITH_SESSION</FONT></TT>
</TD><TD WIDTH=295>If the server has previously been sent an <TT><FONT FACE="Courier">HSE_STATUS_PENDING</FONT></TT> response, this request informs the server that the session is no longer needed, and it can feel free to clean up the previous session and 
its structures. All parameters are ignored in this case, except for the connection handle (<TT><FONT FACE="Courier">hConn</FONT></TT>).
</TD></TR>
</TABLE></CENTER>
<P>
<CENTER><B><FONT SIZE=2>Table 25.11. Examples of server-defined
acceptable service requests (Purveyor 1.1).</FONT></B></CENTER>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><I>Service Request</I></TD><TD WIDTH=295><I>Action</I>
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_GET_COUNTER_FOR_GET_METHOD</FONT></TT>
</TD><TD WIDTH=295>Accepts the <TT><FONT FACE="Courier">SERVER_NAME</FONT></TT> system variable in the Buffer (<TT><FONT FACE="Courier">lpvBuffer</FONT></TT>), the length of <TT><FONT FACE="Courier">SERVER_NAME</FONT></TT> in the Size buffer (<TT><FONT 
FACE="Courier">lpdwSize</FONT></TT>), and returns the total number of GET requests served since initiation of the server, storing them in the <TT><FONT FACE="Courier">DataType</FONT></TT> buffer (<TT><FONT FACE="Courier">lpdwDataType</FONT></TT>)
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_GET_COUNTER_FOR_POST_METHOD</FONT></TT>
</TD><TD WIDTH=295>Except <TT><FONT FACE="Courier">DataType</FONT></TT> (<TT><FONT FACE="Courier">lpdwDataType</FONT></TT>), will hold the number of POST requests since startup of the server
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_GET_COUNTER_FOR_HEAD_METHOD</FONT></TT>
</TD><TD WIDTH=295>Except <TT><FONT FACE="Courier">DataType</FONT></TT>(<TT><FONT FACE="Courier">lpdwDataType</FONT></TT>), will hold the number of HEAD requests since startup of the server
</TD></TR>
<TR><TD WIDTH=295><TT><FONT FACE="Courier">HSE_GET_COUNTER_FOR_ALL_METHODS</FONT></TT>
</TD><TD WIDTH=295>Except <TT><FONT FACE="Courier">DataType</FONT></TT> (<TT><FONT FACE="Courier">lpdwDataType</FONT></TT>), will hold the total number of all requests since server startup
</TD></TR>
</TABLE></CENTER>
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD WIDTH=590>
<BLOCKQUOTE>
Currently, there aren't many extra defined server functions in the public arena. But, given the rate of server expansion, and Microsoft's race to expand it's Internet Information Server, it wouldn't be surprising to see a large number of very useful 
functions show up in the near future.</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<P>
As you've seen, an ISA is much like a traditional program that
has a couple of added advantages, such as being able to get at
the server program's insides, and taking advantage of things that
might otherwise require either lots of file reading, or not be
able to be accomplished at all. Next, however, you're going to
take a look at something that's one step beyond that-adding onto
the server functionality itself, to make it do whatever tricks
you want it to.
<H3><A NAME="InternetServerAPIFilter">Internet Server API Filter</A>
</H3>
<P>
ISAPI filters are quite different from a traditional CGI program.
If ISAPI DLLs make a server more flexible, ISAPI filters turn
a server into a true contortionist, able to flex whatever way
they need to. They're not just resident with the server, they're
part of the server itself, having been loaded into memory and
the server's configuration ahead of time. They're direct extensions
of the server, allowing them to do tasks that no CGI program could
think of doing, such as enhancing the local logging of file transfers,
building in pre-defined methods of handling forms or searches,
and even doing customized local authentication for requests. You're
making the server evolve into something more powerful, instead
of adding pieces that the server can call for help.
<P>
When you create an ISAPI filter, you're creating a linked DLL
that's being examined every time the server processes an HTTP
request. The goal is to filter out specific notifications that
you're interested in, and remove the duties of handling that particular
process from the core functionality of the server. You're essentially
saying, &quot;Oh, don't worry about that when you see it; that's
what this filter is for.&quot; This scalability allows you to
take a basic server and customize it to meet whatever needs you
might have. You're adding scalability to the server so that it
meets your needs, even if the original manufacturer didn't anticipate
them.
<P>
Like an ISAPI DLL, an ISAPI filter has two entry points that must
be present in order to verify that the function meets the current
specification, and that it has a place to receive information
from the server. Unlike an ISAPI DLL, though, an ISAPI filter
isn't something that's spur-of-the-moment in its use-any filters
you define have to be entered in the system registry so that they
are literally part of the server's configuration. Since they're
intercepting things as they happen, the server needs to know about
them. In this case, it's convinced that it always had the ability
to do these functions, it just never used them before.
<H4>Entry Point-<TT><FONT FACE="Courier">GetFilterVersion</FONT></TT>
</H4>
<P>
The first entry point to define in the ISAPI filter is the one
that tells the server that it does in fact correspond to the correct

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -