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

📄 util.c

📁 Apache 2.0.63 is the current stable version of the 2.0 series, and is recommended over any previous
💻 C
📖 第 1 页 / 共 5 页
字号:
    dav_buffer work_buf = { 0 };
    dav_response *new_response;

#if DAV_DEBUG
    if (depth && response == NULL) {
        /*
        ** ### bleck. we can't return errors for other URIs unless we have
        ** ### a "response" ptr.
        */
        return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "DESIGN ERROR: dav_validate_request called "
                             "with depth>0, but no response ptr.");
    }
#endif

    if (response != NULL)
        *response = NULL;

    /* Do the standard checks for conditional requests using 
     * If-..-Since, If-Match etc */
    if ((result = ap_meets_conditions(r)) != OK) {
        /* ### fix this up... how? */
        return dav_new_error(r->pool, result, 0, NULL);
    }

    /* always parse (and later process) the If: header */
    if ((err = dav_process_if_header(r, &if_header)) != NULL) {
        /* ### maybe add higher-level description */
        return err;
    }

    /* If a locktoken was specified, create a dummy if_header with which
     * to validate resources.  In the interim, figure out why DAV uses
     * locktokens in an if-header without a Lock-Token header to refresh
     * locks, but a Lock-Token header without an if-header to remove them.
     */
    if (locktoken != NULL) {
        dav_if_header *ifhdr_new;

        ifhdr_new = apr_pcalloc(r->pool, sizeof(*ifhdr_new));
        ifhdr_new->uri = resource->uri;
        ifhdr_new->uri_len = strlen(resource->uri);
        ifhdr_new->dummy_header = 1;

        ifhdr_new->state = apr_pcalloc(r->pool, sizeof(*ifhdr_new->state));
        ifhdr_new->state->type = dav_if_opaquelock;
        ifhdr_new->state->condition = DAV_IF_COND_NORMAL;
        ifhdr_new->state->locktoken = locktoken;

        ifhdr_new->next = if_header;
        if_header = ifhdr_new;
    }

    /*
    ** If necessary, open the lock database (read-only, lazily);
    ** the validation process may need to retrieve or update lock info.
    ** Otherwise, assume provided lockdb is valid and opened rw.
    */
    if (lockdb == NULL) {
        if (locks_hooks != NULL) {
            if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, &lockdb)) != NULL) {
                /* ### maybe insert higher-level comment */
                return err;
            }
            lock_db_opened_locally = 1;
        }
    }

    /* (1) Validate the specified resource, at the specified depth */
    if (resource->exists && depth > 0) {
        dav_walker_ctx ctx = { { 0 } };
        dav_response *multi_status;

        ctx.w.walk_type = DAV_WALKTYPE_NORMAL;
        ctx.w.func = dav_validate_walker;
        ctx.w.walk_ctx = &ctx;
        ctx.w.pool = r->pool;
        ctx.w.root = resource;

        ctx.if_header = if_header;
        ctx.r = r;
        ctx.flags = flags;

        if (lockdb != NULL) {
            ctx.w.lockdb = lockdb;
            ctx.w.walk_type |= DAV_WALKTYPE_LOCKNULL;
        }

        err = (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
        if (err == NULL) {
            *response = multi_status;;
        }
        /* else: implies a 5xx status code occurred. */
    }
    else {
        err = dav_validate_resource_state(r->pool, resource, lockdb,
                                          if_header, flags, &work_buf, r);
    }

    /* (2) Validate the parent resource if requested */
    if (err == NULL && (flags & DAV_VALIDATE_PARENT)) {
        dav_resource *parent_resource;

        err = (*repos_hooks->get_parent_resource)(resource, &parent_resource);

        if (err == NULL && parent_resource == NULL) {
            err = dav_new_error(r->pool, HTTP_FORBIDDEN, 0,
                                "Cannot access parent of repository root.");
        }
        else if (err == NULL) {
            err = dav_validate_resource_state(r->pool, parent_resource, lockdb,
                                              if_header,
                                              flags | DAV_VALIDATE_IS_PARENT,
                                              &work_buf, r);
            
            /*
            ** This error occurred on the parent resource. This implies that
            ** we have to create a multistatus response (to report the error
            ** against a URI other than the Request-URI). "Convert" this error
            ** into a multistatus response.
            */
            if (err != NULL) {
                new_response = apr_pcalloc(r->pool, sizeof(*new_response));
                
                new_response->href = parent_resource->uri;
                new_response->status = err->status;
                new_response->desc =
                    "A validation error has occurred on the parent resource, "
                    "preventing the operation on the resource specified by "
                    "the Request-URI.";
                if (err->desc != NULL) {
                    new_response->desc = apr_pstrcat(r->pool,
                                                    new_response->desc,
                                                    " The error was: ",
                                                    err->desc, NULL);
                }
                
                /* assert: DAV_VALIDATE_PARENT implies response != NULL */
                new_response->next = *response;
                *response = new_response;
                
                err = NULL;
            }
        }
    }

    if (lock_db_opened_locally)
        (*locks_hooks->close_lockdb)(lockdb);

    /*
    ** If we don't have a (serious) error, and we have multistatus responses,
    ** then we need to construct an "error". This error will be the overall
    ** status returned, and the multistatus responses will go into its body.
    **
    ** For certain methods, the overall error will be a 424. The default is
    ** to construct a standard 207 response.
    */
    if (err == NULL && response != NULL && *response != NULL) {
        apr_text *propstat = NULL;

        if ((flags & DAV_VALIDATE_USE_424) != 0) {
            /* manufacture a 424 error to hold the multistatus response(s) */
            return dav_new_error(r->pool, HTTP_FAILED_DEPENDENCY, 0,
                                 "An error occurred on another resource, "
                                 "preventing the requested operation on "
                                 "this resource.");
        }

        /*
        ** Whatever caused the error, the Request-URI should have a 424
        ** associated with it since we cannot complete the method.
        **
        ** For a LOCK operation, insert an empty DAV:lockdiscovery property.
        ** For other methods, return a simple 424.
        */
        if ((flags & DAV_VALIDATE_ADD_LD) != 0) {
            propstat = apr_pcalloc(r->pool, sizeof(*propstat));
            propstat->text =
                "<D:propstat>" DEBUG_CR
                "<D:prop><D:lockdiscovery/></D:prop>" DEBUG_CR
                "<D:status>HTTP/1.1 424 Failed Dependency</D:status>" DEBUG_CR
                "</D:propstat>" DEBUG_CR;
        }

        /* create the 424 response */
        new_response = apr_pcalloc(r->pool, sizeof(*new_response));
        new_response->href = resource->uri;
        new_response->status = HTTP_FAILED_DEPENDENCY;
        new_response->propresult.propstats = propstat;
        new_response->desc =
            "An error occurred on another resource, preventing the "
            "requested operation on this resource.";

        new_response->next = *response;
        *response = new_response;

        /* manufacture a 207 error for the multistatus response(s) */
        return dav_new_error(r->pool, HTTP_MULTI_STATUS, 0,
                             "Error(s) occurred on resources during the "
                             "validation process.");
    }

    return err;
}

