Here's a patch for mod_dav; it gives mod_dav the ability to output
both standard and customized <D:error> responses. It's crucial for
marshalling svn error messages back over to the client.
* mod_dav.h (dav_error): add two new fields -- an optional error
namespace, and an error-tag-name. Remove the 'delayed computation'
function and cxt ptrs in this struct; they were never used.
(dav_new_error_tag): new alternative constructor that takes new
fields.
* util.c (dav_new_error_tag): implement constructor.
* mod_dav.c (dav_error_response_tag): new function to output
'standard' xml error response based on error struct.
(dav_handle_err): if no multistatus response is passed in, and if an
error-tag is defined, then call our new xml-output routine.
Index: mod_dav.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/dav/main/mod_dav.c,v
retrieving revision 1.69
diff -u -r1.69 mod_dav.c
--- mod_dav.c 9 Feb 2002 01:57:38 -0000 1.69
+++ mod_dav.c 27 Feb 2002 21:22:23 -0000
@@ -389,6 +389,52 @@
return DONE;
}
+
+/*
+ * Send a "standardized" error response based on the error's namespace & tag
+ */
+static int dav_error_response_tag(request_rec *r,
+ dav_error *err)
+{
+ r->status = err->status;
+ r->status_line = ap_get_status_line(err->status); /* ### needed? */
+ r->content_type = DAV_XML_CONTENT_TYPE;
+
+ /* since we're returning DONE, ensure the request body is consumed. */
+ (void) ap_discard_request_body(r);
+
+ ap_rputs (DAV_XML_HEADER "\n", r);
+ ap_rputs("<D:error xmlns:D=\"DAV:\"", r);
+
+ if (err->desc != NULL) {
+ ap_rputs(" xmlns:m=\"http://apache.org/dav/xmlns\"", r);
+ }
+
+ if ((err->namespace != NULL)
+ && (strcmp(err->namespace, "DAV:") != 0)) {
+ ap_rprintf(r, "xmlns:C=\"%s\">\n", err->namespace);
+ ap_rprintf(r, " <C:%s/>\n", err->tagname);
+ }
+ else {
+ ap_rputs(">\n", r);
+ ap_rprintf(r, " <D:%s/>", err->tagname);
+ }
+
+ if (err->desc != NULL) {
+ ap_rprintf(r, " <m:human-readable>\n%s\n</m:human-readable>\n",
+ err->desc);
+ }
+
+ ap_rputs("</D:error>\n", r);
+
+ /* the response has been sent. */
+ /*
+ * ### Use of DONE obviates logging..!
+ */
+ return DONE;
+}
+
+
/*
** Apache's URI escaping does not replace '&' since that is a valid character
** in a URI (to form a query section). We must explicitly handle it so that
@@ -533,6 +579,13 @@
if (response == NULL) {
/* our error messages are safe; tell Apache this */
apr_table_setn(r->notes, "verbose-error-to", "*");
+
+ /* didn't get a multistatus response passed in, but we still
+ might be able to generate a standard <D:error> response. */
+ if (err->tagname) {
+ return dav_error_response_tag(r, err);
+ }
+
return err->status;
}
Index: mod_dav.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/dav/main/mod_dav.h,v
retrieving revision 1.56
diff -u -r1.56 mod_dav.h
--- mod_dav.h 9 Feb 2002 01:57:38 -0000 1.56
+++ mod_dav.h 27 Feb 2002 21:22:23 -0000
@@ -158,13 +158,10 @@
int save_errno; /* copy of errno causing the error */
- struct dav_error *prev; /* previous error (in stack) */
+ const char *namespace; /* [optional] namespace of error */
+ const char *tagname; /* name of error-tag */
- /* deferred computation of the description */
- void (*compute_desc)(struct dav_error *err, apr_pool_t *p);
- int ctx_i;
- const char *ctx_s;
- void *ctx_p;
+ struct dav_error *prev; /* previous error (in stack) */
} dav_error;
@@ -174,6 +171,18 @@
*/
DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status,
int error_id, const char *desc);
+
+
+/*
+** Create a new error structure with tagname and (optional) namespace;
+** namespace may be NULL, which means "DAV:". save_errno will be
+** filled with the current errno value.
+*/
+DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status,
+ int error_id, const char *desc,
+ const char *namespace,
+ const char *tagname);
+
/*
** Push a new error description onto the stack of errors.
Index: util.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/dav/main/util.c,v
retrieving revision 1.36
diff -u -r1.36 util.c
--- util.c 22 Jan 2002 19:00:22 -0000 1.36
+++ util.c 27 Feb 2002 21:22:24 -0000
@@ -87,6 +87,30 @@
return err;
}
+DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status,
+ int error_id, const char *desc,
+ const char *namespace,
+ const char *tagname)
+{
+ int save_errno = errno;
+ dav_error *err = apr_pcalloc(p, sizeof(*err));
+
+ /* DBG3("dav_new_error: %d %d %s", status, error_id, desc ? desc : "(no desc)"); */
+
+ err->status = status;
+ err->error_id = error_id;
+ err->desc = desc;
+ err->save_errno = save_errno;
+ err->tagname = tagname;
+ if (namespace != NULL)
+ err->namespace = namespace;
+ else
+ err->namespace = "DAV:"; /* ### should this be a symbolic constant? */
+
+ return err;
+}
+
+
DAV_DECLARE(dav_error*) dav_push_error(apr_pool_t *p, int status,
int error_id, const char *desc,
dav_error *prev)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:37:10 2006