📄 api.html.en
字号:
module cgi_module = {</code></p><pre> STANDARD_MODULE_STUFF, NULL, /* initializer */ NULL, /* dir config creator */ NULL, /* dir merger */ make_cgi_server_config, /* server config */ merge_cgi_server_config, /* merge server config */ cgi_cmds, /* command table */ cgi_handlers, /* handlers */ translate_scriptalias, /* filename translation */ NULL, /* check_user_id */ NULL, /* check auth */ NULL, /* check access */ type_scriptalias, /* type_checker */ NULL, /* fixups */ NULL, /* logger */ NULL /* header parser */};</pre></div> </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div><div class="section"><h2><a name="handlers" id="handlers">How handlers work</a></h2> <p>The sole argument to handlers is a <code>request_rec</code> structure. This structure describes a particular request which has been made to the server, on behalf of a client. In most cases, each connection to the client generates only one <code>request_rec</code> structure.</p> <h3><a name="req_tour" id="req_tour">A brief tour of the request_rec</a></h3> <p>The <code>request_rec</code> contains pointers to a resource pool which will be cleared when the server is finished handling the request; to structures containing per-server and per-connection information, and most importantly, information on the request itself.</p> <p>The most important such information is a small set of character strings describing attributes of the object being requested, including its URI, filename, content-type and content-encoding (these being filled in by the translation and type-check handlers which handle the request, respectively).</p> <p>Other commonly used data items are tables giving the MIME headers on the client's original request, MIME headers to be sent back with the response (which modules can add to at will), and environment variables for any subprocesses which are spawned off in the course of servicing the request. These tables are manipulated using the <code>ap_table_get</code> and <code>ap_table_set</code> routines.</p> <div class="note"> <p>Note that the <code>Content-type</code> header value <em>cannot</em> be set by module content-handlers using the <code>ap_table_*()</code> routines. Rather, it is set by pointing the <code>content_type</code> field in the <code>request_rec</code> structure to an appropriate string. <em>e.g.</em>,</p> <div class="example"><p><code> r->content_type = "text/html"; </code></p></div> </div> <p>Finally, there are pointers to two data structures which, in turn, point to per-module configuration structures. Specifically, these hold pointers to the data structures which the module has built to describe the way it has been configured to operate in a given directory (via <code>.htaccess</code> files or <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> sections), for private data it has built in the course of servicing the request (so modules' handlers for one phase can pass `notes' to their handlers for other phases). There is another such configuration vector in the <code>server_rec</code> data structure pointed to by the <code>request_rec</code>, which contains per (virtual) server configuration data.</p> <p>Here is an abridged declaration, giving the fields most commonly used:</p> <div class="example"><p><code> struct request_rec {<br /> <br /> pool *pool;<br /> conn_rec *connection;<br /> server_rec *server;<br /> <br /> /* What object is being requested */<br /> <br /> char *uri;<br /> char *filename;<br /> char *path_info;</code></p><pre>char *args; /* QUERY_ARGS, if any */struct stat finfo; /* Set by server core; * st_mode set to zero if no such file */</pre><p><code> char *content_type;<br /> char *content_encoding;<br /> <br /> /* MIME header environments, in and out. Also, <br /> * an array containing environment variables to<br /> * be passed to subprocesses, so people can write<br /> * modules to add to that environment.<br /> *<br /> * The difference between headers_out and <br /> * err_headers_out is that the latter are printed <br /> * even on error, and persist across internal<br /> * redirects (so the headers printed for <br /> * <code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code> handlers will have them).<br /> */<br /> <br /> table *headers_in;<br /> table *headers_out;<br /> table *err_headers_out;<br /> table *subprocess_env;<br /> <br /> /* Info about the request itself... */<br /> <br /></code></p><pre>int header_only; /* HEAD request, as opposed to GET */char *protocol; /* Protocol, as given to us, or HTTP/0.9 */char *method; /* GET, HEAD, POST, <em>etc.</em> */int method_number; /* M_GET, M_POST, <em>etc.</em> */</pre><p><code> /* Info for logging */<br /> <br /> char *the_request;<br /> int bytes_sent;<br /> <br /> /* A flag which modules can set, to indicate that<br /> * the data being returned is volatile, and clients<br /> * should be told not to cache it.<br /> */<br /> <br /> int no_cache;<br /> <br /> /* Various other config info which may change<br /> * with .htaccess files<br /> * These are config vectors, with one void*<br /> * pointer for each module (the thing pointed<br /> * to being the module's business).<br /> */<br /> <br /></code></p><pre>void *per_dir_config; /* Options set in config files, <em>etc.</em> */void *request_config; /* Notes on *this* request */</pre><p><code> }; </code></p></div> <h3><a name="req_orig" id="req_orig">Where request_rec structures come from</a></h3> <p>Most <code>request_rec</code> structures are built by reading an HTTP request from a client, and filling in the fields. However, there are a few exceptions:</p> <ul> <li>If the request is to an imagemap, a type map (<em>i.e.</em>, a <code>*.var</code> file), or a CGI script which returned a local `Location:', then the resource which the user requested is going to be ultimately located by some URI other than what the client originally supplied. In this case, the server does an <em>internal redirect</em>, constructing a new <code>request_rec</code> for the new URI, and processing it almost exactly as if the client had requested the new URI directly.</li> <li>If some handler signaled an error, and an <code>ErrorDocument</code> is in scope, the same internal redirect machinery comes into play.</li> <li><p>Finally, a handler occasionally needs to investigate `what would happen if' some other request were run. For instance, the directory indexing module needs to know what MIME type would be assigned to a request for each directory entry, in order to figure out what icon to use.</p> <p>Such handlers can construct a <em>sub-request</em>, using the functions <code>ap_sub_req_lookup_file</code>, <code>ap_sub_req_lookup_uri</code>, and <code>ap_sub_req_method_uri</code>; these construct a new <code>request_rec</code> structure and processes it as you would expect, up to but not including the point of actually sending a response. (These functions skip over the access checks if the sub-request is for a file in the same directory as the original request).</p> <p>(Server-side includes work by building sub-requests and then actually invoking the response handler for them, via the function <code>ap_run_sub_req</code>).</p> </li> </ul> <h3><a name="req_return" id="req_return">Handling requests, declining, and returning error codes</a></h3> <p>As discussed above, each handler, when invoked to handle a particular <code>request_rec</code>, has to return an <code>int</code> to indicate what happened. That can either be</p> <ul> <li><code>OK</code> -- the request was handled successfully. This may or may not terminate the phase.</li> <li><code>DECLINED</code> -- no erroneous condition exists, but the module declines to handle the phase; the server tries to find another.</li> <li>an HTTP error code, which aborts handling of the request.</li> </ul> <p>Note that if the error code returned is <code>REDIRECT</code>, then the module should put a <code>Location</code> in the request's <code>headers_out</code>, to indicate where the client should be redirected <em>to</em>.</p> <h3><a name="resp_handlers" id="resp_handlers">Special considerations for response handlers</a></h3> <p>Handlers for most phases do their work by simply setting a few fields in the <code>request_rec</code> structure (or, in the case of access checkers, simply by returning the correct error code). However, response handlers have to actually send a request back to the client.</p> <p>They should begin by sending an HTTP response header, using the function <code>ap_send_http_header</code>. (You don't have to do anything special to skip sending the header for HTTP/0.9 requests; the function figures out on its own that it shouldn't do anything). If the request is marked <code>header_only</code>, that's all they should do; they should return after that, without attempting any further output.</p> <p>Otherwise, they should produce a request body which responds to the client as appropriate. The primitives for this are <code>ap_rputc</code> and <code>ap_rprintf</code>, for internally generated output, and <code>ap_send_fd</code>, to copy the contents of some <code>FILE *</code> straight to the client.</p> <p>At this point, you should more or less understand the following piece of code, which is the handler which handles <code>GET</code> requests which have no more specific handler; it also shows how conditional <code>GET</code>s can be handled, if it's desirable to do so in a particular response handler -- <code>ap_set_last_modified</code> checks against the <code>If-modified-since</code> value supplied by the client, if any, and returns an appropriate code (which will, if nonzero, be USE_LOCAL_COPY). No similar considerations apply for <code>ap_set_content_length</code>, but it returns an error code for symmetry.</p> <div class="example"><p><code> int default_handler (request_rec *r)<br /> {<br /> <span class="indent"> int errstatus;<br /> FILE *f;<br /> <br /> if (r->method_number != M_GET) return DECLINED;<br /> if (r->finfo.st_mode == 0) return NOT_FOUND;<br /> <br />
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -