On Fri, Dec 02, 2022 at 03:17:05PM +0000, Joe Orton wrote: > I think this might need to do something more complex, maybe running the > PROPFIND in a subrequest properly and capturing (buffering) the output > in a custom filter, rather than using the mod_dav internal API directly. > Have you tried using ap_sub_req_method_uri()? Not sure this has been > tried before with mod_dav so might well be something I'm missing.
I did it the way you suggested. The patch gets huge, I just send the reelvant bits. Does it looks good to you? In register_hooks() I have ap_register_output_filter("DAV_MSEXT_OUT", dav_msext_output, NULL, AP_FTYPE_RESOURCE); Then: static apr_status_t dav_msext_output(ap_filter_t *f, apr_bucket_brigade *bb) { apr_bucket_brigade *bbsub = f->ctx; apr_bucket *b; b = APR_BRIGADE_FIRST(bb); while (b != APR_BRIGADE_SENTINEL(bb)) { apr_bucket *nb; if (APR_BUCKET_IS_EOS(b)) break; nb = APR_BUCKET_NEXT(b); APR_BUCKET_REMOVE(b); APR_BRIGADE_INSERT_TAIL(bbsub, b); b = nb; } return ap_pass_brigade(f->next, bb); } static void dav_msdavext_combined_propfind(request_rec *r) { apr_bucket_brigade *bbsub; apr_bucket_brigade *bb; ap_filter_t *f; apr_bucket *b; request_rec *rr = NULL; apr_off_t length; bbsub = apr_brigade_create(r->pool, r->output_filters->c->bucket_alloc); rr = ap_sub_req_method_uri("PROPFIND", r->uri, r, r->output_filters); if (!rr || rr->status != HTTP_OK) goto out; f = ap_add_output_filter("DAV_MSEXT_OUT", bbsub, rr, rr->connection); if (!f) goto out; if (ap_run_sub_req(rr) != OK) goto out; ap_remove_output_filter(f); if (apr_brigade_length(bbsub, 1, &length) != APR_SUCCESS) goto out; bb = apr_brigade_create(r->pool,r->output_filters->c->bucket_alloc); apr_brigade_printf(bb, NULL, NULL, "%016" APR_UINT64_T_HEX_FMT, length); APR_BRIGADE_CONCAT(bb, bbsub); ap_destroy_sub_req(rr); rr = NULL; rr = ap_sub_req_lookup_uri(r->uri, r, r->output_filters); if (!rr || rr->status != HTTP_OK || rr->filename == NULL || rr->finfo.filetype != APR_REG) goto out; apr_brigade_printf(bb, NULL, NULL, "%016" APR_UINT64_T_HEX_FMT, rr->finfo.size); ap_set_content_type(r, "multipart/MSDAVEXTPrefixEncoded"); ap_pass_brigade(r->output_filters, bb); /* plain GET rocessing happens afterward */ out: if (rr) ap_destroy_sub_req(rr); return; } -- Emmanuel Dreyfus m...@netbsd.org