From: Graham Leggett Date: Mon, 14 Sep 2009 20:31:18 +0000 (+0000) Subject: mod_dav: Allow other modules to add things to the DAV or Allow headers X-Git-Tag: 2.3.3~301 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9552dd28920104667ada2d9dccade215d46c66fe;p=apache mod_dav: Allow other modules to add things to the DAV or Allow headers of an OPTIONS request. Submitted by: Brian France git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@814832 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 854d4af323..1511df2045 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.3.3 + *) mod_dav: Allow other modules to add things to the DAV or Allow headers + of an OPTIONS request. [Brian France ] + *) core: Lower memory usage of core output filter. [Stefan Fritsch ] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 5a655e460d..eeec6af8d8 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -195,6 +195,7 @@ * until after the register-hooks phase. * 20090401.1 (2.3.3-dev) Protected log.c internals, http_log.h changes * 20090401.2 (2.3.3-dev) Added tmp_flush_bb to core_output_filter_ctx_t + * 20090401.3 (2.3.3-dev) Added DAV options provider to mod_dav.h * */ diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index 163b006d3c..ab0f3d0652 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -59,6 +59,8 @@ #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 @@ static int dav_method_options(request_rec *r) 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 @@ static int dav_method_options(request_rec *r) 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_options_provider *options = + dav_get_options_providers(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 @@ static int dav_method_options(request_rec *r) 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_options_provider *options = + dav_get_options_providers(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; diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index 25dc6d458e..6218266b52 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -2419,6 +2419,31 @@ typedef struct { const dav_hooks_liveprop *provider; /* the provider defining this prop */ } dav_elem_private; +/* -------------------------------------------------------------------- +** +** DAV OPTIONS +*/ +#define DAV_OPTIONS_EXTENSION_GROUP "dav_options" + +typedef struct dav_options_provider +{ + 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_options_provider; + +extern DAV_DECLARE(const dav_options_provider *) dav_get_options_providers(const char *name); + +extern DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p, + const char *name, + const dav_options_provider *provider); + #ifdef __cplusplus } #endif diff --git a/modules/dav/main/providers.c b/modules/dav/main/providers.c index a2ccd1cad8..96a8fc5e93 100644 --- a/modules/dav/main/providers.c +++ b/modules/dav/main/providers.c @@ -31,3 +31,16 @@ DAV_DECLARE(const dav_provider *) dav_lookup_provider(const char *name) { return ap_lookup_provider(DAV_PROVIDER_GROUP, name, "0"); } + +DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p, + const char *name, + const dav_options_provider *provider) +{ + ap_register_provider(p, DAV_OPTIONS_EXTENSION_GROUP, name, "0", provider); +} + +DAV_DECLARE(const dav_options_provider *) dav_get_options_providers(const char *name) +{ + return ap_lookup_provider(DAV_OPTIONS_EXTENSION_GROUP, name, "0"); +} +