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

📄 util.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 5 页
字号:
** The check of parent should be done when it is necessary to verify that** the parent collection will accept a new member (ie current resource** state is null).**** Return OK on successful validation.** On error, return appropriate HTTP_* code, and log error. If a multi-stat** error is necessary, response will point to it, else NULL.*/DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r,                                              dav_resource *resource,                                              int depth,                                              dav_locktoken *locktoken,                                              dav_response **response,                                              int flags,                                              dav_lockdb *lockdb){    dav_error *err;    int result;    dav_if_header *if_header;    int lock_db_opened_locally = 0;    const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r);    const dav_hooks_repository *repos_hooks = resource->hooks;    dav_buffer work_buf = { 0 };    dav_response *new_response;    int resource_state;    const char *etag;    int set_etag = 0;#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;    /* Set the ETag header required by dav_meets_conditions() */    etag = apr_table_get(r->headers_out, "ETag");    if (!etag) {        etag = (*resource->hooks->getetag)(resource);        if (etag && *etag) {            apr_table_set(r->headers_out, "ETag", etag);            set_etag = 1;        }    }    /* Do the standard checks for conditional requests using     * If-..-Since, If-Match etc */    resource_state = dav_get_resource_state(r, resource);    result = dav_meets_conditions(r, resource_state);    if (set_etag) {        /*         * If we have set an ETag to headers out above for         * dav_meets_conditions() revert this here as we do not want to set         * the ETag in responses to requests with methods where this might not         * be desired.         */        apr_table_unset(r->headers_out, "ETag");    }    if (result != OK) {        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) * a

⌨️ 快捷键说明

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