diff options
author | Graham Leggett <minfrin@apache.org> | 2010-11-20 22:39:23 +0100 |
---|---|---|
committer | Graham Leggett <minfrin@apache.org> | 2010-11-20 22:39:23 +0100 |
commit | 476bd51775c8663a8b2e06d280d655ab7987e8a6 (patch) | |
tree | 84a693a582ac513c3cc3c3c482e2393e3e886c59 | |
parent | Update status of ap_expr and Limit (diff) | |
download | apache2-476bd51775c8663a8b2e06d280d655ab7987e8a6.tar.xz apache2-476bd51775c8663a8b2e06d280d655ab7987e8a6.zip |
mod_include: Add the onerror attribute to the include element, allowing
an URL to be specified to include on error.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1037335 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | docs/manual/mod/mod_include.xml | 31 | ||||
-rw-r--r-- | docs/manual/new_features_2_4.xml | 7 | ||||
-rw-r--r-- | modules/filters/mod_include.c | 37 |
4 files changed, 66 insertions, 13 deletions
@@ -6,6 +6,10 @@ Changes with Apache 2.3.9 Fix a denial of service attack against mod_reqtimeout. [Stefan Fritsch] + *) mod_include: Add the onerror attribute to the include element, + allowing an URL to be specified to include on error. [Graham + Leggett] + *) mod_cache_disk: mod_disk_cache renamed to mod_cache_disk, to be consistent with the naming of other modules. [Graham Leggett] diff --git a/docs/manual/mod/mod_include.xml b/docs/manual/mod/mod_include.xml index 9c479f4460..f843718a77 100644 --- a/docs/manual/mod/mod_include.xml +++ b/docs/manual/mod/mod_include.xml @@ -331,9 +331,10 @@ scripts are invoked as normal using the complete URL given in the command, including any query string.</p> - <p>An attribute defines the location of the document; the - inclusion is done for each attribute given to the include - command. The valid attributes are:</p> + <p>An attribute defines the location of the document, and may + appear more than once in an include element; an inclusion is + done for each attribute given to the include command in turn. + The valid attributes are:</p> <dl> <dt><code>file</code></dt> @@ -359,11 +360,11 @@ <p>If the specified URL is a CGI program, the program will be executed and its output inserted in place of the directive in the parsed file. You may include a query string in a CGI url:</p> - + <example> <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> </example> - + <p><code>include virtual</code> should be used in preference to <code>exec cgi</code> to include the output of CGI programs into an HTML document.</p> @@ -376,6 +377,26 @@ requests.</p> </dd> + + <dt><code>onerror</code></dt> + <dd><p>The value is a (%-encoded) URL-path which is shown should a + previous attempt to include a file or virtual attribute failed. + To be effective, this attribute must be specified after the + file or virtual attributes being covered. If the attempt to + include the onerror path fails, or if onerror is not specified, the + default error message will be included.</p> + + <example> + # Simple example<br /> + <!--#include virtual="/not-exist.html" onerror="/error.html" --> + </example> + + <example> + # Dedicated onerror paths<br /> + <!--#include virtual="/path-a.html" onerror="/error-a.html" virtual="/path-b.html" onerror="/error-b.html" --> + </example> + + </dd> </dl> </section> <!-- /include --> diff --git a/docs/manual/new_features_2_4.xml b/docs/manual/new_features_2_4.xml index b4a9aa74b6..94539bd5d9 100644 --- a/docs/manual/new_features_2_4.xml +++ b/docs/manual/new_features_2_4.xml @@ -107,6 +107,13 @@ <dt><module>mod_allowmethods</module></dt> <dd>New module to restrict certain HTTP methods without interfering with authentication or authorization.</dd> + + <dt><module>mod_include</module></dt> + + <dd>Support for the 'onerror' attribute within an 'include' element, + allowing an error document to be served on error instead of the default + error string.</dd> + </dl> </section> diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c index 45ea141116..c8d90fd055 100644 --- a/modules/filters/mod_include.c +++ b/modules/filters/mod_include.c @@ -1648,12 +1648,19 @@ static int find_file(request_rec *r, const char *directive, const char *tag, } /* - * <!--#include virtual|file="..." [virtual|file="..."] ... --> + * <!--#include virtual|file="..." [onerror|virtual|file="..."] ... --> + * + * Output each file/virtual in turn until one of them returns an error. + * On error, ignore all further file/virtual attributes until we reach + * an onerror attribute, where we make an attempt to serve the onerror + * virtual url. If onerror fails, or no onerror is present, the default + * error string is inserted into the stream. */ static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb) { request_rec *r = f->r; + char *last_error; if (!ctx->argc) { ap_log_rerror(APLOG_MARK, @@ -1672,6 +1679,7 @@ static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, return APR_SUCCESS; } + last_error = NULL; while (1) { char *tag = NULL; char *tag_val = NULL; @@ -1684,7 +1692,8 @@ static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, break; } - if (strcmp(tag, "virtual") && strcmp(tag, "file")) { + if (strcmp(tag, "virtual") && strcmp(tag, "file") && strcmp(tag, + "onerror")) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter " "\"%s\" to tag include in %s", tag, r->filename); SSI_CREATE_ERROR_BUCKET(ctx, f, bb); @@ -1709,7 +1718,8 @@ static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, rr = ap_sub_req_lookup_file(newpath, r, f->next); } } - else { + else if ((tag[0] == 'v' && !last_error) + || (tag[0] == 'o' && last_error)) { if (r->kept_body) { rr = ap_sub_req_method_uri(r->method, parsed_string, r, f->next); } @@ -1717,6 +1727,9 @@ static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, rr = ap_sub_req_lookup_uri(parsed_string, r, f->next); } } + else { + continue; + } if (!error_fmt && rr->status != HTTP_OK) { error_fmt = "unable to include \"%s\" in parsed file %s"; @@ -1743,8 +1756,15 @@ static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, if (error_fmt) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error_fmt, tag_val, - r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + r->filename); + if (last_error) { + /* onerror threw an error, give up completely */ + break; + } + last_error = error_fmt; + } + else { + last_error = NULL; } /* Do *not* destroy the subrequest here; it may have allocated @@ -1752,9 +1772,10 @@ static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, * r->pool, so that pool must survive as long as this request. * Yes, this is a memory leak. */ - if (error_fmt) { - break; - } + } + + if (last_error) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); } return APR_SUCCESS; |