]> granicus.if.org Git - apache/commitdiff
mod_dav: Allow other modules to become providers and add resource types
authorGraham Leggett <minfrin@apache.org>
Sat, 19 Sep 2009 11:20:24 +0000 (11:20 +0000)
committerGraham Leggett <minfrin@apache.org>
Sat, 19 Sep 2009 11:20:24 +0000 (11:20 +0000)
to the DAV response.
Submitted by: Jari Urpalainen <jari.urpalainen nokia.com>, Brian France <brian brianfrance.com>

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@816893 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/dav/main/mod_dav.h
modules/dav/main/providers.c
modules/dav/main/std_liveprop.c

diff --git a/CHANGES b/CHANGES
index 8e7e229fd31e3d326b0b8d47e6db23dd255c5194..5debcbc0c80974283016ef88b048cb96fefd591f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,10 @@ Changes with Apache 2.3.3
      mod_proxy_ftp: NULL pointer dereference on error paths.
      [Stefan Fritsch <sf fritsch.de>, Joe Orton]
 
+  *) mod_dav: Allow other modules to become providers and add resource types
+     to the DAV response. [Jari Urpalainen <jari.urpalainen nokia.com>,
+     Brian France <brian brianfrance.com>]
+
   *) mod_dav: Allow other modules to add things to the DAV or Allow headers
      of an OPTIONS request. [Jari Urpalainen <jari.urpalainen nokia.com>,
      Brian France <brian brianfrance.com>]
index 6218266b52930e49eb941b13ddf2f94723410520..ac04cda419c14f9a4a1f01d618e7d9aeae59ddc3 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 /**
- * @file  mod_dav.h 
+ * @file  mod_dav.h
  * @brief DAV extension module for Apache 2.0.*
  *
  * @defgroup MOD_DAV mod_dav
@@ -78,7 +78,7 @@ extern "C" {
 
 #define DAV_INFINITY    INT_MAX    /* for the Depth: header */
 
-/* Create a set of DAV_DECLARE(type), DAV_DECLARE_NONSTD(type) and 
+/* Create a set of DAV_DECLARE(type), DAV_DECLARE_NONSTD(type) and
  * DAV_DECLARE_DATA with appropriate export and import tags for the platform
  */
 #if !defined(WIN32)
@@ -136,7 +136,7 @@ typedef struct dav_error {
 ** Create a new error structure. save_errno will be filled with the current
 ** errno value.
 */
-DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status, 
+DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status,
                                       int error_id, const char *desc);
 
 
@@ -145,7 +145,7 @@ DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status,
 ** namespace may be NULL, which means "DAV:". save_errno will be
 ** filled with the current errno value.
 */
-DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status, 
+DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status,
                                           int error_id, const char *desc,
                                           const char *namespace,
                                           const char *tagname);
@@ -411,28 +411,28 @@ typedef struct
 #define DAV_BUFFER_PAD          64     /* amount of pad when growing */
 
 /* set the cur_len to the given size and ensure space is available */
