From: William A. Rowe Jr Date: Sat, 22 Sep 2001 16:48:01 +0000 (+0000) Subject: By popular demand, the beginnings of an explanation of how the request X-Git-Tag: 2.0.26~200 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=64670c57ff3c8a851b66d37a4c9d1fe730e57c48;p=thirdparty%2Fapache%2Fhttpd.git By popular demand, the beginnings of an explanation of how the request phase runs in 2.0 (compared with 1.3.) git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@91111 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/developer/index.html b/docs/manual/developer/index.html index c20d989ccd2..8da1052cdd7 100644 --- a/docs/manual/developer/index.html +++ b/docs/manual/developer/index.html @@ -27,6 +27,9 @@
Apache 2.0 API Notes
Overview of Apache's Application Programming Interface.
Apache Hook Functions
+
+
Request Processing in Apache 2.0
+
Porting Apache 1.3 Modules
Debugging Memory Allocation
Documenting Apache 2.0
diff --git a/docs/manual/developer/request.html b/docs/manual/developer/request.html new file mode 100644 index 00000000000..6becc938a4e --- /dev/null +++ b/docs/manual/developer/request.html @@ -0,0 +1,217 @@ + + + +Request Processing in Apache 2.0 + + + + + + + +

Request Processing in Apache 2.0

+ +

Warning - this is a first (fast) draft that needs further revision!

+ +

Several changes in Apache 2.0 affect the internal request processing + mechanics. Module authors need to be aware of these changes so they + may take advantage of the optimizations and security enhancements.

+ +

The first major change is to the subrequest and redirect mechanisms. + There were a number of different code paths in Apache 1.3 to attempt + to optimize subrequest or redirect behavior. As patches were introduced + to 2.0, these optimizations (and the server behavior) were quickly broken + due to this duplication of code. All duplicate code has been folded + back into ap_process_internal_request() to prevent the + code from falling out of sync again.

+ +

This means that much of the existing code was 'unoptimized'. It is + the Apache HTTP Project's first goal to create a robust and correct + implementation of the HTTP server RFC. Additional goals include + security, scalability and optimization. New methods were sought to + optimize the server (beyond the performance of Apache 1.3) without + introducing fragile or insecure code.

+ +

The Request Processing Cycle

+ +

All requests pass through ap_process_request_internal() + in request.c, including subrequests and redirects. If a module doesn't + pass generated requests through this code, the author is cautioned that + the module may be broken by future changes to request processing.

+ +

To streamline requests, the module author can take advantage of the + hooks offered to drop out of the request cycle early, or to bypass + core Apache hooks which are irrelevant (and costly in terms of CPU.)

+ +

The Request Parsing Phase

+ +

Unescapes the URL

+ +

The request's parsed_uri path is unescaped, once and only once, at the + beginning of internal request processing.

+ +

This step is bypassed if the proxyreq flag is set, or the parsed_uri.path + element is unset. The module has no further control of this one-time + unescape operation, either failing to unescape or multiply unescaping + the URL leads to security reprecussions.

+ +

Strips Parent and This Elements from the URI

+ +

All /../ and /./ elements are removed by + ap_getparents(). This helps to ensure the path is (nearly) + absolute before the request processing continues.

+ +

This step cannot be bypassed.

+ +

Initial URI Location Walk

+ +

Every request is subject to an ap_location_walk() call. + This ensures that <Location > sections are consistently enforced for + all requests. If the request is an internal redirect or a sub-request, + it may borrow some or all of the processing from the previous or parent + request's ap_location_walk, so this step is generally very efficient + after processing the main request.

+ +

Hook: translate_name

+ +

Modules can determine the file name, or alter the given URI in this step. + For example, mod_vhost_alias will translate the URI's path into the + configured virtual host, mod_alias will translate the path to an alias + path, and if the request falls back on the core, the DocumentRoot is + prepended to the request resource. + +

If all modules DECLINE this phase, an error 500 is returned to the browser, + and a "couldn't translate name" error is logged automatically.

+ +

Hook: map_to_storage

+ +

