⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 props.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//*** DAV extension module for Apache 2.0.***  - Property database handling (repository-independent)**** NOTES:****   PROPERTY DATABASE****   This version assumes that there is a per-resource database provider**   to record properties. The database provider decides how and where to**   store these databases.****   The DBM keys for the properties have the following form:****     namespace ":" propname****   For example: 5:author****   The namespace provides an integer index into the namespace table**   (see below). propname is simply the property name, without a namespace**   prefix.****   A special case exists for properties that had a prefix starting with**   "xml". The XML Specification reserves these for future use. mod_dav**   stores and retrieves them unchanged. The keys for these properties**   have the form:****     ":" propname****   The propname will contain the prefix and the property name. For**   example, a key might be ":xmlfoo:name"****   The ":name" style will also be used for properties that do not**   exist within a namespace.****   The DBM values consist of two null-terminated strings, appended**   together (the null-terms are retained and stored in the database).**   The first string is the xml:lang value for the property. An empty**   string signifies that a lang value was not in context for the value.**   The second string is the property value itself.******   NAMESPACE TABLE****   The namespace table is an array that lists each of the namespaces**   that are in use by the properties in the given propdb. Each entry**   in the array is a simple URI.****   For example: http://www.foo.bar/standards/props/****   The prefix used for the property is stripped and the URI for it**   is entered into the namespace table. Also, any namespaces used**   within the property value will be entered into the table (and**   stripped from the child elements).****   The namespaces are stored in the DBM database under the "METADATA" key.******   STRIPPING NAMESPACES****   Within the property values, the namespace declarations (xmlns...)**   are stripped. Each element and attribute will have its prefix removed**   and a new prefix inserted.****   This must be done so that we can return multiple properties in a**   PROPFIND which may have (originally) used conflicting prefixes. For**   that case, we must bind all property value elements to new namespace**   values.****   This implies that clients must NOT be sensitive to the namespace**   prefix used for their properties. It WILL change when the properties**   are returned (we return them as "ns<index>", e.g. "ns5"). Also, the**   property value can contain ONLY XML elements and CDATA. PI and comment**   elements will be stripped. CDATA whitespace will be preserved, but**   whitespace within element tags will be altered. Attribute ordering**   may be altered. Element and CDATA ordering will be preserved.******   ATTRIBUTES ON PROPERTY NAME ELEMENTS****   When getting/setting properties, the XML used looks like:****     <prop>**       <propname1>value</propname1>**       <propname2>value</propname1>**     </prop>****   This implementation (mod_dav) DOES NOT save any attributes that are**   associated with the <propname1> element. The property value is deemed**   to be only the contents ("value" in the above example).****   We do store the xml:lang value (if any) that applies to the context**   of the <propname1> element. Whether the xml:lang attribute is on**   <propname1> itself, or from a higher level element, we will store it**   with the property value.******   VERSIONING****   The DBM db contains a key named "METADATA" that holds database-level**   information, such as the namespace table. The record also contains the**   db's version number as the very first 16-bit value. This first number**   is actually stored as two single bytes: the first byte is a "major"**   version number. The second byte is a "minor" number.****   If the major number is not what mod_dav expects, then the db is closed**   immediately and an error is returned. A minor number change is**   acceptable -- it is presumed that old/new dav_props.c can deal with**   the database format. For example, a newer dav_props might update the**   minor value and append information to the end of the metadata record**   (which would be ignored by previous versions).****** ISSUES:****   At the moment, for the dav_get_allprops() and dav_get_props() functions,**   we must return a set of xmlns: declarations for ALL known namespaces**   in the file. There isn't a way to filter this because we don't know**   which are going to be used or not. Examining property names is not**   sufficient because the property values could use entirely different**   namespaces.****   ==> we must devise a scheme where we can "garbage collect" the namespace**       entries from the property database.*/#include "apr.h"#include "apr_strings.h"#define APR_WANT_STDIO#define APR_WANT_BYTEFUNC#include "apr_want.h"#include "mod_dav.h"#include "http_log.h"#include "http_request.h"/*** There is some rough support for writable DAV:getcontenttype and** DAV:getcontentlanguage properties. If this #define is (1), then** this support is disabled.**** We are disabling it because of a lack of support in GET and PUT** operations. For GET, it would be "expensive" to look for a propdb,** open it, and attempt to extract the Content-Type and Content-Language** values for the response.** (Handling the PUT would not be difficult, though)*/#define DAV_DISABLE_WRITABLE_PROPS     1#define DAV_EMPTY_VALUE                "\0"    /* TWO null terms */struct dav_propdb {    apr_pool_t *p;                /* the pool we should use */    request_rec *r;               /* the request record */    const dav_resource *resource; /* the target resource */    int deferred;                 /* open of db has been deferred */    dav_db *db;                   /* underlying database containing props */    apr_array_header_t *ns_xlate; /* translation of an elem->ns to URI */    dav_namespace_map *mapping;   /* namespace mapping */    dav_lockdb *lockdb;           /* the lock database */    dav_buffer wb_lock;           /* work buffer for lockdiscovery property */    /* if we ever run a GET subreq, it will be stored here */    request_rec *subreq;    /* hooks we should use for processing (based on the target resource) */    const dav_hooks_db *db_hooks;};/* NOTE: dav_core_props[] and the following enum must stay in sync. *//* ### move these into a "core" liveprop provider? */static const char * const dav_core_props[] ={    "getcontenttype",    "getcontentlanguage",    "lockdiscovery",    "supportedlock",    NULL        /* sentinel */};enum {    DAV_PROPID_CORE_getcontenttype = DAV_PROPID_CORE,    DAV_PROPID_CORE_getcontentlanguage,    DAV_PROPID_CORE_lockdiscovery,    DAV_PROPID_CORE_supportedlock,    DAV_PROPID_CORE_UNKNOWN};/*** This structure is used to track information needed for a rollback.*/typedef struct dav_rollback_item {    /* select one of the two rollback context structures based on the       value of dav_prop_ctx.is_liveprop */    dav_deadprop_rollback *deadprop;    dav_liveprop_rollback *liveprop;} dav_rollback_item;static int dav_find_liveprop_provider(dav_propdb *propdb,                                      const char *ns_uri,                                      const char *propname,                                      const dav_hooks_liveprop **provider){    int propid;    *provider = NULL;    if (ns_uri == NULL) {        /* policy: liveprop providers cannot define no-namespace properties */        return DAV_PROPID_CORE_UNKNOWN;    }    /* check liveprop providers first, so they can define core properties */    propid = dav_run_find_liveprop(propdb->resource, ns_uri, propname,                                   provider);    if (propid != 0) {        return propid;    }    /* check for core property */    if (strcmp(ns_uri, "DAV:") == 0) {        const char * const *p = dav_core_props;        for (propid = DAV_PROPID_CORE; *p != NULL; ++p, ++propid)            if (strcmp(propname, *p) == 0) {                return propid;            }    }    /* no provider for this property */    return DAV_PROPID_CORE_UNKNOWN;}static void dav_find_liveprop(dav_propdb *propdb, apr_xml_elem *elem){    const char *ns_uri;    dav_elem_private *priv = elem->priv;    const dav_hooks_liveprop *hooks;    if (elem->ns == APR_XML_NS_NONE)        ns_uri = NULL;    else if (elem->ns == APR_XML_NS_DAV_ID)        ns_uri = "DAV:";    else        ns_uri = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns);    priv->propid = dav_find_liveprop_provider(propdb, ns_uri, elem->name,                                              &hooks);    /* ### this test seems redundant... */    if (priv->propid != DAV_PROPID_CORE_UNKNOWN) {        priv->provider = hooks;    }}/* is the live property read/write? */static int dav_rw_liveprop(dav_propdb *propdb, dav_elem_private *priv){    int propid = priv->propid;    /*    ** Check the liveprop provider (if this is a provider-defined prop)    */    if (priv->provider != NULL) {        return (*priv->provider->is_writable)(propdb->resource, propid);    }    /* these are defined as read-only */    if (propid == DAV_PROPID_CORE_lockdiscovery#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,                                       apr_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);            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -