📄 api.html
字号:
f = fopen (r->filename, "r");<br />
<br />
if (f == NULL) {<br />
<span class="indent">
log_reason("file permissions deny server access", r->filename, r);<br />
return FORBIDDEN;<br />
</span>
}<br />
<br />
register_timeout ("send", r);<br />
ap_send_http_header (r);<br />
<br />
if (!r->header_only) send_fd (f, r);<br />
ap_pfclose (r->pool, f);<br />
return OK;<br />
</span>
}
</code></p></div>
<p>Finally, if all of this is too much of a challenge, there are a few
ways out of it. First off, as shown above, a response handler which has
not yet produced any output can simply return an error code, in which
case the server will automatically produce an error response. Secondly,
it can punt to some other handler by invoking
<code>ap_internal_redirect</code>, which is how the internal redirection
machinery discussed above is invoked. A response handler which has
internally redirected should always return <code>OK</code>.</p>
<p>(Invoking <code>ap_internal_redirect</code> from handlers which are
<em>not</em> response handlers will lead to serious confusion).</p>
<h3><a name="auth_handlers" id="auth_handlers">Special considerations for authentication
handlers</a></h3>
<p>Stuff that should be discussed here in detail:</p>
<ul>
<li>Authentication-phase handlers not invoked unless auth is
configured for the directory.</li>
<li>Common auth configuration stored in the core per-dir
configuration; it has accessors <code>ap_auth_type</code>,
<code>ap_auth_name</code>, and <code>ap_requires</code>.</li>
<li>Common routines, to handle the protocol end of things, at
least for HTTP basic authentication
(<code>ap_get_basic_auth_pw</code>, which sets the
<code>connection->user</code> structure field
automatically, and <code>ap_note_basic_auth_failure</code>,
which arranges for the proper <code>WWW-Authenticate:</code>
header to be sent back).</li>
</ul>
<h3><a name="log_handlers" id="log_handlers">Special considerations for logging
handlers</a></h3>
<p>When a request has internally redirected, there is the question of
what to log. Apache handles this by bundling the entire chain of redirects
into a list of <code>request_rec</code> structures which are threaded
through the <code>r->prev</code> and <code>r->next</code> pointers.
The <code>request_rec</code> which is passed to the logging handlers in
such cases is the one which was originally built for the initial request
from the client; note that the <code>bytes_sent</code> field will only be
correct in the last request in the chain (the one for which a response was
actually sent).</p>
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="pools" id="pools">Resource allocation and resource pools</a></h2>
<p>One of the problems of writing and designing a server-pool server is
that of preventing leakage, that is, allocating resources (memory, open
files, <em>etc.</em>), without subsequently releasing them. The resource
pool machinery is designed to make it easy to prevent this from happening,
by allowing resource to be allocated in such a way that they are
<em>automatically</em> released when the server is done with them.</p>
<p>The way this works is as follows: the memory which is allocated, file
opened, <em>etc.</em>, to deal with a particular request are tied to a
<em>resource pool</em> which is allocated for the request. The pool is a
data structure which itself tracks the resources in question.</p>
<p>When the request has been processed, the pool is <em>cleared</em>. At
that point, all the memory associated with it is released for reuse, all
files associated with it are closed, and any other clean-up functions which
are associated with the pool are run. When this is over, we can be confident
that all the resource tied to the pool have been released, and that none of
them have leaked.</p>
<p>Server restarts, and allocation of memory and resources for per-server
configuration, are handled in a similar way. There is a <em>configuration
pool</em>, which keeps track of resources which were allocated while reading
the server configuration files, and handling the commands therein (for
instance, the memory that was allocated for per-server module configuration,
log files and other files that were opened, and so forth). When the server
restarts, and has to reread the configuration files, the configuration pool
is cleared, and so the memory and file descriptors which were taken up by
reading them the last time are made available for reuse.</p>
<p>It should be noted that use of the pool machinery isn't generally
obligatory, except for situations like logging handlers, where you really
need to register cleanups to make sure that the log file gets closed when
the server restarts (this is most easily done by using the function <code><a href="#pool-files">ap_pfopen</a></code>, which also arranges for the
underlying file descriptor to be closed before any child processes, such as
for CGI scripts, are <code>exec</code>ed), or in case you are using the
timeout machinery (which isn't yet even documented here). However, there are
two benefits to using it: resources allocated to a pool never leak (even if
you allocate a scratch string, and just forget about it); also, for memory
allocation, <code>ap_palloc</code> is generally faster than
<code>malloc</code>.</p>
<p>We begin here by describing how memory is allocated to pools, and then
discuss how other resources are tracked by the resource pool machinery.</p>
<h3>Allocation of memory in pools</h3>
<p>Memory is allocated to pools by calling the function
<code>ap_palloc</code>, which takes two arguments, one being a pointer to
a resource pool structure, and the other being the amount of memory to
allocate (in <code>char</code>s). Within handlers for handling requests,
the most common way of getting a resource pool structure is by looking at
the <code>pool</code> slot of the relevant <code>request_rec</code>; hence
the repeated appearance of the following idiom in module code:</p>
<div class="example"><p><code>
int my_handler(request_rec *r)<br />
{<br />
<span class="indent">
struct my_structure *foo;<br />
...<br />
<br />
foo = (foo *)ap_palloc (r->pool, sizeof(my_structure));<br />
</span>
}
</code></p></div>
<p>Note that <em>there is no <code>ap_pfree</code></em> --
<code>ap_palloc</code>ed memory is freed only when the associated resource
pool is cleared. This means that <code>ap_palloc</code> does not have to
do as much accounting as <code>malloc()</code>; all it does in the typical
case is to round up the size, bump a pointer, and do a range check.</p>
<p>(It also raises the possibility that heavy use of
<code>ap_palloc</code> could cause a server process to grow excessively
large. There are two ways to deal with this, which are dealt with below;
briefly, you can use <code>malloc</code>, and try to be sure that all of
the memory gets explicitly <code>free</code>d, or you can allocate a
sub-pool of the main pool, allocate your memory in the sub-pool, and clear
it out periodically. The latter technique is discussed in the section
on sub-pools below, and is used in the directory-indexing code, in order
to avoid excessive storage allocation when listing directories with
thousands of files).</p>
<h3>Allocating initialized memory</h3>
<p>There are functions which allocate initialized memory, and are
frequently useful. The function <code>ap_pcalloc</code> has the same
interface as <code>ap_palloc</code>, but clears out the memory it
allocates before it returns it. The function <code>ap_pstrdup</code>
takes a resource pool and a <code>char *</code> as arguments, and
allocates memory for a copy of the string the pointer points to, returning
a pointer to the copy. Finally <code>ap_pstrcat</code> is a varargs-style
function, which takes a pointer to a resource pool, and at least two
<code>char *</code> arguments, the last of which must be
<code>NULL</code>. It allocates enough memory to fit copies of each of
the strings, as a unit; for instance:</p>
<div class="example"><p><code>
ap_pstrcat (r->pool, "foo", "/", "bar", NULL);
</code></p></div>
<p>returns a pointer to 8 bytes worth of memory, initialized to
<code>"foo/bar"</code>.</p>
<h3><a name="pools-used" id="pools-used">Commonly-used pools in the Apache Web
server</a></h3>
<p>A pool is really defined by its lifetime more than anything else.
There are some static pools in http_main which are passed to various
non-http_main functions as arguments at opportune times. Here they
are:</p>
<dl>
<dt><code>permanent_pool</code></dt>
<dd>never passed to anything else, this is the ancestor of all pools</dd>
<dt><code>pconf</code></dt>
<dd>
<ul>
<li>subpool of permanent_pool</li>
<li>created at the beginning of a config "cycle"; exists
until the server is terminated or restarts; passed to all
config-time routines, either via cmd->pool, or as the
"pool *p" argument on those which don't take pools</li>
<li>passed to the module init() functions</li>
</ul>
</dd>
<dt><code>ptemp</code></dt>
<dd>
<ul>
<li>sorry I lie, this pool isn't called this currently in
1.3, I renamed it this in my pthreads development. I'm
referring to the use of ptrans in the parent... contrast
this with the later definition of ptrans in the
child.</li>
<li>subpool of permanent_pool</li>
<li>created at the beginning of a config "cycle"; exists
until the end of config parsing; passed to config-time
routines <em>via</em> cmd->temp_pool. Somewhat of a
"bastard child" because it isn't available everywhere.
Used for temporary scratch space which may be needed by
some config routines but which is deleted at the end of
config.</li>
</ul>
</dd>
<dt><code>pchild</code></dt>
<dd>
<ul>
<li>subpool of permanent_pool</li>
<li>created when a child is spawned (or a thread is
created); lives until that child (thread) is
destroyed</li>
<li>passed to the module child_init functions</li>
<li>destruction happens right after the child_exit
functions are called... (which may explain why I think
child_exit is redundant and unneeded)</li>
</ul>
</dd>
<dt><code>ptrans</code></dt>
<dd>
<ul>
<li>should be a subpool of pchild, but currently is a
subpool of permanent_pool, see above</li>
<li>cleared by the child before going into the accept()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -