[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] mod_dav error handling changes

From: Ben Collins-Sussman <sussman_at_collab.net>
Date: 2002-02-27 23:49:50 CET

Here's a revised patch, based on gstein's suggestions. (Aww... who
are we kidding? Gstein basically *wrote* this thing, given the hours
of explanation he had to give me!)

In any case, now gstein can actually apply the patch to the httpd-2.0
source. And then mod_dav_svn can start marshalling full svn_error_t's
over to libsvn_ra_dav. (Whoopee!)

---------------

Give 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; and someday it will be needed to return
specific <DAV:> errors as dictated by the DeltaV spec.

* 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 22:40:34 -0000
@@ -389,6 +389,54 @@
     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 DEBUG_CR, 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) {
+ ap_rprintf(r, "xmlns:C=\"%s\">" DEBUG_CR, err->namespace);
+ ap_rprintf(r, " <C:%s/>" DEBUG_CR, err->tagname);
+ }
+ else {
+ ap_rputs(">" DEBUG_CR, r);
+ ap_rprintf(r, " <D:%s/>", err->tagname);
+ }
+
+ /* here's our mod_dav specific tag: */
+ if (err->desc != NULL) {
+ ap_rprintf(r,
+ " <m:human-readable errcode=\"%d\">\n%s" DEBUG_CR
+ "</m:human-readable>" DEBUG_CR,
+ err->error_id, err->desc);
+ }
+
+ ap_rputs("</D:error>" DEBUG_CR, 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 +581,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 22:40:35 -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 22:40:35 -0000
@@ -87,6 +87,27 @@
     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;
+ err->namespace = namespace ? namespace : "DAV:";
+
+ 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

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.