*/
/**
- * @file mod_dav.h
+ * @file mod_dav.h
* @brief DAV extension module for Apache 2.0.*
*
* @defgroup MOD_DAV mod_dav
#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)
** 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);
** 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);
#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);
**
** (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))
/*
** 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))
{
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
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;
** 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
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 */
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.
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);
/* ### 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. */
*
* 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,
);
/* 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
typedef struct {
int propid; /* live property ID */
const dav_hooks_liveprop *provider; /* the provider defining this prop */
-} dav_elem_private;
+} dav_elem_private;
/* --------------------------------------------------------------------
**
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
}
#include "httpd.h"
#include "util_xml.h"
#include "apr_strings.h"
+#include "ap_provider.h"
#include "mod_dav.h"
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;
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: