API.html revision 6d045a7504b4121f8f5680a2a2ba36019e56d7db
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<!--#include virtual="header.html" -->
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwThese are some notes on the Apache API and the data structures you
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwhave to deal with, etc. They are not yet nearly complete, but
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwhopefully, they will help you get your bearings. Keep in mind that
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwthe API is still subject to change as we gain experience with it.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw(See the TODO file for what <em>might</em> be coming). However,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwit will be easy to adapt modules to any changes that are made.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw(We have more modules to adapt than you do).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwA few notes on general pedagogical style here. In the interest of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwconciseness, all structure declarations here are incomplete --- the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwreal ones have more slots that I'm not telling you about. For the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwmost part, these are reserved to one component of the server core or
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wrightanother, and should be altered by modules with caution. However, in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsome cases, they really are things I just haven't gotten around to
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wrightyet. Welcome to the bleeding edge.<p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwFinally, here's an outline, to give you some bare idea of what's
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwcoming up, and in what order:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> <a href="#req_tour">A brief tour of the <code>request_rec</code></a>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> <a href="#req_orig">Where request_rec structures come from</a>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> <a href="#req_return">Handling requests, declining, and returning error codes</a>
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> <a href="#resp_handlers">Special considerations for response handlers</a>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as <li> <a href="#auth_handlers">Special considerations for authentication handlers</a>
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego <li> <a href="#log_handlers">Special considerations for logging handlers</a>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as<li> <a href="#pools">Resource allocation and resource pools</a>
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego<li> <a href="#config">Configuration, commands and the like</a>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as <li> <a href="#per-dir">Per-directory configuration structures</a>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross <li> <a href="#servconf">Side notes --- per-server configuration, virtual servers, etc.</a>
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregoWe begin with an overview of the basic concepts behind the
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregoAPI, and how they are manifested in the code.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego<h3><a name="HMR">Handlers, Modules, and Requests</a></h3>
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregoApache breaks down request handling into a series of steps, more or
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregoless the same way the Netscape server API does (although this API has
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregoa few more stages than NetSite does, as hooks for stuff I thought
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asmight be useful in the future). These are:
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as <li> URI -> Filename translation
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as <li> Auth ID checking [is the user who they say they are?]
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as <li> Auth access checking [is the user authorized <em>here</em>?]
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> Access checking other than auth
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> Determining MIME type of the object requested
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> `Fixups' --- there aren't any of these yet, but the phase is
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego intended as a hook for possible extensions like
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <code>SetEnv</code>, which don't really fit well elsewhere.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> Actually sending a response back to the client.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as <li> Logging the request
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asThese phases are handled by looking at each of a succession of
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego<em>modules</em>, looking to see if each of them has a handler for the
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregophase, and attempting invoking it if so. The handler can typically do
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregoone of three things:
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> <em>Handle</em> the request, and indicate that it has done so
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego by returning the magic constant <code>OK</code>.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> <em>Decline</em> to handle the request, by returning the magic
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego integer constant <code>DECLINED</code>. In this case, the
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego server behaves in all respects as if the handler simply hadn't
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> Signal an error, by returning one of the HTTP error codes.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego This terminates normal handling of the request, although an
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego ErrorDocument may be invoked to try to mop up, and it will be
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego logged in any case.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregoMost phases are terminated by the first module that handles them;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5ashowever, for logging, `fixups', and non-access authentication
dc20a3024900c47dd2ee44b9707e6df38f7d62a5aschecking, all handlers always run (barring an error). Also, the
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asresponse phase is unique in that modules may declare multiple handlers
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asfor it, via a dispatch table keyed on the MIME type of the requested
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asobject. Modules may declare a response-phase handler which can handle
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego<em>any</em> request, by giving it the key <code>*/*</code> (i.e., a
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregowildcard MIME type specification). However, wildcard handlers are
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoonly invoked if the server has already tried and failed to find a more
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregospecific response handler for the MIME type of the requested object
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as(either none existed, or they all declined).<p>
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregoThe handlers themselves are functions of one argument (a
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego<code>request_rec</code> structure. vide infra), which returns an
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asinteger, as above.<p>
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego<h3><a name="moduletour">A brief tour of a module</a></h3>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asAt this point, we need to explain the structure of a module. Our
dc20a3024900c47dd2ee44b9707e6df38f7d62a5ascandidate will be one of the messier ones, the CGI module --- this
7f667e74610492ddbce8ce60f52ece95d2401949jose borregohandles both CGI scripts and the <code>ScriptAlias</code> config file
dc20a3024900c47dd2ee44b9707e6df38f7d62a5ascommand. It's actually a great deal more complicated than most
7f667e74610492ddbce8ce60f52ece95d2401949jose borregomodules, but if we're going to have only one example, it might as well
7f667e74610492ddbce8ce60f52ece95d2401949jose borregobe the one with its fingers in every place.<p>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asLet's begin with handlers. In order to handle the CGI scripts, the
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asmodule declares a response handler for them. Because of
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego<code>ScriptAlias</code>, it also has handlers for the name
7f667e74610492ddbce8ce60f52ece95d2401949jose borregotranslation phase (to recognize <code>ScriptAlias</code>ed URIs), the
7f667e74610492ddbce8ce60f52ece95d2401949jose borregotype-checking phase (any <code>ScriptAlias</code>ed request is typed
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoas a CGI script).<p>
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoThe module needs to maintain some per (virtual)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asserver information, namely, the <code>ScriptAlias</code>es in effect;
7f667e74610492ddbce8ce60f52ece95d2401949jose borregothe module structure therefore contains pointers to a functions which
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asbuilds these structures, and to another which combines two of them (in
dc20a3024900c47dd2ee44b9707e6df38f7d62a5ascase the main server and a virtual server both have
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan WrightFinally, this module contains code to handle the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code>ScriptAlias</code> command itself. This particular module only
8d7e41661dc4633488e93b13363137523ce59977jose borregodeclares one command, but there could be more, so modules have
8d7e41661dc4633488e93b13363137523ce59977jose borrego<em>command tables</em> which declare their commands, and describe
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosswhere they are permitted, and how they are to be invoked. <p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwA final note on the declared types of the arguments of some of these
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightcommands: a <code>pool</code> is a pointer to a <em>resource pool</em>
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightstructure; these are used by the server to keep track of the memory
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwwhich has been allocated, files opened, etc., either to service a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwparticular request, or to handle the process of configuring itself.
a0aa776e20803c84edd153d9cb584fd67163aef3Alan WrightThat way, when the request is over (or, for the configuration pool,
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosswhen the server is restarting), the memory can be freed, and the files
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightclosed, <i>en masse</i>, without anyone having to write explicit code to
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrighttrack them all down and dispose of them. Also, a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code>cmd_parms</code> structure contains various information about
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossthe config file being read, and other status information, which is
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosssometimes of use to the function which processes a config-file command
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwWith no further ado, the module itself:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/* Declarations of handlers. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint translate_scriptalias (request_rec *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint type_scriptalias (request_rec *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint cgi_handler (request_rec *);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/* Subsidiary dispatch table for response-phase handlers, by MIME type */
8d7e41661dc4633488e93b13363137523ce59977jose borregohandler_rec cgi_handlers[] = {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright/* Declarations of routines to manipulate the module's configuration
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright * info. Note that these are returned, and passed in, as void *'s;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the server core keeps track of them, but it doesn't, and can't,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * know their internal structure.
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightvoid *make_cgi_server_config (pool *);
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightvoid *merge_cgi_server_config (pool *, void *, void *);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross/* Declarations of routines to handle config-file commands */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossextern char *script_alias(cmd_parms *, void *per_dir_config, char *fake,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *real);
8d7e41661dc4633488e93b13363137523ce59977jose borregocommand_rec cgi_cmds[] = {
8d7e41661dc4633488e93b13363137523ce59977jose borrego{ "ScriptAlias", script_alias, NULL, RSRC_CONF, TAKE2,
8d7e41661dc4633488e93b13363137523ce59977jose borrego "a fakename and a realname"},
8d7e41661dc4633488e93b13363137523ce59977jose borregomodule cgi_module = {
8d7e41661dc4633488e93b13363137523ce59977jose borrego STANDARD_MODULE_STUFF,
8d7e41661dc4633488e93b13363137523ce59977jose borrego NULL, /* initializer */
8d7e41661dc4633488e93b13363137523ce59977jose borrego NULL, /* dir config creator */
8d7e41661dc4633488e93b13363137523ce59977jose borrego NULL, /* dir merger --- default is to override */
8d7e41661dc4633488e93b13363137523ce59977jose borrego make_cgi_server_config, /* server config */
8d7e41661dc4633488e93b13363137523ce59977jose borrego merge_cgi_server_config, /* merge server config */
8d7e41661dc4633488e93b13363137523ce59977jose borrego cgi_cmds, /* command table */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross cgi_handlers, /* handlers */
8d7e41661dc4633488e93b13363137523ce59977jose borrego translate_scriptalias, /* filename translation */
8d7e41661dc4633488e93b13363137523ce59977jose borrego NULL, /* check_user_id */
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright NULL, /* check auth */
8d7e41661dc4633488e93b13363137523ce59977jose borrego NULL, /* check access */
8d7e41661dc4633488e93b13363137523ce59977jose borrego type_scriptalias, /* type_checker */
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright NULL, /* fixups */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross NULL, /* logger */
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright NULL /* header parser */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<h2><a name="handlers">How handlers work</a></h2>
8d7e41661dc4633488e93b13363137523ce59977jose borregoThe sole argument to handlers is a <code>request_rec</code> structure.
8d7e41661dc4633488e93b13363137523ce59977jose borregoThis structure describes a particular request which has been made to
8d7e41661dc4633488e93b13363137523ce59977jose borregothe server, on behalf of a client. In most cases, each connection to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwthe client generates only one <code>request_rec</code> structure.<p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<h3><a name="req_tour">A brief tour of the <code>request_rec</code></a></h3>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwThe <code>request_rec</code> contains pointers to a resource pool
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwwhich will be cleared when the server is finished handling the
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightrequest; to structures containing per-server and per-connection
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightinformation, and most importantly, information on the request itself.<p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwThe most important such information is a small set of character
8d7e41661dc4633488e93b13363137523ce59977jose borregostrings describing attributes of the object being requested, including
8d7e41661dc4633488e93b13363137523ce59977jose borregoits URI, filename, content-type and content-encoding (these being filled
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossin by the translation and type-check handlers which handle the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwrequest, respectively). <p>
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan WrightOther commonly used data items are tables giving the MIME headers on
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightthe client's original request, MIME headers to be sent back with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwresponse (which modules can add to at will), and environment variables
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwfor any subprocesses which are spawned off in the course of servicing
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossthe request. These tables are manipulated using the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code>table_get</code> and <code>table_set</code> routines. <p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<BLOCKQUOTE>
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright Note that the <SAMP>Content-type</SAMP> header value <EM>cannot</EM> be
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright set by module content-handlers using the <SAMP>table_*()</SAMP>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw routines. Rather, it is set by pointing the <SAMP>content_type</SAMP>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross field in the <SAMP>request_rec</SAMP> structure to an appropriate
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</BLOCKQUOTE>
8d7e41661dc4633488e93b13363137523ce59977jose borregoFinally, there are pointers to two data structures which, in turn,
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wrightpoint to per-module configuration structures. Specifically, these
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwhold pointers to the data structures which the module has built to
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wrightdescribe the way it has been configured to operate in a given
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code><Directory></code> sections), for private data it has
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwbuilt in the course of servicing the request (so modules' handlers for
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwone phase can pass `notes' to their handlers for other phases). There
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwis another such configuration vector in the <code>server_rec</code>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwdata structure pointed to by the <code>request_rec</code>, which
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwcontains per (virtual) server configuration data.<p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwHere is an abridged declaration, giving the fields most commonly used:<p>
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstruct request_rec {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright conn_rec *connection;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright server_rec *server;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* What object is being requested */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright char *filename;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright char *path_info;
8d7e41661dc4633488e93b13363137523ce59977jose borrego char *args; /* QUERY_ARGS, if any */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright struct stat finfo; /* Set by server core;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * st_mode set to zero if no such file */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright char *content_type;
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright char *content_encoding;
8d7e41661dc4633488e93b13363137523ce59977jose borrego /* MIME header environments, in and out. Also, an array containing
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * environment variables to be passed to subprocesses, so people can
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * write modules to add to that environment.
8d7e41661dc4633488e93b13363137523ce59977jose borrego * The difference between headers_out and err_headers_out is that
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * the latter are printed even on error, and persist across internal
8d7e41661dc4633488e93b13363137523ce59977jose borrego * redirects (so the headers printed for ErrorDocument handlers will
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright * have them).
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright table *headers_in;
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright table *headers_out;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright table *err_headers_out;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright table *subprocess_env;
8d7e41661dc4633488e93b13363137523ce59977jose borrego /* Info about the request itself... */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright int header_only; /* HEAD request, as opposed to GET */
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright char *protocol; /* Protocol, as given to us, or HTTP/0.9 */
8d7e41661dc4633488e93b13363137523ce59977jose borrego char *method; /* GET, HEAD, POST, etc. */
8d7e41661dc4633488e93b13363137523ce59977jose borrego int method_number; /* M_GET, M_POST, etc. */
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego /* Info for logging */
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego char *the_request;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego int bytes_sent;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego /* A flag which modules can set, to indicate that the data being
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * returned is volatile, and clients should be told not to cache it.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int no_cache;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego /* Various other config info which may change with .htaccess files
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * These are config vectors, with one void* pointer for each module
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * (the thing pointed to being the module's business).
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego void *per_dir_config; /* Options set in config files, etc. */
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego void *request_config; /* Notes on *this* request */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<h3><a name="req_orig">Where request_rec structures come from</a></h3>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asMost <code>request_rec</code> structures are built by reading an HTTP
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwrequest from a client, and filling in the fields. However, there are
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoa few exceptions:
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego <li> If the request is to an imagemap, a type map (i.e., a
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego <code>*.var</code> file), or a CGI script which returned a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw local `Location:', then the resource which the user requested
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego is going to be ultimately located by some URI other than what
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego the client originally supplied. In this case, the server does
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego an <em>internal redirect</em>, constructing a new
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as <code>request_rec</code> for the new URI, and processing it
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw almost exactly as if the client had requested the new URI
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as directly. <p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> If some handler signaled an error, and an
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <code>ErrorDocument</code> is in scope, the same internal
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross redirect machinery comes into play.<p>
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego <li> Finally, a handler occasionally needs to investigate `what
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego would happen if' some other request were run. For instance,
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego the directory indexing module needs to know what MIME type
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross would be assigned to a request for each directory entry, in
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross order to figure out what icon to use.<p>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as Such handlers can construct a <em>sub-request</em>, using the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <code>request_rec</code> structure and processes it as you
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright would expect, up to but not including the point of actually
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright sending a response. (These functions skip over the access
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross checks if the sub-request is for a file in the same directory
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright as the original request).<p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (Server-side includes work by building sub-requests and then
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego actually invoking the response handler for them, via the
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<h3><a name="req_return">Handling requests, declining, and returning error codes</a></h3>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossAs discussed above, each handler, when invoked to handle a particular
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code>request_rec</code>, has to return an <code>int</code> to
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krierindicate what happened. That can either be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> OK --- the request was handled successfully. This may or may
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw not terminate the phase.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> DECLINED --- no erroneous condition exists, but the module
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw declines to handle the phase; the server tries to find another.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> an HTTP error code, which aborts handling of the request.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwNote that if the error code returned is <code>REDIRECT</code>, then
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwthe module should put a <code>Location</code> in the request's
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code>headers_out</code>, to indicate where the client should be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<h3><a name="resp_handlers">Special considerations for response handlers</a></h3>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossHandlers for most phases do their work by simply setting a few fields
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwin the <code>request_rec</code> structure (or, in the case of access
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwcheckers, simply by returning the correct error code). However,
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossresponse handlers have to actually send a request back to the client. <p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwThey should begin by sending an HTTP response header, using the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwfunction <code>send_http_header</code>. (You don't have to do
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightanything special to skip sending the header for HTTP/0.9 requests; the
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightfunction figures out on its own that it shouldn't do anything). If
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossthe request is marked <code>header_only</code>, that's all they should
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightdo; they should return after that, without attempting any further
8d7e41661dc4633488e93b13363137523ce59977jose borregoOtherwise, they should produce a request body which responds to the
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossclient as appropriate. The primitives for this are <code>rputc</code>
8d7e41661dc4633488e93b13363137523ce59977jose borregoand <code>rprintf</code>, for internally generated output, and
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<code>send_fd</code>, to copy the contents of some <code>FILE *</code>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossstraight to the client. <p>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossAt this point, you should more or less understand the following piece
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwof code, which is the handler which handles <code>GET</code> requests
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosswhich have no more specific handler; it also shows how conditional
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code>GET</code>s can be handled, if it's desirable to do so in a
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossparticular response handler --- <code>set_last_modified</code> checks
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwagainst the <code>If-modified-since</code> value supplied by the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwclient, if any, and returns an appropriate code (which will, if
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnonzero, be USE_LOCAL_COPY). No similar considerations apply for
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code>set_content_length</code>, but it returns an error code for
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsymmetry.<p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint default_handler (request_rec *r)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int errstatus;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (r->method_number != M_GET) return DECLINED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (r->finfo.st_mode == 0) return NOT_FOUND;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((errstatus = set_content_length (r, r->finfo.st_size))
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross || (errstatus = set_last_modified (r, r->finfo.st_mtime)))
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return errstatus;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw f = fopen (r->filename, "r");
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright if (f == NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw log_reason("file permissions deny server access",
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross r->filename, r);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return FORBIDDEN;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw register_timeout ("send", r);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw send_http_header (r);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!r->header_only) send_fd (f, r);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pfclose (r->pool, f);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return OK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwFinally, if all of this is too much of a challenge, there are a few
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwways out of it. First off, as shown above, a response handler which
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwhas not yet produced any output can simply return an error code, in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwwhich case the server will automatically produce an error response.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwSecondly, it can punt to some other handler by invoking
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<code>internal_redirect</code>, which is how the internal redirection
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwmachinery discussed above is invoked. A response handler which has
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwinternally redirected should always return <code>OK</code>. <p>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw(Invoking <code>internal_redirect</code> from handlers which are
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<em>not</em> response handlers will lead to serious confusion).
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<h3><a name="auth_handlers">Special considerations for authentication handlers</a></h3>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossStuff that should be discussed here in detail:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> Authentication-phase handlers not invoked unless auth is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw configured for the directory.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li> Common auth configuration stored in the core per-dir
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego configuration; it has accessors <code>auth_type</code>,
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross <li> Common routines, to handle the protocol end of things, at least
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for HTTP basic authentication (<code>get_basic_auth_pw</code>,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw which sets the <code>connection->user</code> structure field
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw automatically, and <code>note_basic_auth_failure</code>, which
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arranges for the proper <code>WWW-Authenticate:</code> header
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw to be sent back).
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<h3><a name="log_handlers">Special considerations for logging handlers</a></h3>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwWhen a request has internally redirected, there is the question of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwwhat to log. Apache handles this by bundling the entire chain of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwredirects into a list of <code>request_rec</code> structures which are
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwthreaded through the <code>r->prev</code> and <code>r->next</code>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwpointers. The <code>request_rec</code> which is passed to the logging
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwhandlers in such cases is the one which was originally built for the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwinitial request from the client; note that the bytes_sent field will
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoonly be correct in the last request in the chain (the one for which a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwresponse was actually sent).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<h2><a name="pools">Resource allocation and resource pools</a></h2>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwOne of the problems of writing and designing a server-pool server is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwthat of preventing leakage, that is, allocating resources (memory,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwopen files, etc.), without subsequently releasing them. The resource
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwpool machinery is designed to make it easy to prevent this from
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosshappening, by allowing resource to be allocated in such a way that
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwthey are <em>automatically</em> released when the server is done with
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asThe way this works is as follows: the memory which is allocated, file
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asopened, etc., to deal with a particular request are tied to a
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego<em>resource pool</em> which is allocated for the request. The pool
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asis a data structure which itself tracks the resources in question. <p>
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoWhen the request has been processed, the pool is <em>cleared</em>. At
7f667e74610492ddbce8ce60f52ece95d2401949jose borregothat point, all the memory associated with it is released for reuse,
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoall files associated with it are closed, and any other clean-up
7f667e74610492ddbce8ce60f52ece95d2401949jose borregofunctions which are associated with the pool are run. When this is
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoover, we can be confident that all the resource tied to the pool have
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asbeen released, and that none of them have leaked. <p>
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoServer restarts, and allocation of memory and resources for per-server
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asconfiguration, are handled in a similar way. There is a
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego<em>configuration pool</em>, which keeps track of resources which were
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoallocated while reading the server configuration files, and handling
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asthe commands therein (for instance, the memory that was allocated for
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoper-server module configuration, log files and other files that were
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asopened, and so forth). When the server restarts, and has to reread
7f667e74610492ddbce8ce60f52ece95d2401949jose borregothe configuration files, the configuration pool is cleared, and so the
7f667e74610492ddbce8ce60f52ece95d2401949jose borregomemory and file descriptors which were taken up by reading them the
dc20a3024900c47dd2ee44b9707e6df38f7d62a5aslast time are made available for reuse. <p>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asIt should be noted that use of the pool machinery isn't generally
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asobligatory, except for situations like logging handlers, where you
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoreally need to register cleanups to make sure that the log file gets
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoclosed when the server restarts (this is most easily done by using the
7f667e74610492ddbce8ce60f52ece95d2401949jose borregofunction <code><a href="#pool-files">pfopen</a></code>, which also
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoarranges for the underlying file descriptor to be closed before any
7f667e74610492ddbce8ce60f52ece95d2401949jose borregochild processes, such as for CGI scripts, are <code>exec</code>ed), or
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asin case you are using the timeout machinery (which isn't yet even
7f667e74610492ddbce8ce60f52ece95d2401949jose borregodocumented here). However, there are two benefits to using it:
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoresources allocated to a pool never leak (even if you allocate a
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asscratch string, and just forget about it); also, for memory
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoallocation, <code>palloc</code> is generally faster than
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asWe begin here by describing how memory is allocated to pools, and then
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asdiscuss how other resources are tracked by the resource pool
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossMemory is allocated to pools by calling the function
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<code>palloc</code>, which takes two arguments, one being a pointer to
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossa resource pool structure, and the other being the amount of memory to
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossallocate (in <code>char</code>s). Within handlers for handling
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossrequests, the most common way of getting a resource pool structure is
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego<code>request_rec</code>; hence the repeated appearance of the
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asfollowing idiom in module code:
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightint my_handler(request_rec *r)
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright struct my_structure *foo;
8d7e41661dc4633488e93b13363137523ce59977jose borrego foo = (foo *)palloc (r->pool, sizeof(my_structure));
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossNote that <em>there is no <code>pfree</code></em> ---
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<code>palloc</code>ed memory is freed only when the associated
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossresource pool is cleared. This means that <code>palloc</code> does not
dc20a3024900c47dd2ee44b9707e6df38f7d62a5ashave to do as much accounting as <code>malloc()</code>; all it does in
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krierthe typical case is to round up the size, bump a pointer, and do a
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asrange check.<p>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as(It also raises the possibility that heavy use of <code>palloc</code>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5ascould cause a server process to grow excessively large. There are
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosstwo ways to deal with this, which are dealt with below; briefly, you
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosscan use <code>malloc</code>, and try to be sure that all of the memory
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossgets explicitly <code>free</code>d, or you can allocate a sub-pool of
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossthe main pool, allocate your memory in the sub-pool, and clear it out
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossperiodically. The latter technique is discussed in the section on
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosssub-pools below, and is used in the directory-indexing code, in order
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossto avoid excessive storage allocation when listing directories with
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossthousands of files).
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossThere are functions which allocate initialized memory, and are
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossfrequently useful. The function <code>pcalloc</code> has the same
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossinterface as <code>palloc</code>, but clears out the memory it
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossallocates before it returns it. The function <code>pstrdup</code>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rosstakes a resource pool and a <code>char *</code> as arguments, and
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossallocates memory for a copy of the string the pointer points to,
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossreturning a pointer to the copy. Finally <code>pstrcat</code> is a
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossvarargs-style function, which takes a pointer to a resource pool, and
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossat least two <code>char *</code> arguments, the last of which must be
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<code>NULL</code>. It allocates enough memory to fit copies of each
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossof the strings, as a unit; for instance:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross pstrcat (r->pool, "foo", "/", "bar", NULL);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Rossreturns a pointer to 8 bytes worth of memory, initialized to
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross<h3><a name="pool-files">Tracking open files, etc.</a></h3>
the parent's. For some modules, that works just fine (e.g., for the
"an encoding (e.g., gzip), followed by a file extension" },
if (S_ISDIR(r->finfo.st_mode)) {
<!--#include virtual="footer.html" -->