From: Graham Leggett
Date: Sat, 20 Nov 2010 21:39:23 +0000 (+0000)
Subject: mod_include: Add the onerror attribute to the include element, allowing
X-Git-Tag: 2.3.9~19
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=476bd51775c8663a8b2e06d280d655ab7987e8a6;p=thirdparty%2Fapache%2Fhttpd.git
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
---
diff --git a/CHANGES b/CHANGES
index 1c736e6c2c5..23cc7175459 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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 9c479f4460e..f843718a772 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.
- An attribute defines the location of the document; the
- inclusion is done for each attribute given to the include
- command. The valid attributes are:
+ 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:
file
@@ -359,11 +360,11 @@
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:
-
+
<!--#include virtual="/cgi-bin/example.cgi?argument=value" -->
-
+
include virtual
should be used in preference
to exec cgi
to include the output of CGI programs
into an HTML document.
@@ -375,6 +376,26 @@
Without the directive, all subrequests are processed as GET
requests.
+
+
+ onerror
+ 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.
+
+
+ # Simple example
+ <!--#include virtual="/not-exist.html" onerror="/error.html" -->
+
+
+
+ # Dedicated onerror paths
+ <!--#include virtual="/path-a.html" onerror="/error-a.html" virtual="/path-b.html" onerror="/error-b.html" -->
+
+
diff --git a/docs/manual/new_features_2_4.xml b/docs/manual/new_features_2_4.xml
index b4a9aa74b66..94539bd5d9e 100644
--- a/docs/manual/new_features_2_4.xml
+++ b/docs/manual/new_features_2_4.xml
@@ -107,6 +107,13 @@
mod_allowmethods
New module to restrict certain HTTP methods without interfering with
authentication or authorization.
+
+ mod_include
+
+ Support for the 'onerror' attribute within an 'include' element,
+ allowing an error document to be served on error instead of the default
+ error string.
+
diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c
index 45ea141116d..c8d90fd0552 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,
}
/*
- *
+ *
+ *
+ * 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;