-DAV_DECLARE(void) dav_set_bufsize(apr_pool_t *p, dav_buffer *pbuf, 
+DAV_DECLARE(void) dav_set_bufsize(apr_pool_t *p, dav_buffer *pbuf,
                                   apr_size_t size);
 
 /* initialize a buffer and copy the specified (null-term'd) string into it */
-DAV_DECLARE(void) dav_buffer_init(apr_pool_t *p, dav_buffer *pbuf, 
+DAV_DECLARE(void) dav_buffer_init(apr_pool_t *p, dav_buffer *pbuf,
                                   const char *str);
 
 /* check that the buffer can accomodate <extra_needed> more bytes */
-DAV_DECLARE(void) dav_check_bufsize(apr_pool_t *p, dav_buffer *pbuf, 
+DAV_DECLARE(void) dav_check_bufsize(apr_pool_t *p, dav_buffer *pbuf,
                                     apr_size_t extra_needed);
 
 /* append a string to the end of the buffer, adjust length */
-DAV_DECLARE(void) dav_buffer_append(apr_pool_t *p, dav_buffer *pbuf, 
+DAV_DECLARE(void) dav_buffer_append(apr_pool_t *p, dav_buffer *pbuf,
                                     const char *str);
 
 /* place a string on the end of the buffer, do NOT adjust length */
-DAV_DECLARE(void) dav_buffer_place(apr_pool_t *p, dav_buffer *pbuf, 
+DAV_DECLARE(void) dav_buffer_place(apr_pool_t *p, dav_buffer *pbuf,
                                    const char *str);
 
 /* place some memory on the end of a buffer; do NOT adjust length */
-DAV_DECLARE(void) dav_buffer_place_mem(apr_pool_t *p, dav_buffer *pbuf, 
-                                       const void *mem, apr_size_t amt, 
+DAV_DECLARE(void) dav_buffer_place_mem(apr_pool_t *p, dav_buffer *pbuf,
+                                       const void *mem, apr_size_t amt,
                                        apr_size_t pad);
 
 
@@ -604,7 +604,7 @@ typedef struct {
 **
 ** (of course, use your own domain to ensure a unique value)
 */
-APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, gather_propsets, 
+APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, gather_propsets,
                          (apr_array_header_t *uris))
 
 /*
@@ -634,7 +634,7 @@ APR_DECLARE_EXTERNAL_HOOK(dav, DAV, int, find_liveprop,
 ** properties on the specified resource. If a particular liveprop is
 ** not defined for this resource, then it should not be inserted.
 */
-APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, insert_all_liveprops, 
+APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, insert_all_liveprops,
                          (request_rec *r, const dav_resource *resource,
                           dav_prop_insert what, apr_text_header *phdr))
 
@@ -687,7 +687,7 @@ typedef enum
 {
     dav_if_etag,
     dav_if_opaquelock,
-    dav_if_unknown /* the "unknown" state type; always matches false. */   
+    dav_if_unknown /* the "unknown" state type; always matches false. */
 } dav_if_state_type;
 
 typedef struct dav_if_state_list
@@ -714,7 +714,7 @@ typedef struct dav_if_header
     int dummy_header;   /* used internally by the lock/etag validation */
 } dav_if_header;
 
-typedef struct dav_locktoken_list 
+typedef struct dav_locktoken_list
 {
     dav_locktoken *locktoken;
     struct dav_locktoken_list *next;
@@ -746,7 +746,7 @@ struct dav_hooks_liveprop
     **      if the property is defined on the resource, then
     **      a DAV:supported-live-property element, as defined
     **      by the DeltaV extensions to RFC2518.
-    **                      
+    **
     ** Providers should return DAV_PROP_INSERT_NOTDEF if the property is
     ** known and not defined for this resource, so should be handled as a
     ** dead property. If a provider recognizes, but does not support, a
@@ -887,7 +887,7 @@ DAV_DECLARE(long) dav_get_liveprop_info(int propid,
                                         const dav_liveprop_spec **info);
 
 /* ### docco */
-DAV_DECLARE(void) dav_register_liveprop_group(apr_pool_t *pool, 
+DAV_DECLARE(void) dav_register_liveprop_group(apr_pool_t *pool,
                                               const dav_liveprop_group *group);
 
 /* ### docco */
@@ -1083,7 +1083,7 @@ struct dav_hooks_propdb
     dav_error * (*map_namespaces)(dav_db *db,
                                   const apr_array_header_t *namespaces,
                                   dav_namespace_map **mapping);
-    
+
     /*
     ** Store a property value for a given name. The value->combined field
     ** MUST be set for this call.
@@ -1258,7 +1258,7 @@ DAV_DECLARE(dav_error *) dav_notify_created(request_rec *r,
                                             int resource_state,
                                             int depth);
 
-DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb, 
+DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb,
                                        const dav_resource *resource,
                                        dav_lock **locks);
 
@@ -1654,7 +1654,7 @@ typedef struct dav_walker_ctx
 
     /* ### client data... phasing out this big glom */
 
-    /* this brigade buffers data being sent to r->output_filters */ 
+    /* this brigade buffers data being sent to r->output_filters */
     apr_bucket_brigade *bb;
 
     /* a scratch pool, used to stream responses and iteratively cleared. */
@@ -1748,7 +1748,7 @@ struct dav_hooks_repository
      *
      * The provider may associate the request storage pool with the resource
      * (in the resource->pool field), to use in other operations on that
-     * resource. 
+     * resource.
      */
     dav_error * (*get_resource)(
         request_rec *r,
@@ -1759,7 +1759,7 @@ struct dav_hooks_repository
     );
 
     /* Get a resource descriptor for the parent of the given resource.
-     * The resources need not exist.  NULL is returned if the resource 
+     * The resources need not exist.  NULL is returned if the resource
      * is the root collection.
      *
      * An error should be returned only if there is a fatal error in
@@ -2417,7 +2417,7 @@ DAV_DECLARE(apr_size_t) dav_get_limit_xml_body(const request_rec *r);
 typedef struct {
     int propid;                          /* live property ID */
     const dav_hooks_liveprop *provider;  /* the provider defining this prop */
-} dav_elem_private;    
+} dav_elem_private;
 
 /* --------------------------------------------------------------------
 **
@@ -2430,19 +2430,39 @@ 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;                              
+
+    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);
+extern DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p,
+                               const char *name,
+                               const dav_options_provider *provider);
+
+/* --------------------------------------------------------------------
+**
+** DAV RESOURCE TYPE HOOKS
+*/
+
+typedef struct dav_resource_type_provider
+{
+    int (*get_resource_type)(const dav_resource *resource,
+                  const char **name,
+                  const char **uri);
+} dav_resource_type_provider;
+
+#define DAV_RESOURCE_TYPE_GROUP "dav_resource_type"
+
+DAV_DECLARE(void) dav_resource_type_provider_register(apr_pool_t *p,
+                                        const char *name,
+                                    const dav_resource_type_provider *provider);
+
+DAV_DECLARE(const dav_resource_type_provider *) dav_get_resource_type_providers(const char *name);
 
 #ifdef __cplusplus
 }
index 96a8fc5e93d64da814b5a102e7f4492964ce452b..44870fd01b50fd47a06f359de35cd38e01d9dee1 100644 (file)
@@ -32,9 +32,9 @@ 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)
+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);
 }
