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

📄 ch26.htm

📁 CGI programming is the hottest stuff to look out for in this book
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<BLOCKQUOTE>
<B>Listing 26.1. Parameter block structure definition.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#include &quot;base/pblock.h&quot;<BR>
<BR>
typedef struct {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;char *name,*value;<BR>
} pb_param;<BR>
<BR>
struct pb_entry {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;pb_param *param;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;struct pb_entry *next;<BR>
};<BR>
<BR>
typedef struct {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;int hsize;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;struct pb_entry **ht;<BR>
} pblock;</FONT></TT>
</BLOCKQUOTE>
<HR>
<HR>
<BLOCKQUOTE>
<B>Listing 26.2. </B><TT><B><FONT SIZE=2 FACE="Courier">pblock</FONT></B></TT><B>
hash table sample definition.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#include &quot;base/pblock.h&quot;<BR>
<BR>
/* Create parameter with given name and value */<BR>
pb_param *param_create(char *name, char *value);<BR>
<BR>
/* Free Parameter if not null, Return 1 if non-null, 0 if null*/
<BR>
int param_free(pb_param *pp);<BR>
<BR>
/* Create new pblock of Hash Table size 'n' */<BR>
pblock *pblock_create(int n);<BR>
<BR>
/* Free defined pblock and entries it contains */<BR>
void pblock_free(pblock *pb);<BR>
<BR>
/* Find entry with given name in pblock */<BR>
pblock *pblock_find(char *name, pblock *pb);<BR>
<BR>
/* Return value of pblock with given name found in it */<BR>
char *pblock_findval(char *name, pblock *pb);<BR>
<BR>
/* Find entry containing name in pblock, and remove it */<BR>
pblock *pblock_remove(char *name, pblock *pb);<BR>
<BR>
/* Create new parameter, insert into specified pblock */<BR>
pb_param *pblock_nvinsert(char *name, char *value, pblock *pb);
<BR>
<BR>
/* Insert a pb_param into a pblock */<BR>
void pblock_pinsert)pb_param *pp, pblock *pb);<BR>
<BR>
/* Scan the string for name=value pairs */<BR>
int pblock_str2pblock(char *str, pblock *pb);<BR>
<BR>
/* Place all the parameters in pblock into string */<BR>
char *pblock_pblock2str(pblock *pb, char *str);</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Not all the functions are needed for server application functions,
but the preceding listings show which functions are currently
defined. Before implementing any of these functions, however,
check the latest version of your server documentation, which contains
more specific details on each one of these functions, their use,
and their current state.
<H3><A NAME="Sessions">Sessions</A></H3>
<P>
A<I> session</I>, by Netscape's definition for the NSAPI, is the
time between the opening and the closing of the client connection.
To hold the data associated with the session in question and make
it available system-wide, a <TT><FONT FACE="Courier">Session</FONT></TT>
data structure is needed, as outlined in Listing 26.3.<BR>
<HR>
<BLOCKQUOTE>
<B>Listing 26.3. Sample </B><TT><B><FONT SIZE=2 FACE="Courier">Session</FONT></B></TT><B>
data structure.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#include &quot;base/session.h&quot;<BR>
<BR>
typdef struct {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;pblock *client;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;SYS_NETFD csd;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;netbuf *inbuf;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;struct in_addr iaddr;<BR>
} Session;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">client</FONT></TT> parameter block
points to two more pieces of information to help identify the
session uniquely: the IP address of the client machine and the
resolved DNS name of the client machine. Information in <TT><FONT FACE="Courier">csd</FONT></TT>
and <TT><FONT FACE="Courier">inbuf</FONT></TT> is relevant to
the socket descriptor for the connection, whereas the <TT><FONT FACE="Courier">iaddr</FONT></TT>
structure is for internal use and contains raw socket information.
<H3><A NAME="RequestStructure">Request Structure</A></H3>
<P>
When the client makes a request, various HTTP-related information
is stored, just as it is during normal CGI operations. All this
information is accessible through the <TT><FONT FACE="Courier">Request</FONT></TT>
data structure, as outlined in Listing 26.4.<BR>
<HR>
<BLOCKQUOTE>
<B>Listing 26.4. HTTP </B><TT><B><FONT SIZE=2 FACE="Courier">Request</FONT></B></TT><B>
data structure.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#include &quot;frame/req.h&quot;<BR>
<BR>
typedef struct {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;/* Server's working variables */<BR>
&nbsp;&nbsp;&nbsp;&nbsp;pblock *vars;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;/* Method, URI, and Protocol specified
*/<BR>
&nbsp;&nbsp;&nbsp;&nbsp;pblock *reqpb;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;/* Protocol Specific Headers */<BR>
&nbsp;&nbsp;&nbsp;&nbsp;int loadhdrs;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;pblock *headers;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;/* Server's Response headers */<BR>
&nbsp;&nbsp;&nbsp;&nbsp;pblock *srvhdrs;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;/* Object Set constructed to handle this
request */<BR>
&nbsp;&nbsp;&nbsp;&nbsp;httpd_objset *os;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;/* Last stat returned by request_stat_path
*/<BR>
&nbsp;&nbsp;&nbsp;&nbsp;char *statpath;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;struct stat *finfo;<BR>
<BR>
} Request;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Contained within the <TT><FONT FACE="Courier">Request</FONT></TT>
structure are several sources of data that your function can take
advantage of, depending on what function class your function belongs
to and what you're <BR>
looking for.
<P>
The <TT><FONT FACE="Courier">vars</FONT></TT> parameter block
contains function-specific variables, which are different for
every function class. In the section &quot;Functions, Variables,
and Their Responses,&quot; you will look in more detail at what
the possible values can be.
<P>
One of the first things your function comes in contact with is
the <TT><FONT FACE="Courier">reqpb</FONT></TT> parameter block
because it contains the data you first need to evaluate, as outlined
in Table 26.4.<BR>
<P>
<CENTER><B>Table 26.4. Request parameters contained in </B><TT><B><FONT SIZE=2 FACE="Courier">reqpb</FONT></B></TT><B>.</B></CENTER>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><CENTER><I>Parameter</I></CENTER></TD><TD WIDTH=462><CENTER><I>Purpose</I></CENTER>
</TD></TR>
<TR><TD WIDTH=128><TT><FONT FACE="Courier">method</FONT></TT>
</TD><TD WIDTH=462>HTTP method used to initialize the request; equivalent to the <TT><FONT FACE="Courier">REQUEST_METHOD</FONT></TT> variable
</TD></TR>
<TR><TD WIDTH=128><TT><FONT FACE="Courier">uri</FONT></TT></TD>
<TD WIDTH=462>The URI that the client requests</TD></TR>
<TR><TD WIDTH=128><TT><FONT FACE="Courier">protocol</FONT></TT>
</TD><TD WIDTH=462>The HTTP protocol version that the client supports
</TD></TR>
<TR><TD WIDTH=128><TT><FONT FACE="Courier">clf-request</FONT></TT>
</TD><TD WIDTH=462>The first line of the client's request to be used for logging or other similar purposes
</TD></TR>
</TABLE></CENTER>
<P>
<P>
The <TT><FONT FACE="Courier">headers</FONT></TT> block is just
what you would expect-the headers sent by the client. If more
than one value is sent for the same header, they are joined together
with a comma, as follows: 
<BLOCKQUOTE>
<TT><I><FONT FACE="Courier">Header: value1, value2<BR>
</FONT></I></TT>
</BLOCKQUOTE>
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Tip</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Netscape recommends that you do not access the pblock for headers directly but instead use the following function:</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">int request_headers(char *name, char *value, Session *sn, Request *rq)</FONT></TT>
</BLOCKQUOTE>
<BLOCKQUOTE>
Even though you can access the pblock directly, that capability may change in the future. Because Netscape doesn't want you to create code that won't work later, they have made this recommendation.</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<P>
The data contained in <TT><FONT FACE="Courier">srvhdrs</FONT></TT>
is just the reverse of the headers block: this is the place where
you can specify headers to be sent back to the client for the
request result.
<P>
The last three parts of Listing 26.4 (<TT><FONT FACE="Courier">os</FONT></TT>,
<TT><FONT FACE="Courier">statpath</FONT></TT>, and <TT><FONT FACE="Courier">finfo</FONT></TT>)
are used by the base server itself and are basically transparent
to your application. They essentially verify the status of a given
path, returning a <TT><FONT FACE="Courier">stat</FONT></TT> structure
if it's successful or an error code if it isn't.
<H3><A NAME="FunctionsVariablesandTheirResponse">Functions, Variables,
and Their Responses</A></H3>
<P>
With each of the application function classes, specific data is
evaluated, and certain response codes are valid. In the following
sections, I help you review each one of the main classes in the
order that the server handles them, and then I cover what's available
with each one for both variables and response codes. Following
that, I provide further information on some other common functions
that are available to your applications.
<H4><TT><FONT FACE="Courier">AuthTrans</FONT></TT></H4>
<P>
<TT><FONT FACE="Courier">AuthTrans</FONT></TT> decodes any authorization
type data sent by the client so that it can compare the data to
internal tables and determine the validity of the user. If the
user is verified, <TT><FONT FACE="Courier">AuthTrans</FONT></TT>
makes the following data available in a <TT><FONT FACE="Courier">vars</FONT></TT>
<TT><FONT FACE="Courier">pblock</FONT></TT>:
<UL>
<LI><TT><FONT FACE="Courier">auth-type</FONT></TT>: Defines the
authorization scheme to which it complies. Currently, the only
possible value is <TT><FONT FACE="Courier">basic</FONT></TT>.
(The CGI variable equivalent is <TT><FONT FACE="Courier">AUTH_TYPE</FONT></TT>.)
<LI><TT><FONT FACE="Courier">auth-user</FONT></TT>: Provides the
username that has been verified. (The CGI variable equivalent
is <TT><FONT FACE="Courier">AUTH_USER</FONT></TT>.)
</UL>
<P>
<TT><FONT FACE="Courier">AuthTrans</FONT></TT> returns one of
the following three response codes, with the following meanings:
<UL>
<LI><TT><FONT FACE="Courier">REQ_ABORTED</FONT></TT>: Abort the
process (error).
<LI><TT><FONT FACE="Courier">REQ_NOACTION</FONT></TT>: No authorization
took place.
<LI><TT><FONT FACE="Courier">REQ_PROCEED</FONT></TT>: Authorization
occurred; continue.
</UL>
<H4><TT><FONT FACE="Courier">NameTrans</FONT></TT></H4>
<P>
<TT><FONT FACE="Courier">NameTrans</FONT></TT> converts a virtual
path, such as <TT><FONT FACE="Courier">/stuff/docs</FONT></TT>
into the absolute directory path, such as <TT><FONT FACE="Courier">/usr/bin/netscape/docs/stuff/docs</FONT></TT>.
<P>
<TT><FONT FACE="Courier">NameTrans</FONT></TT> functions expect
to receive two variables in the <TT><FONT FACE="Courier">vars</FONT></TT>
<TT><FONT FACE="Courier">pblock</FONT></TT> on execution: <TT><FONT FACE="Courier">ppath</FONT></TT>
and <TT><FONT FACE="Courier">name</FONT></TT>. <TT><FONT FACE="Courier">ppath</FONT></TT>
is the partial path, that is, the virtual path that was supplied
such as /stuff/docs. It may have already been partially translated,
and your function can modify it, no matter what it decides to
return. The <TT><FONT FACE="Courier">name</FONT></TT> variable
specifies additional server objects (besides <TT><FONT FACE="Courier">default</FONT></TT>)
that should add their list of things to do to this process.
<P>
Return codes from a <TT><FONT FACE="Courier">NameTrans</FONT></TT>
function can be any of the following:
<UL>
<LI><TT><FONT FACE="Courier">REQ_PROCEED</FONT></TT>: Translation
was performed; no more translation should occur.
<LI><TT><FONT FACE="Courier">REQ_ABORTED</FONT></TT>: An error
should be sent to the client; no other functions should execute.
<LI><TT><FONT FACE="Courier">REQ_NOACTION</FONT></TT>: The function
doesn't admit translating <TT><FONT FACE="Courier">ppath</FONT></TT>,
though it may have changed it anyway. The rest of the functions
should be carried out.
<LI><TT><FONT FACE="Courier">REQ_EXIT</FONT></TT>: An I/O error
occurred, and the process should be aborted.
</UL>
<H4><TT><FONT FACE="Courier">PathCheck</FONT></TT></H4>
<P>
<TT><FONT FACE="Courier">PathCheck</FONT></TT> functions verify
that a given path can be safely returned to the client, based
on authorization, URL screening, and other similar checks. The
only information supplied to the <TT><FONT FACE="Courier">PathCheck</FONT></TT>
function is the <TT><FONT FACE="Courier">path</FONT></TT> variable,
which specifies the location to be checked.
<P>
For return codes, anything other than <TT><FONT FACE="Courier">REQ_ABORTED</FONT></TT>
is considered to be a success.
<H4><TT><FONT FACE="Courier">ObjectType</FONT></TT></H4>
<P>
<TT><FONT FACE="Courier">ObjectType</FONT></TT> functions are

⌨️ 快捷键说明

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