/* dav_get_locktoken_list:
 *
 * Sets ltl to a locktoken_list of all positive locktokens in header,
 * else NULL if no If-header, or no positive locktokens.
 */
DAV_DECLARE(dav_error *) dav_get_locktoken_list(request_rec *r,
                                                dav_locktoken_list **ltl) 
{
    dav_error *err;
    dav_if_header *if_header;
    dav_if_state_list *if_state;
    dav_locktoken_list *lock_token = NULL;                
        
    *ltl = NULL;

    if ((err = dav_process_if_header(r, &if_header)) != NULL) {
        /* ### add a higher-level description? */
        return err;
    }
                         
    while (if_header != NULL) {
        if_state = if_header->state;        /* Begining of the if_state linked list */
        while (if_state != NULL)        {
            if (if_state->condition == DAV_IF_COND_NORMAL
                && if_state->type == dav_if_opaquelock) {
                lock_token = apr_pcalloc(r->pool, sizeof(dav_locktoken_list));
                lock_token->locktoken = if_state->locktoken;
                lock_token->next = *ltl;
                *ltl = lock_token;
            }
            if_state = if_state->next; 
        }
        if_header = if_header->next;
    }
    if (*ltl == NULL) {
        /* No nodes added */
        return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_ABSENT,
                             "No locktokens were specified in the \"If:\" "
                             "header, so the refresh could not be performed.");
    }

    return NULL;
}

#if 0 /* not needed right now... */

static const char *strip_white(const char *s, apr_pool_t *pool)
{
    apr_size_t idx;

    /* trim leading whitespace */
    while (apr_isspace(*s))     /* assume: return false for '\0' */
        ++s;

    /* trim trailing whitespace */
    idx = strlen(s) - 1;
    if (apr_isspace(s[idx])) {
        char *s2 = apr_pstrdup(pool, s);

        while (apr_isspace(s2[idx]) && idx > 0)
            --idx;
        s2[idx + 1] = '\0';
        return s2;
    }

    return s;
}
#endif

#define DAV_LABEL_HDR "Label"

/* dav_add_vary_header
 *
 * If there were any headers in the request which require a Vary header
 * in the response, add it.
 */
DAV_DECLARE(void) dav_add_vary_header(request_rec *in_req,
                                      request_rec *out_req,
                                      const dav_resource *resource)
{
    const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(in_req);

    /* ### this is probably all wrong... I think there is a function in
       ### the Apache API to add things to the Vary header. need to check */

    /* Only versioning headers require a Vary response header,
     * so only do this check if there is a versioning provider */
    if (vsn_hooks != NULL) {
        const char *target = apr_table_get(in_req->headers_in, DAV_LABEL_HDR);
        const char *vary = apr_table_get(out_req->headers_out, "Vary");

        /* If Target-Selector specified, add it to the Vary header */
        if (target != NULL) {
            if (vary == NULL)
                vary = DAV_LABEL_HDR;
            else
                vary = apr_pstrcat(out_req->pool, vary, "," DAV_LABEL_HDR,
                                   NULL);

            apr_table_setn(out_req->headers_out, "Vary", vary);
        }
    }
}

/* dav_can_auto_checkout
 *
 * Determine whether auto-checkout is enabled for a resource.
 * r - the request_rec
 * resource - the resource
 * auto_version - the value of the auto_versionable hook for the resource
 * lockdb - pointer to lock database (opened if necessary)
 * auto_checkout - set to 1 if auto-checkout enabled
 */
static dav_error * dav_can_auto_checkout(
    request_rec *r,                                         
    dav_resource *resource,
    dav_auto_version auto_version,
    dav_lockdb **lockdb,
    int *auto_checkout)
{
    dav_error *err;
    dav_lock *lock_list;

    *auto_checkout = 0;

    if (auto_version == DAV_AUTO_VERSION_ALWAYS) {
        *auto_checkout = 1;
    }
    else if (auto_version == DAV_AUTO_VERSION_LOCKED) {
        if (*lockdb == NULL) {
            const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r);

            if (locks_hooks == NULL) {
                return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                                     "Auto-checkout is only enabled for locked resources, "
                                     "but there is no lock provider.");
            }

            if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, lockdb)) != NULL) {
                return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                                      "Cannot open lock database to determine "
                                      "auto-versioning behavior.",
                                      e

⌨️ 快捷键说明

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