Index: modules/dav/main/mod_dav.h =================================================================== --- modules/dav/main/mod_dav.h (revision 814689) +++ modules/dav/main/mod_dav.h (working copy) @@ -2419,6 +2419,31 @@ const dav_hooks_liveprop *provider; /* the provider defining this prop */ } dav_elem_private; +/* -------------------------------------------------------------------- +** +** DAV OPTIONS HOOKS +*/ +#define DAV_OPTIONS_EXTENSION_GROUP "dav_options" + +typedef struct dav_hooks_options +{ + dav_error* (*dav_header)(request_rec *r, + const dav_resource *resource, + apr_text_header *phdr); + + dav_error* (*dav_method)(request_rec *r, + const dav_resource *resource, + apr_text_header *phdr); + + void *ctx; +} dav_hooks_options; + +extern DAV_DECLARE(const dav_hooks_options *) dav_get_options_hooks(const char *name); + +extern DAV_DECLARE(void) dav_options_register_hooks(apr_pool_t *p, + const char *name, + const dav_hooks_options *provider); + #ifdef __cplusplus } #endif Index: modules/dav/main/mod_dav.c =================================================================== --- modules/dav/main/mod_dav.c (revision 814689) +++ modules/dav/main/mod_dav.c (working copy) @@ -59,7 +59,9 @@ #include "mod_dav.h" +#include "ap_provider.h" + /* ### what is the best way to set this? */ #define DAV_DEFAULT_PROVIDER "filesystem" @@ -1575,6 +1577,9 @@ const apr_xml_elem *elem; dav_error *err; + apr_array_header_t *extensions; + ap_list_provider_names_t *entry; + /* resolve the resource */ err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, &resource); @@ -1603,6 +1608,23 @@ if (binding_hooks != NULL) dav_level = apr_pstrcat(r->pool, dav_level, ",bindings", NULL); + /* DAV header additions registered by external modules */ + extensions = ap_list_provider_names(r->pool, DAV_OPTIONS_EXTENSION_GROUP, "0"); + entry = (ap_list_provider_names_t *)extensions->elts; + + for (i = 0; i < extensions->nelts; i++, entry++) { + const dav_hooks_options *options = + dav_get_options_hooks(entry->provider_name); + + if (options && options->dav_header) { + apr_text_header hoptions = { 0 }; + + options->dav_header(r, resource, &hoptions); + for (t = hoptions.first; t && t->text; t = t->next) + dav_level = apr_pstrcat(r->pool, dav_level, ",", t->text, NULL); + } + } + /* ### * MSFT Web Folders chokes if length of DAV header value > 63 characters! * To workaround that, we use separate DAV headers for versioning and @@ -1746,6 +1768,23 @@ apr_table_addn(methods, "SEARCH", ""); } + /* additional methods registered by external modules */ + extensions = ap_list_provider_names(r->pool, DAV_OPTIONS_EXTENSION_GROUP, "0"); + entry = (ap_list_provider_names_t *)extensions->elts; + + for (i = 0; i < extensions->nelts; i++, entry++) { + const dav_hooks_options *options = + dav_get_options_hooks(entry->provider_name); + + if (options && options->dav_method) { + apr_text_header hoptions = { 0 }; + + options->dav_method(r, resource, &hoptions); + for (t = hoptions.first; t && t->text; t = t->next) + apr_table_addn(methods, t->text, ""); + } + } + /* Generate the Allow header */ arr = apr_table_elts(methods); elts = (const apr_table_entry_t *)arr->elts; Index: modules/dav/main/providers.c =================================================================== --- modules/dav/main/providers.c (revision 814689) +++ modules/dav/main/providers.c (working copy) @@ -31,3 +31,16 @@ { return ap_lookup_provider(DAV_PROVIDER_GROUP, name, "0"); } + +DAV_DECLARE(void) dav_options_register_hooks(apr_pool_t *p, + const char *name, + const dav_hooks_options *provider) +{ + ap_register_provider(p, DAV_OPTIONS_EXTENSION_GROUP, name, "0", provider); +} + +DAV_DECLARE(const dav_hooks_options *) dav_get_options_hooks(const char *name) +{ + return ap_lookup_provider(DAV_OPTIONS_EXTENSION_GROUP, name, "0"); +} +