@@ -44,3 +44,15 @@ DAV_DECLARE(const dav_options_provider *) dav_get_options_providers(const char *
     return ap_lookup_provider(DAV_OPTIONS_EXTENSION_GROUP, name, "0");
 }
 
+
+DAV_DECLARE(void) dav_resource_type_provider_register(apr_pool_t *p,
+                          const char *name,
+                          const dav_resource_type_provider *provider)
+{
+    ap_register_provider(p, DAV_RESOURCE_TYPE_GROUP, name, "0", provider);
+}
+
+DAV_DECLARE(const dav_resource_type_provider *) dav_get_resource_type_providers(const char *name)
+{
+    return ap_lookup_provider(DAV_RESOURCE_TYPE_GROUP, name, "0");
+}
index 297b04bdbf078c0f9bde943d9d1f0f278a6ee615..1f79dc712875af4b5fac80e61bc944f813adab21 100644 (file)
@@ -17,6 +17,7 @@
 #include "httpd.h"
 #include "util_xml.h"
 #include "apr_strings.h"
+#include "ap_provider.h"
 
 #include "mod_dav.h"
 
@@ -59,7 +60,7 @@ static dav_prop_insert dav_core_insert_prop(const dav_resource *resource,
                                             int propid, dav_prop_insert what,
                                             apr_text_header *phdr)
 {
-    const char *value;
+    const char *value = NULL;
     const char *s;
     apr_pool_t *p = resource->pool;
     const dav_liveprop_spec *info;
@@ -68,32 +69,63 @@ static dav_prop_insert dav_core_insert_prop(const dav_resource *resource,
     switch (propid)
     {
     case DAV_PROPID_resourcetype:
+        { /* additional type info provided by external modules ? */
+            int i;
+
+            apr_array_header_t *extensions =
+                ap_list_provider_names(p, DAV_RESOURCE_TYPE_GROUP, "0");
+            ap_list_provider_names_t *entry =
+                (ap_list_provider_names_t *)extensions->elts;
+
+            for (i = 0; i < extensions->nelts; i++, entry++) {
+                const dav_resource_type_provider *res_hooks =
+                    dav_get_resource_type_providers(entry->provider_name);
+                const char *name = NULL, *uri = NULL;
+
+                if (!res_hooks || !res_hooks->get_resource_type)
+                    continue;
+
+                if (!res_hooks->get_resource_type(resource, &name, &uri) &&
+            name) {
+
+                    if (!uri || !strcasecmp(uri, "DAV:"))
+                        value = apr_pstrcat(p, value ? value : "",
+                        "<D:", name, "/>", NULL);
+            else
+                        value = apr_pstrcat(p, value ? value : "",
+                        "<x:", name,
+                        " xmlns:x=\"", uri,
+                        "\"/>", NULL);
+                }
+        }
+        }
         switch (resource->type) {
         case DAV_RESOURCE_TYPE_VERSION:
             if (resource->baselined) {
-                value = "<D:baseline/>";
+                value = apr_pstrcat(p, value ? value : "", "<D:baseline/>", NULL);
                 break;
             }
             /* fall through */
         case DAV_RESOURCE_TYPE_REGULAR:
         case DAV_RESOURCE_TYPE_WORKING:
             if (resource->collection) {
-                value = "<D:collection/>";
+                value = apr_pstrcat(p, value ? value : "", "<D:collection/>", NULL);
             }
             else {
                 /* ### should we denote lock-null resources? */
-
+                if (value == NULL) {
                 value = "";        /* becomes: <D:resourcetype/> */
             }
+            }
             break;
         case DAV_RESOURCE_TYPE_HISTORY:
-            value = "<D:version-history/>";
+            value = apr_pstrcat(p, value ? value : "", "<D:version-history/>", NULL);
             break;
         case DAV_RESOURCE_TYPE_WORKSPACE:
-            value = "<D:collection/>";
+            value = apr_pstrcat(p, value ? value : "", "<D:collection/>", NULL);
             break;
         case DAV_RESOURCE_TYPE_ACTIVITY:
-            value = "<D:activity/>";
+            value = apr_pstrcat(p, value ? value : "", "<D:activity/>", NULL);
             break;
 
         default: