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

📄 props.c

📁 Apache 2.0.63 is the current stable version of the 2.0 series, and is recommended over any previous
💻 C
📖 第 1 页 / 共 3 页
字号:
            }
        }
        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 + -