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. */
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
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;
}
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;
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.
**
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)