Changes with Apache 2.4.5
+ *) mod_dav: Improve error handling in dav_method_put(), add new
+ dav_join_error() function. PR 54145. [Ben Reser <ben reser.org>]
+
*) mod_dav: Sending a MERGE request against a URI handled by mod_dav_svn with
the source href (sent as part of the request body as XML) pointing to a
URI that is not configured for DAV will trigger a segfault. [Ben Reser
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * mod_dav: Improve error handling in dav_method_put(), add new
- dav_join_error() function. PR 54145.
- trunk patch: http://svn.apache.org/r1464241
- 2.4.x patch: http://people.apache.org/~minfrin/httpd-mod_dav-errorhandling.patch
- +1: minfrin, jim, jorton
-
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
[ New proposals should be added at the end of the list ]
* 20120211.9 (2.4.4-dev) Add fgrab() to ap_slotmem_provider_t.
* 20120211.10 (2.4.4-dev) Add in bal_persist field to proxy_server_conf
* 20120211.11 (2.4.4-dev) Add ap_bin2hex()
- * 20120211.12 (2.4.5-dev) Add ap_remove_input|output_filter_byhandle()
- * 20120211.13 (2.4.5-dev) Add ap_get_exec_line
- * 20120211.14 (2.4.5-dev) Add ppinherit and inherit to proxy_server_conf
+ * 20120211.12 (2.4.5-dev) Add ap_remove_input|output_filter_byhandle()
+ * 20120211.13 (2.4.5-dev) Add ap_get_exec_line
+ * 20120211.14 (2.4.5-dev) Add ppinherit and inherit to proxy_server_conf
+ * 20120211.15 (2.4.5-dev) Add dav_join_error()
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20120211
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 14 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 15 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
else {
/* XXX: should this actually be HTTP_BAD_REQUEST? */
http_err = HTTP_INTERNAL_SERVER_ERROR;
- msg = apr_psprintf(r->pool, "Could not get next bucket "
- "brigade (URI: %s)", msg);
+ msg = apr_psprintf(r->pool, "An error occurred while reading"
+ " the request body (URI: %s)", msg);
}
err = dav_new_error(r->pool, http_err, 0, rc, msg);
break;
continue;
}
- rc = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
- if (rc != APR_SUCCESS) {
- err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, rc,
- apr_psprintf(r->pool,
- "An error occurred while reading"
- " the request body (URI: %s)",
- ap_escape_html(r->pool, r->uri)));
- break;
- }
-
if (err == NULL) {
/* write whatever we read, until we see an error */
+ rc = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
+ if (rc != APR_SUCCESS) {
+ err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, rc,
+ apr_psprintf(r->pool,
+ "An error occurred while"
+ " reading the request body"
+ " from the bucket (URI: %s)",
+ ap_escape_html(r->pool, r->uri)));
+ break;
+ }
+
err = (*resource->hooks->write_stream)(stream, data, len);
}
}
err2 = (*resource->hooks->close_stream)(stream,
err == NULL /* commit */);
- if (err2 != NULL && err == NULL) {
- /* no error during the write, but we hit one at close. use it. */
- err = err2;
- }
+ err = dav_join_error(err, err2);
}
/*
/* check for errors now */
if (err != NULL) {
+ err = dav_join_error(err, err2); /* don't forget err2 */
return dav_handle_err(r, err, NULL);
}
const char *desc, dav_error *prev);
+/*
+** Join two errors together.
+**
+** This function is used to add a new error stack onto an existing error so
+** that subsequent errors can be reported after the first error. It returns
+** the correct error stack to use so that the caller can blindly call it
+** without checking that both dest and src are not NULL.
+**
+** <dest> is the error stack that the error will be added to.
+**
+** <src> is the error stack that will be appended.
+*/
+DAV_DECLARE(dav_error*) dav_join_error(dav_error* dest, dav_error* src);
+
+
/* error ID values... */
/* IF: header errors */
return err;
}
+DAV_DECLARE(dav_error*) dav_join_error(dav_error *dest, dav_error *src)
+{
+ dav_error *curr = dest;
+
+ /* src error doesn't exist so nothing to join just return dest */
+ if (src == NULL) {
+ return dest;
+ }
+
+ /* dest error doesn't exist so nothing to join just return src */
+ if (curr == NULL) {
+ return src;
+ }
+
+ /* find last error in dest stack */
+ while (curr->prev != NULL) {
+ curr = curr->prev;
+ }
+
+ /* add the src error onto end of dest stack and return it */
+ curr->prev = src;
+ return dest;
+}
+
DAV_DECLARE(void) dav_check_bufsize(apr_pool_t * p, dav_buffer *pbuf,
apr_size_t extra_needed)
{