]> granicus.if.org Git - apache/commitdiff
Give mod_dav the ability to output both standard and customized
authorGreg Stein <gstein@apache.org>
Fri, 1 Mar 2002 03:25:49 +0000 (03:25 +0000)
committerGreg Stein <gstein@apache.org>
Fri, 1 Mar 2002 03:25:49 +0000 (03:25 +0000)
<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.

Submitted by: Ben Collins-Sussman <sussman@collab.net>

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93651 13f79535-47bb-0310-9956-ffa450edef68

modules/dav/main/mod_dav.c
modules/dav/main/mod_dav.h
modules/dav/main/util.c

index 6ce8c7b519ccd45d0acc7aa387cf36a79a64becb..5850096bafeb426558096f3cf0d049882a74f564 100644 (file)
@@ -363,7 +363,10 @@ static const char *dav_cmd_davmintimeout(cmd_parms *cmd, void *config,
 static int dav_error_response(request_rec *r, int status, const char *body)
 {
     r->status = status;
-    r->status_line = ap_get_status_line(status);       /* ### needed? */
+
+    /* ### I really don't think this is needed; gotta test */
+    r->status_line = ap_get_status_line(status);
+
     r->content_type = "text/html";
 
     /* since we're returning DONE, ensure the request body is consumed. */
@@ -389,6 +392,63 @@ static int dav_error_response(request_rec *r, int status, const char *body)
     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;
+
+    /* ### I really don't think this is needed; gotta test */
+    r->status_line = ap_get_status_line(err->status);
+
+    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
+             "<D:error xmlns:D=\"DAV:\"", r);
+
+    if (err->desc != NULL) {
+        /* ### should move this namespace somewhere (with the others!) */
+        ap_rputs(" xmlns:m=\"http://apache.org/dav/xmlns\"", r);
+    }
+
+    if (err->namespace != NULL) {
+        ap_rprintf(r,
+                   " xmlns:C=\"%s\">" DEBUG_CR
+                   "<C:%s/>" DEBUG_CR,
+                   err->namespace, err->tagname);
+    }
+    else {
+        ap_rprintf(r,
+                   ">" DEBUG_CR
+                   "<D:%s/>" DEBUG_CR, err->tagname);
+    }
+    
+    /* here's our mod_dav specific tag: */
+    if (err->desc != NULL) {
+        ap_rprintf(r, 
+                   "<m:human-readable errcode=\"%d\">" DEBUG_CR
+                   "%s" DEBUG_CR
+                   "</m:human-readable>" DEBUG_CR,
+                   err->error_id,
+                   apr_xml_quote_string(r->pool, err->desc, 0));
+    }
+
+    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 +593,13 @@ static int dav_handle_err(request_rec *r, dav_error *err,
     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 c93598f7c6578c56d3600d8072a033967d3dc189..053b12327ca7ce6c05501bd63ea21c1d2cd0e8cb 100644 (file)
@@ -158,13 +158,10 @@ typedef struct dav_error {
 
     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;
 
@@ -175,6 +172,18 @@ typedef struct dav_error {
 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 b191bc09c7a78163c4cdcbc76d5a16f5cbc18fba..4c02f5038f6eefe87e19699f95e18573e1233295 100644 (file)
@@ -87,6 +87,20 @@ DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status,
     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)
+{
+    dav_error *err = dav_new_error(p, status, error_id, desc);
+
+    err->tagname = tagname;
+    err->namespace = namespace;
+
+    return err;
+}
+
+
 DAV_DECLARE(dav_error*) dav_push_error(apr_pool_t *p, int status, 
                                        int error_id, const char *desc, 
                                        dav_error *prev)