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;