After the file or correct URI was determined, the appropriate per-dir + configurations are merged together. For example, mod_proxy compares + and merges the appropriate <Proxy > sections. If the URI is nothing + more than a local (non-proxy) TRACE request, the core handles the + request and returns DONE. If no module answers this hook with OK or + DONE, the core will run the request filename against the <Directory > + and <Files > sections. If the request 'filename' isn't an absolute, + legal filename, a note is set for later termination.

+ +

Initial URI Location Walk

+ +

Every request is hardened by a second ap_location_walk() + call. This reassures that a translated request is still subjected to + the configured <Location > sections. The request again borrows + some or all of the processing from it's previous location_walk above, + so this step is almost always very efficient unless the translated URI + mapped to a substantially different path or Virtual Host.

+ +

Hook: header_parser

+ +

The main request then parses the client's headers. This prepares +the remaining request processing steps to better serve the client's +request.

+ +

The Security Phase

+ +

Needs Documentation. Code is;

+
+    switch (ap_satisfies(r)) {
+    case SATISFY_ALL:
+    case SATISFY_NOSPEC:
+        if ((access_status = ap_run_access_checker(r)) != 0) {
+            return decl_die(access_status, "check access", r);
+        }
+        if (ap_some_auth_required(r)) {
+            if (((access_status = ap_run_check_user_id(r)) != 0) || !ap_auth_type(r)) {
+                return decl_die(access_status, ap_auth_type(r)
+		            ? "check user.  No user file?"
+		            : "perform authentication. AuthType not set!", r);
+            }
+            if (((access_status = ap_run_auth_checker(r)) != 0) || !ap_auth_type(r)) {
+                return decl_die(access_status, ap_auth_type(r)
+		            ? "check access.  No groups file?"
+		            : "perform authentication. AuthType not set!", r);
+            }
+        }
+        break;
+    case SATISFY_ANY:
+        if (((access_status = ap_run_access_checker(r)) != 0) || !ap_auth_type(r)) {
+            if (!ap_some_auth_required(r)) {
+                return decl_die(access_status, ap_auth_type(r)
+		            ? "check access"
+		            : "perform authentication. AuthType not set!", r);
+            }
+            if (((access_status = ap_run_check_user_id(r)) != 0) || !ap_auth_type(r)) {
+                return decl_die(access_status, ap_auth_type(r)
+		            ? "check user.  No user file?"
+		            : "perform authentication. AuthType not set!", r);
+            }
+            if (((access_status = ap_run_auth_checker(r)) != 0) || !ap_auth_type(r)) {
+                return decl_die(access_status, ap_auth_type(r)
+		            ? "check access.  No groups file?"
+		            : "perform authentication. AuthType not set!", r);
+            }
+	        }
+        break;
+    }
+
+

The Preparation Phase

+ +

Hook: type_checker

+ +

The modules have an opportunity to test the URI or filename against + the target resource, and set mime information for the request. Both + mod_mime and mod_mime_magic use this phase to compare the file name + or contents against the administrator's configuration and set the + content type, language, character set and request handler. Some + modules may set up their filters or other request handling parameters + at this time.

+ +

If all modules DECLINE this phase, an error 500 is returned to the browser, + and a "couldn't find types" error is logged automatically.

+ +

Hook: fixups

+ +

Many modules are 'trounced' by some phase above. The fixups phase is + used by modules to 'reassert' their ownership or force the request's + fields to their appropriate values. It isn't always the cleanest + mechanism, but occasionally it's the only option.

+ +

Hook: insert_filter

+ +

Modules that transform the content in some way can insert their values + and override existing filters, such that if the user configured a more + advanced filter out-of-order, then the module can move it's order as + need be. + +

The Handler Phase

+ +

This phase is not part of the processing in + ap_process_request_internal(). Many modules prepare one + or more subrequests prior to creating any content at all. After the + core, or a module calls ap_process_request_internal() it + then calls ap_invoke_handler() to generate the request.

+ +

Hook: handler

+ +

The module finally has a chance to serve the request in it's handler + hook. Note that not every prepared request is sent to the handler + hook. Many modules, such as mod_autoindex, will create subrequests + for a given URI, and then never serve the subrequest, but simply + lists it for the user. Remember not to put required teardown from + the hooks above into this module, but register pool cleanups against + the request pool to free resources as required.

+ + + + + + + + + +