📄 props.c
字号:
#if DAV_DISABLE_WRITABLE_PROPS || propid == DAV_PROPID_CORE_getcontenttype || propid == DAV_PROPID_CORE_getcontentlanguage#endif || propid == DAV_PROPID_CORE_supportedlock ) { return 0; } /* these are defined as read/write */ if (propid == DAV_PROPID_CORE_getcontenttype || propid == DAV_PROPID_CORE_getcontentlanguage || propid == DAV_PROPID_CORE_UNKNOWN) { return 1; } /* ** We don't recognize the property, so it must be dead (and writable) */ return 1;}/* do a sub-request to fetch properties for the target resource's URI. */static void dav_do_prop_subreq(dav_propdb *propdb){ /* perform a "GET" on the resource's URI (note that the resource may not correspond to the current request!). */ propdb->subreq = ap_sub_req_lookup_uri(propdb->resource->uri, propdb->r, NULL);}static dav_error * dav_insert_coreprop(dav_propdb *propdb, int propid, const char *name, dav_prop_insert what, ap_text_header *phdr, dav_prop_insert *inserted){ const char *value = NULL; dav_error *err; *inserted = DAV_PROP_INSERT_NOTDEF; /* fast-path the common case */ if (propid == DAV_PROPID_CORE_UNKNOWN) return NULL; switch (propid) { case DAV_PROPID_CORE_lockdiscovery: if (propdb->lockdb != NULL) { dav_lock *locks; if ((err = dav_lock_query(propdb->lockdb, propdb->resource, &locks)) != NULL) { return dav_push_error(propdb->p, err->status, 0, "DAV:lockdiscovery could not be " "determined due to a problem fetching " "the locks for this resource.", err); } /* fast-path the no-locks case */ if (locks == NULL) { value = ""; } else { /* ** This may modify the buffer. value may point to ** wb_lock.pbuf or a string constant. */ value = dav_lock_get_activelock(propdb->r, locks, &propdb->wb_lock); /* make a copy to isolate it from changes to wb_lock */ value = apr_pstrdup(propdb->p, propdb->wb_lock.buf); } } 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); } ap_text_append(propdb->p, phdr, s); *inserted = what; } return NULL;}static dav_error * dav_insert_liveprop(dav_propdb *propdb, const ap_xml_elem *elem, dav_prop_insert what, ap_text_header *phdr, dav_prop_insert *inserted){ dav_elem_private *priv = elem->private; *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_append_prop(dav_propdb *propdb, const char *name, const char *value, ap_text_header *phdr){ const char *s; const char *lang = value; /* skip past the xml:lang value */ value += strlen(lang) + 1; if (*value == '\0') { /* the property is an empty value */ if (*name == ':') { /* "no namespace" case */ s = apr_psprintf(propdb->p, "<%s/>" DEBUG_CR, name+1); } else { s = apr_psprintf(propdb->p, "<ns%s/>" DEBUG_CR, name); } } else if (*lang != '\0') { if (*name == ':') { /* "no namespace" case */ s = apr_psprintf(propdb->p, "<%s xml:lang=\"%s\">%s</%s>" DEBUG_CR, name+1, lang, value, name+1); } else { s = apr_psprintf(propdb->p, "<ns%s xml:lang=\"%s\">%s</ns%s>" DEBUG_CR, name, lang, value, name); } } else if (*name == ':') { /* "no namespace" case */ s = apr_psprintf(propdb->p, "<%s>%s</%s>" DEBUG_CR, name+1, value, name+1); } else { s = apr_psprintf(propdb->p, "<ns%s>%s</ns%s>" DEBUG_CR, name, value, name); } ap_text_append(propdb->p, phdr, s);}/*** Prepare the ns_map variable in the propdb structure. This entails copying** all URIs from the "input" namespace list (in propdb->ns_xlate) into the** propdb's list of namespaces. As each URI is copied (or pre-existing** URI looked up), the index mapping is stored into the ns_map variable.**** Note: we must copy all declared namespaces because we cannot easily** determine which input namespaces were actually used within the property** values that are being stored within the propdb. Theoretically, we can** determine this at the point where we serialize the property values** back into strings. This would require a bit more work, and will be** left to future optimizations.**** ### we should always initialize the propdb namespace array with "DAV:"** ### since we know it will be entered anyhow (by virtue of it always** ### occurring in the ns_xlate array). That will allow us to use** ### AP_XML_NS_DAV_ID for propdb ns values, too.*/static void dav_prep_ns_map(dav_propdb *propdb, int add_ns){ int i; const char **puri; const int orig_count = propdb->ns_count; int *pmap; int updating = 0; /* are we updating an existing ns_map? */ if (propdb->ns_map) { if (add_ns && propdb->incomplete_map) { /* we must revisit the map and insert new entries */ updating = 1; propdb->incomplete_map = 0; } else { /* nothing to do: we have a proper ns_map */ return; } } else { propdb->ns_map = apr_palloc(propdb->p, propdb->ns_xlate->nelts * sizeof(*propdb->ns_map)); } pmap = propdb->ns_map; /* ### stupid O(n * orig_count) algorithm */ for (i = propdb->ns_xlate->nelts, puri = (const char **)propdb->ns_xlate->elts; i-- > 0; ++puri, ++pmap) { const char *uri = *puri; const size_t uri_len = strlen(uri); if (updating) { /* updating an existing mapping... we can skip a lot of stuff */ if (*pmap != AP_XML_NS_ERROR_NOT_FOUND) { /* This entry has been filled in, so we can skip it */ continue; } } else { int j; size_t len; const char *p; /* ** GIVEN: uri (a namespace URI from the request input) ** ** FIND: an equivalent URI in the propdb namespace table */ /* only scan original entries (we may have added some in here) */ for (p = propdb->ns_table.buf + sizeof(dav_propdb_metadata), j = 0; j < orig_count; ++j, p += len + 1) { len = strlen(p); if (uri_len != len) continue; if (memcmp(uri, p, len) == 0) { *pmap = j; goto next_input_uri; } } if (!add_ns) { *pmap = AP_XML_NS_ERROR_NOT_FOUND; /* ** This flag indicates that we have an ns_map with missing ** entries. If dav_prep_ns_map() is called with add_ns==1 AND ** this flag is set, then we zip thru the array and add those ** URIs (effectively updating the ns_map as if add_ns=1 was ** passed when the initial prep was called). */ propdb->incomplete_map = 1; continue; } } /* ** The input URI was not found in the propdb namespace table, and ** we are supposed to add it. Append it to the table and store ** the index into the ns_map. */ dav_check_bufsize(propdb->p, &propdb->ns_table, uri_len + 1); memcpy(propdb->ns_table.buf + propdb->ns_table.cur_len, uri, uri_len + 1); propdb->ns_table.cur_len += uri_len + 1; propdb->ns_table_dirty = 1; *pmap = propdb->ns_count++; next_input_uri: ; }}/* find the "DAV:" namespace in our table and return its ID. */static int dav_find_dav_id(dav_propdb *propdb){ const char *p = propdb->ns_table.buf + sizeof(dav_propdb_metadata); int ns; for (ns = 0; ns < propdb->ns_count; ++ns) { size_t len = strlen(p); if (len == 4 && memcmp(p, "DAV:", 5) == 0) return ns; p += len + 1; } /* the "DAV:" namespace is not present */ return -1;}static void dav_insert_xmlns(apr_pool_t *p, const char *pre_prefix, int ns, const char *ns_uri, ap_text_header *phdr){ const char *s; s = apr_psprintf(p, " xmlns:%s%d=\"%s\"", pre_prefix, ns, ns_uri); ap_text_append(p, phdr, s);}/* return all known namespaces (in this propdb) */static void dav_get_propdb_xmlns(dav_propdb *propdb, ap_text_header *phdr){ int i; const char *p = propdb->ns_table.buf + sizeof(dav_propdb_metadata); size_t len; /* note: ns_count == 0 when we have no propdb file */ for (i = 0; i < propdb->ns_count; ++i, p += len + 1) { len = strlen(p); dav_insert_xmlns(propdb->p, "ns", i, p, phdr); }}/* add a namespace decl from one of the namespace tables */static void dav_add_marked_xmlns(dav_propdb *propdb, char *marks, int ns, apr_array_header_t *ns_table, const char *pre_prefix, ap_text_header *phdr){ if (marks[ns]) return; marks[ns] = 1; dav_insert_xmlns(propdb->p, pre_prefix, ns, AP_XML_GET_URI_ITEM(ns_table, ns), phdr);}/*** Internal function to build a key**** WARNING: returns a pointer to a "static" buffer holding the key. The** value must be copied or no longer used if this function is** called again.*/static dav_datum dav_gdbm_key(dav_propdb *propdb, const ap_xml_elem *elem){ int ns; char nsbuf[20]; size_t l_ns;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -