📄 api.html.en
字号:
if ((errstatus = ap_set_content_length (r, r->finfo.st_size))<br /> || (errstatus = ap_set_last_modified (r, r->finfo.st_mtime)))<br /> return errstatus;<br /> <br /> 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -