📄 props.c
字号:
}
}
break;
case DAV_PROPID_CORE_supportedlock:
if (propdb->lockdb != NULL) {
value = (*propdb->lockdb->hooks->get_supportedlock)(propdb->resource);
}
break;
case DAV_PROPID_CORE_getcontenttype:
if (propdb->subreq == NULL) {
dav_do_prop_subreq(propdb);
}
if (propdb->subreq->content_type != NULL) {
value = propdb->subreq->content_type;
}
break;
case DAV_PROPID_CORE_getcontentlanguage:
{
const char *lang;
if (propdb->subreq == NULL) {
dav_do_prop_subreq(propdb);
}
if ((lang = apr_table_get(propdb->subreq->headers_out,
"Content-Language")) != NULL) {
value = lang;
}
break;
}
default:
/* fall through to interpret as a dead property */
break;
}
/* if something was supplied, then insert it */
if (value != NULL) {
const char *s;
if (what == DAV_PROP_INSERT_SUPPORTED) {
/* use D: prefix to refer to the DAV: namespace URI,
* and let the namespace attribute default to "DAV:"
*/
s = apr_psprintf(propdb->p,
"<D:supported-live-property D:name=\"%s\"/>" DEBUG_CR,
name);
}
else if (what == DAV_PROP_INSERT_VALUE && *value != '\0') {
/* use D: prefix to refer to the DAV: namespace URI */
s = apr_psprintf(propdb->p, "<D:%s>%s</D:%s>" DEBUG_CR,
name, value, name);
}
else {
/* use D: prefix to refer to the DAV: namespace URI */
s = apr_psprintf(propdb->p, "<D:%s/>" DEBUG_CR, name);
}
apr_text_append(propdb->p, phdr, s);
*inserted = what;
}
return NULL;
}
static dav_error * dav_insert_liveprop(dav_propdb *propdb,
const apr_xml_elem *elem,
dav_prop_insert what,
apr_text_header *phdr,
dav_prop_insert *inserted)
{
dav_elem_private *priv = elem->priv;
*inserted = DAV_PROP_INSERT_NOTDEF;
if (priv->provider == NULL) {
/* this is a "core" property that we define */
return dav_insert_coreprop(propdb, priv->propid, elem->name,
what, phdr, inserted);
}
/* ask the provider (that defined this prop) to insert the prop */
*inserted = (*priv->provider->insert_prop)(propdb->resource, priv->propid,
what, phdr);
return NULL;
}
static void dav_output_prop_name(apr_pool_t *pool,
const dav_prop_name *name,
dav_xmlns_info *xi,
apr_text_header *phdr)
{
const char *s;
if (*name->ns == '\0')
s = apr_psprintf(pool, "<%s/>" DEBUG_CR, name->name);
else {
const char *prefix = dav_xmlns_add_uri(xi, name->ns);
s = apr_psprintf(pool, "<%s:%s/>" DEBUG_CR, prefix, name->name);
}
apr_text_append(pool, phdr, s);
}
static void dav_insert_xmlns(apr_pool_t *p, const char *pre_prefix, int ns,
const char *ns_uri, apr_text_header *phdr)
{
const char *s;
s = apr_psprintf(p, " xmlns:%s%d=\"%s\"", pre_prefix, ns, ns_uri);
apr_text_append(p, phdr, s);
}
static dav_error *dav_really_open_db(dav_propdb *propdb, int ro)
{
dav_error *err;
/* we're trying to open the db; turn off the 'deferred' flag */
propdb->deferred = 0;
/* ask the DB provider to open the thing */
err = (*propdb->db_hooks->open)(propdb->p, propdb->resource, ro,
&propdb->db);
if (err != NULL) {
return dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
DAV_ERR_PROP_OPENING,
"Could not open the property database.",
err);
}
/*
** NOTE: propdb->db could be NULL if we attempted to open a readonly
** database that doesn't exist. If we require read/write
** access, then a database was created and opened.
*/
return NULL;
}
DAV_DECLARE(dav_error *)dav_open_propdb(request_rec *r, dav_lockdb *lockdb,
const dav_resource *resource,
int ro,
apr_array_header_t * ns_xlate,
dav_propdb **p_propdb)
{
dav_propdb *propdb = apr_pcalloc(r->pool, sizeof(*propdb));
*p_propdb = NULL;
#if DAV_DEBUG
if (resource->uri == NULL) {
return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
"INTERNAL DESIGN ERROR: resource must define "
"its URI.");
}
#endif
propdb->r = r;
propdb->p = r->pool; /* ### get rid of this */
propdb->resource = resource;
propdb->ns_xlate = ns_xlate;
propdb->db_hooks = DAV_GET_HOOKS_PROPDB(r);
propdb->lockdb = lockdb;
/* always defer actual open, to avoid expense of accessing db
* when only live properties are involved
*/
propdb->deferred = 1;
/* ### what to do about closing the propdb on server failure? */
*p_propdb = propdb;
return NULL;
}
DAV_DECLARE(void) dav_close_propdb(dav_propdb *propdb)
{
if (propdb->db == NULL)
return;
(*propdb->db_hooks->close)(propdb->db);
}
DAV_DECLARE(dav_get_props_result) dav_get_allprops(dav_propdb *propdb,
dav_prop_insert what)
{
const dav_hooks_db *db_hooks = propdb->db_hooks;
apr_text_header hdr = { 0 };
apr_text_header hdr_ns = { 0 };
dav_get_props_result result = { 0 };
int found_contenttype = 0;
int found_contentlang = 0;
dav_prop_insert unused_inserted;
/* if not just getting supported live properties,
* scan all properties in the dead prop database
*/
if (what != DAV_PROP_INSERT_SUPPORTED) {
if (propdb->deferred) {
/* ### what to do with db open error? */
(void) dav_really_open_db(propdb, 1 /*ro*/);
}
/* initialize the result with some start tags... */
apr_text_append(propdb->p, &hdr,
"<D:propstat>" DEBUG_CR
"<D:prop>" DEBUG_CR);
/* if there ARE properties, then scan them */
if (propdb->db != NULL) {
dav_xmlns_info *xi = dav_xmlns_create(propdb->p);
dav_prop_name name;
/* define (up front) any namespaces the db might need */
(void) (*db_hooks->define_namespaces)(propdb->db, xi);
/* get the first property name, beginning the scan */
(void) (*db_hooks->first_name)(propdb->db, &name);
while (name.ns != NULL) {
/*
** We also look for <DAV:getcontenttype> and
** <DAV:getcontentlanguage>. If they are not stored as dead
** properties, then we need to perform a subrequest to get
** their values (if any).
*/
if (*name.ns == 'D' && strcmp(name.ns, "DAV:") == 0
&& *name.name == 'g') {
if (strcmp(name.name, "getcontenttype") == 0) {
found_contenttype = 1;
}
else if (strcmp(name.name, "getcontentlanguage") == 0) {
found_contentlang = 1;
}
}
if (what == DAV_PROP_INSERT_VALUE) {
dav_error *err;
int found;
if ((err = (*db_hooks->output_value)(propdb->db, &name,
xi, &hdr,
&found)) != NULL) {
/* ### anything better to do? */
/* ### probably should enter a 500 error */
goto next_key;
}
/* assert: found == 1 */
}
else {
/* the value was not requested, so just add an empty
tag specifying the property name. */
dav_output_prop_name(propdb->p, &name, xi, &hdr);
}
next_key:
(void) (*db_hooks->next_name)(propdb->db, &name);
}
/* all namespaces have been entered into xi. generate them into
the output now. */
dav_xmlns_generate(xi, &hdr_ns);
} /* propdb->db != NULL */
/* add namespaces for all the liveprop providers */
dav_add_all_liveprop_xmlns(propdb->p, &hdr_ns);
}
/* ask the liveprop providers to insert their properties */
dav_run_insert_all_liveprops(propdb->r, propdb->resource, what, &hdr);
/* insert the standard properties */
/* ### should be handling the return errors here */
(void)dav_insert_coreprop(propdb,
DAV_PROPID_CORE_supportedlock, "supportedlock",
what, &hdr, &unused_inserted);
(void)dav_insert_coreprop(propdb,
DAV_PROPID_CORE_lockdiscovery, "lockdiscovery",
what, &hdr, &unused_inserted);
/* if we didn't find these, then do the whole subreq thing. */
if (!found_contenttype) {
/* ### should be handling the return error here */
(void)dav_insert_coreprop(propdb,
DAV_PROPID_CORE_getcontenttype,
"getcontenttype",
what, &hdr, &unused_inserted);
}
if (!found_contentlang) {
/* ### should be handling the return error here */
(void)dav_insert_coreprop(propdb,
DAV_PROPID_CORE_getcontentlanguage,
"getcontentlanguage",
what, &hdr, &unused_inserted);
}
/* if not just reporting on supported live props,
* terminate the result */
if (what != DAV_PROP_INSERT_SUPPORTED) {
apr_text_append(propdb->p, &hdr,
"</D:prop>" DEBUG_CR
"<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
"</D:propstat>" DEBUG_CR);
}
result.propstats = hdr.first;
result.xmlns = hdr_ns.first;
return result;
}
DAV_DECLARE(dav_get_props_result) dav_get_props(dav_propdb *propdb,
apr_xml_doc *doc)
{
const dav_hooks_db *db_hooks = propdb->db_hooks;
apr_xml_elem *elem = dav_find_child(doc->root, "prop");
apr_text_header hdr_good = { 0 };
apr_text_header hdr_bad = { 0 };
apr_text_header hdr_ns = { 0 };
int have_good = 0;
dav_get_props_result result = { 0 };
char *marks_liveprop;
dav_xmlns_info *xi;
int xi_filled = 0;
/* ### NOTE: we should pass in TWO buffers -- one for keys, one for
the marks */
/* we will ALWAYS provide a "good" result, even if it is EMPTY */
apr_text_append(propdb->p, &hdr_good,
"<D:propstat>" DEBUG_CR
"<D:prop>" DEBUG_CR);
/* ### the marks should be in a buffer! */
/* allocate zeroed-memory for the marks. These marks indicate which
liveprop namespaces we've generated into the output xmlns buffer */
/* same for the liveprops */
marks_liveprop = apr_pcalloc(propdb->p, dav_get_liveprop_ns_count() + 1);
xi = dav_xmlns_create(propdb->p);
for (elem = elem->first_child; elem; elem = elem->next) {
dav_elem_private *priv;
dav_error *err;
dav_prop_insert inserted;
dav_prop_name name;
/*
** First try live property providers; if they don't handle
** the property, then try looking it up in the propdb.
*/
if (elem->priv == NULL) {
elem->priv = apr_pcalloc(propdb->p, sizeof(*priv));
}
priv = elem->priv;
/* cache the propid; dav_get_props() could be called many times */
if (priv->propid == 0)
dav_find_liveprop(propdb, elem);
if (priv->propid != DAV_PROPID_CORE_UNKNOWN) {
/* insert the property. returns 1 if an insertion was done. */
if ((err = dav_insert_liveprop(propdb, elem, DAV_PROP_INSERT_VALUE,
&hdr_good, &inserted)) != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -