Does the attached patch solve your issue? Regards
Rüdiger On 9/20/21 8:01 PM, Evgeny Kotkov wrote: > Hi, > > I think that I have stumbled across a significant regression in httpd 2.4.49 > where mod_dav has been changed in a way that makes it ignore the errors > returned by a versioning provider during REPORT requests. > > I haven't checked that in detail, but I think that r1892513 [1] is the change > that is causing the new behavior. > > Consider the new core part of the dav_method_report() function: > > … > result = dav_run_deliver_report(r, resource, doc, > r->output_filters, &err); > switch (result) { > case OK: > return DONE; > case DECLINED: > /* No one handled the report */ > return HTTP_NOT_IMPLEMENTED; > default: > if ((err) != NULL) { > … handle the error > } > > Assuming there are no deliver_report hooks, this code is going to call > dav_core_deliver_report(), whose relevant part is as follows: > > … > if (vsn_hooks) { > *err = (*vsn_hooks->deliver_report)(r, resource, doc, > r->output_filters); > return OK; > } > … > > Here the "return OK" part skips the error handling on the calling site, > even if there is an associated error returned in *err. > > In turn, this causes the following regression: > > - For a failed request where the server hasn't started sending the response, > it is now going to erroneously send a 200 OK with an empty body instead of > an error response with the appropriate HTTP status. > > - For a failed request where the server has started sending the response body, > it is now going to handle it as if it was successfully completed instead of > aborting the connection. The likely outcome of this is that the server is > going to send a truncated payload with a 2xx status indicating success. > > This regression can cause unexpected behavior of the Subversion clients, > for example in cases where the (ignored) error occurred due to a > non-successful > authorization check. Other DAV clients may be susceptible to some kinds of > unexpected behavior as well. > > [1] https://svn.apache.org/r1892513 > > > Thanks, > Evgeny Kotkov >
Index: modules/dav/main/mod_dav.c =================================================================== --- modules/dav/main/mod_dav.c (revision 1893352) +++ modules/dav/main/mod_dav.c (working copy) @@ -4407,6 +4407,27 @@ /* run report hook */ result = dav_run_deliver_report(r, resource, doc, r->output_filters, &err); + if (err != NULL) { + + if (! r->sent_bodyct) { + /* No data has been sent to client yet; throw normal error. */ + return dav_handle_err(r, err, NULL); + } + + /* If an error occurred during the report delivery, there's + basically nothing we can do but abort the connection and + log an error. This is one of the limitations of HTTP; it + needs to "know" the entire status of the response before + generating it, which is just impossible in these streamy + response situations. */ + err = dav_push_error(r->pool, err->status, 0, + "Provider encountered an error while streaming" + " a REPORT response.", err); + dav_log_err(r, err, APLOG_ERR); + r->connection->aborted = 1; + + return DONE; + } switch (result) { case OK: return DONE; @@ -4414,27 +4435,7 @@ /* No one handled the report */ return HTTP_NOT_IMPLEMENTED; default: - if ((err) != NULL) { - - if (! r->sent_bodyct) { - /* No data has been sent to client yet; throw normal error. */ - return dav_handle_err(r, err, NULL); - } - - /* If an error occurred during the report delivery, there's - basically nothing we can do but abort the connection and - log an error. This is one of the limitations of HTTP; it - needs to "know" the entire status of the response before - generating it, which is just impossible in these streamy - response situations. */ - err = dav_push_error(r->pool, err->status, 0, - "Provider encountered an error while streaming" - " a REPORT response.", err); - dav_log_err(r, err, APLOG_ERR); - r->connection->aborted = 1; - - return DONE; - } + return DONE; } return DONE;