You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Emmanuel Dreyfus <ma...@netbsd.org> on 2022/11/28 02:02:19 UTC
Help with buckets
Hello
I am working on MS-WDV [1]. One of the feature of the specification is
a GET + PROPFIND command combination, which the client requests by
adding a X-MSDAVEXT: PROPFIND header to a GET request. The server
should answer by a multipart/MSDAVEXTPrefixEncoded reply, which
contains
- 64 bit hex size of PROPFIND output
- PROPFIND output
- 64 bit hex size of GET output
- GET output
I understand I must perform a subrequest from dav_handler() to
get the PROPFIND output, but how do I prepend the 64 bit hex suze
of PROPFIND? Is it possible to retreive the buckets sent by the
subrequest and use APR_BRIGADE_INSERT to prepend a transient
bucket?
[1] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wdv
--
Emmanuel Dreyfus
manu@netbsd.org
Re: MS-WDV (was Re: Help with buckets)
Posted by Emmanuel Dreyfus <ma...@netbsd.org>.
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
manu@netbsd.org
Re: MS-WDV (was Re: Help with buckets)
Posted by Ruediger Pluem <rp...@apache.org>.
On 12/2/22 4:42 PM, Emmanuel Dreyfus wrote:
> 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 can try that, but whatever the method is, we need to produce the
> propfind data before sending its size.
>
> I see two unsatisfying alternatives:
>
> 1) produce propfind data in a buffer, output the size, then the buffer
>
> 2) produce propfind data, discarding it as it comes but coutning its size,
> then output the size, and produce the propfind data a second time.
>
> First approach wastes memory, second approach wastes CPU. And second approach
> needs a mechanism to ensure propfind data does not change between the two
> times it is produced. I am not sure that can be guaranteed.
I think we cannot guarantee this, which leaves us with 1.
Regards
RĂ¼diger
Re: MS-WDV (was Re: Help with buckets)
Posted by Emmanuel Dreyfus <ma...@netbsd.org>.
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 can try that, but whatever the method is, we need to produce the
propfind data before sending its size.
I see two unsatisfying alternatives:
1) produce propfind data in a buffer, output the size, then the buffer
2) produce propfind data, discarding it as it comes but coutning its size,
then output the size, and produce the propfind data a second time.
First approach wastes memory, second approach wastes CPU. And second approach
needs a mechanism to ensure propfind data does not change between the two
times it is produced. I am not sure that can be guaranteed.
--
Emmanuel Dreyfus
manu@netbsd.org
Re: MS-WDV (was Re: Help with buckets)
Posted by Joe Orton <jo...@redhat.com>.
On Fri, Dec 02, 2022 at 08:53:07AM +0000, Emmanuel Dreyfus wrote:
> Hello
>
> I made some progress with the combined GET+PROPFIND specified
> by MS-WDV (for a summary, see
> https://lists.apache.org/thread/57s1vvl6k9qpdv5ym7mtcl29bd933w7k )
>
> Attached is the diff against trunk, form comments.
Hi Emmanuel,
That's a very weird protocol design, wow. Have you tested this with a
long PROPFIND response? It needs to buffer the entire response in the
output brigade to work out the length in the "multipart" prefix, but
mod_dav will flush output brigades down the filter chain regularly
during the multistatus response processing.
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.
Regards, Joe
MS-WDV (was Re: Help with buckets)
Posted by Emmanuel Dreyfus <ma...@netbsd.org>.
Hello
I made some progress with the combined GET+PROPFIND specified
by MS-WDV (for a summary, see
https://lists.apache.org/thread/57s1vvl6k9qpdv5ym7mtcl29bd933w7k )
Attached is the diff against trunk, form comments.
--
Emmanuel Dreyfus
manu@netbsd.org