From 317cd14108b0db02bd849067becf2f544feed201 Mon Sep 17 00:00:00 2001 From: Greg Stein Date: Fri, 1 Mar 2002 03:25:49 +0000 Subject: [PATCH] Give mod_dav the ability to output both standard and customized responses. It's crucial for marshalling svn error messages back over to the client; and someday it will be needed to return specific 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 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93651 13f79535-47bb-0310-9956-ffa450edef68 --- modules/dav/main/mod_dav.c | 69 +++++++++++++++++++++++++++++++++++++- modules/dav/main/mod_dav.h | 21 ++++++++---- modules/dav/main/util.c | 14 ++++++++ 3 files changed, 97 insertions(+), 7 deletions(-) diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index 6ce8c7b519..5850096baf 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -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 + "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 + "" DEBUG_CR, + err->namespace, err->tagname); + } + else { + ap_rprintf(r, + ">" DEBUG_CR + "" DEBUG_CR, err->tagname); + } + + /* here's our mod_dav specific tag: */ + if (err->desc != NULL) { + ap_rprintf(r, + "" DEBUG_CR + "%s" DEBUG_CR + "" DEBUG_CR, + err->error_id, + apr_xml_quote_string(r->pool, err->desc, 0)); + } + + ap_rputs("" 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 response. */ + if (err->tagname) { + return dav_error_response_tag(r, err); + } + return err->status; } diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index c93598f7c6..053b12327c 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -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. ** diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c index b191bc09c7..4c02f5038f 100644 --- a/modules/dav/main/util.c +++ b/modules/dav/main/util.c @@ -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) -- 2.40.0