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
m...@netbsd.org
Index: dav/main/mod_dav.c
===
--- dav/main/mod_dav.c (revision 1905652)
+++ dav/main/mod_dav.c (working copy)
@@ -84,7 +84,7 @@
int locktimeout;
int allow_depthinfinity;
int allow_lockdiscovery;
-
+int enable_msext;
} dav_dir_conf;
/* per-server configuration */
@@ -206,6 +206,8 @@
allow_depthinfinity);
newconf->allow_lockdiscovery = DAV_INHERIT_VALUE(parent, child,
allow_lockdiscovery);
+newconf->enable_msext = DAV_INHERIT_VALUE(parent, child,
+ enable_msext);
return newconf;
}
@@ -319,6 +321,20 @@
}
/*
+ * Command handler for the DAVmsExt directive, which is FLAG.
+ */
+static const char *dav_cmd_davmsext(cmd_parms *cmd, void *config, int arg)
+{
+dav_dir_conf *conf = (dav_dir_conf *)config;
+
+if (arg)
+conf->enable_msext = DAV_ENABLED_ON;
+else
+conf->enable_msext = DAV_ENABLED_OFF;
+return NULL;
+}
+
+/*
* Command handler for DAVMinTimeout directive, which is TAKE1
*/
static const char *dav_cmd_davmintimeout(cmd_parms *cmd, void *config,
@@ -558,10 +574,17 @@
DAV_DECLARE(apr_status_t) dav_finish_multistatus(request_rec *r,
apr_bucket_brigade *bb)
{
+ap_fputs(r->output_filters, bb, "" DEBUG_CR);
+
+return OK;
+}
+
+
+/* Send the response to the first filter */
+static apr_status_t dav_pass_brigade(request_rec *r, apr_bucket_brigade *bb)
+{
apr_bucket *b;
-ap_fputs(r->output_filters, bb, "" DEBUG_CR);
-
/* indicate the end of the response body */
b = apr_bucket_eos_create(r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
@@ -590,6 +613,7 @@
apr_pool_destroy(subpool);
dav_finish_multistatus(r, bb);
+dav_pass_brigade(r, bb);
}
/*
@@ -1691,6 +1715,7 @@
/* handle the OPTIONS method */
static int dav_method_options(request_rec *r)
{
+dav_dir_conf *conf;
const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r);
const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r);
const dav_hooks_binding *binding_hooks = DAV_GET_HOOKS_BINDING(r);
@@ -1801,6 +1826,11 @@
/* this tells MSFT products to skip looking for FrontPage extensions */
apr_table_setn(r->headers_out, "MS-Author-Via", "DAV");
+/* MS-WDV extensions */
+conf = ap_get_module_config(r->per_dir_config, _module);
+if (conf && conf->enable_msext == DAV_ENABLED_ON)
+ apr_table_setn(r->headers_out, "X-MSDAVEXT", "1");
+
/*
* Determine which methods are allowed on the resource.
* Three cases: resource is null (3), is lock-null (7.4), or exists.
@@ -2146,7 +2176,7 @@
}
/* handle the PROPFIND method */
-static int dav_method_propfind(request_rec *r)
+static int dav_method_propfind(request_rec *r, apr_bucket_brigade *bb)
{
dav_resource *resource;
int depth;
@@ -2237,7 +2267,10 @@
ctx.doc = doc;
ctx.r = r;
-ctx.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+if (bb)
+ctx.bb = bb;
+else
+ctx.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
apr_pool_create(, r->pool);
apr_pool_tag(ctx.scratchpool, "mod_dav-scratch");
@@ -2288,6 +2321,8 @@
}
dav_finish_multistatus(r, ctx.bb);
+if (!bb)
+dav_pass_brigade(r, ctx.bb);
/* the response has been sent. */
return DONE;
@@ -4965,12 +5000,70 @@
return dav_created(r, lookup.rnew->unparsed_uri, "Binding", 0);
}
+static void dav_msdavext_combined(request_rec *r)
+{
+dav_dir_conf *conf;
+const char *msdavext_hdr;
+apr_bucket_brigade *bb;
+apr_bucket *b;
+request_rec *rr = NULL;
+apr_off_t length;
+char buf[16+1]; /* +1 for trailing \0 */
+if (r->main)
+goto out;
+
+if (r->method_number != M_GET && r->method_number != M_POST)
+goto out;
+
+conf = ap_get_module_config(r->per_dir_config, _module);
+if (conf->enable_msext != DAV_ENABLED_ON)
+goto out;
+
+msdavext_hdr = apr_table_get(r->headers_in, "X-MSDAVEXT");
+if (msdavext_hdr == NULL || strcmp(msdavext_hdr, "PROPFIND") !=0)
+goto out;
+
+bb = apr_brigade_create(r->pool,r->output_filters->c->bucket_alloc);
+if (dav_method_propfind(r, bb) != DONE)
+goto out;
+
+if (apr_brigade_length(bb, 1, ) != APR_SUCCESS)
+ goto out;
+
+b = apr_bucket_transient_create(buf, 16,
+r->output_filters->c->bucket_alloc);
+(void)apr_snprintf(buf, sizeof(buf),
+ "%016"