Wed, 25 Jun 2025 20:45:21 +0200
change error handling in case webdav_xattr_parse_data fails: set response to 500 instead of failig the entire multistatus response
--- a/src/server/public/webdav.h Wed Jun 18 09:38:29 2025 +0200 +++ b/src/server/public/webdav.h Wed Jun 25 20:45:21 2025 +0200 @@ -253,6 +253,8 @@ int err; + int status; + /* * int addprop(WebdavResource *res, WebdavProperty *property, int status); *
--- a/src/server/webdav/multistatus.c Wed Jun 18 09:38:29 2025 +0200 +++ b/src/server/webdav/multistatus.c Wed Jun 25 20:45:21 2025 +0200 @@ -264,6 +264,26 @@ return out->error; } +static void write_status_str(Writer *out, int status) { + char statuscode[8]; + int sclen = snprintf(statuscode, 8, "%d ", status); + if(sclen > 4) { + statuscode[0] = '5'; + statuscode[1] = '0'; + statuscode[2] = '0'; + statuscode[3] = ' '; + sclen = 4; + } + writer_put_lit(out, "HTTP/1.1 "); + writer_put(out, statuscode, sclen); + const char *status_msg = protocol_status_message(status); + if(status_msg) { + writer_put(out, status_msg, strlen(status_msg)); + } else { + writer_put_lit(out, "Server Error"); + } +} + static int send_response_tag(Multistatus *ms, MSResponse *rp, Writer *out) { writer_put_lit(out, " <D:response>\n" " <D:href>"); @@ -272,64 +292,56 @@ WSBool writeContent = ms->proppatch ? FALSE : TRUE; - if(rp->plist_begin) { - writer_put_lit(out, " <D:propstat>\n" - " <D:prop>\n"); - // send properties - PropertyOkList *p = rp->plist_begin; - while(p) { - writer_put_lit(out, " "); - if(send_property(ms, p->property, p->nsdef, writeContent, out)) { - return out->error; - } - writer_put_lit(out, "\n"); - p = p->next; - } - - writer_put_lit(out, " </D:prop>\n" - " <D:status>HTTP/1.1 200 OK</D:status>\n" - " </D:propstat>\n"); - } - - // send error properties - PropertyErrorList *error = rp->errors; - while(error) { - writer_put_lit(out, " <D:propstat>\n" - " <D:prop>\n"); + if(rp->resource.status >= 300) { + writer_put_lit(out, " <D:status>"); + write_status_str(out, rp->resource.status); + writer_put_lit(out, "</D:status>\n"); - WebdavPList *errprop = error->begin; - while(errprop) { - writer_put_lit(out, " "); - if(send_property(ms, errprop->property, NULL, FALSE, out)) { - return out->error; + } else { + if(rp->plist_begin) { + writer_put_lit(out, " <D:propstat>\n" + " <D:prop>\n"); + // send properties + PropertyOkList *p = rp->plist_begin; + while(p) { + writer_put_lit(out, " "); + if(send_property(ms, p->property, p->nsdef, writeContent, out)) { + return out->error; + } + writer_put_lit(out, "\n"); + p = p->next; } - writer_putc(out, '\n'); - errprop = errprop->next; + + writer_put_lit(out, " </D:prop>\n" + " <D:status>HTTP/1.1 200 OK</D:status>\n" + " </D:propstat>\n"); } - - char statuscode[8]; - int sclen = snprintf(statuscode, 8, "%d ", error->status); - if(sclen > 4) { - statuscode[0] = '5'; - statuscode[1] = '0'; - statuscode[2] = '0'; - statuscode[3] = ' '; - sclen = 4; + + // send error properties + PropertyErrorList *error = rp->errors; + while(error) { + writer_put_lit(out, " <D:propstat>\n" + " <D:prop>\n"); + + WebdavPList *errprop = error->begin; + while(errprop) { + writer_put_lit(out, " "); + if(send_property(ms, errprop->property, NULL, FALSE, out)) { + return out->error; + } + writer_putc(out, '\n'); + errprop = errprop->next; + } + + writer_put_lit(out, " </D:prop>\n" + " <D:status>"); + write_status_str(out, error->status); + writer_put_lit(out, "</D:status>\n" + " </D:propstat>\n"); + + + error = error->next; } - writer_put_lit(out, " </D:prop>\n" - " <D:status>HTTP/1.1 "); - writer_put(out, statuscode, sclen); - const char *status_msg = protocol_status_message(error->status); - if(status_msg) { - writer_put(out, status_msg, strlen(status_msg)); - } else { - writer_put_lit(out, "Server Error"); - } - writer_put_lit(out, "</D:status>\n" - " </D:propstat>\n"); - - - error = error->next; } // end response tag
--- a/src/server/webdav/operation.c Wed Jun 18 09:38:29 2025 +0200 +++ b/src/server/webdav/operation.c Wed Jun 25 20:45:21 2025 +0200 @@ -214,6 +214,14 @@ { ret = REQ_ABORTED; } + if(dav->next && resource->status >= 299) { + log_ereport( + LOG_FAILURE, + "webdav: error %d for resource %s: skip remaining backend", + resource->status, + resource->href); + break; + } dav = dav->next; request = request->next;
--- a/src/server/webdav/xattrbackend.c Wed Jun 18 09:38:29 2025 +0200 +++ b/src/server/webdav/xattrbackend.c Wed Jun 25 20:45:21 2025 +0200 @@ -184,17 +184,18 @@ CxMap *pmap = webdav_xattr_parse_data(a, xattr_data, xattr_data_len, path); pool_free(sn->pool, xattr_data); + int err = 0; if(!pmap) { - return 1; + // TODO: should we set all requested properties to status 500 instead? + resource->status = 500; + } else { + if(request->allprop || request->propname) { + err = webdav_xattr_propfind_allprop(request, resource, a, pmap); + } else { + err = webdav_xattr_propfind_get_requested_properties(request, resource, a, pmap); + } } - int err; - if(request->allprop || request->propname) { - err = webdav_xattr_propfind_allprop(request, resource, a, pmap); - } else { - err = webdav_xattr_propfind_get_requested_properties(request, resource, a, pmap); - } - return err; }