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

📄 util.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 4 页
字号:
	uri = pbuf->buf;    }    /* get the resource's etag; we may need it during the checks */    etag = (*resource->hooks->getetag)(resource);    /* how many state_lists apply to this URI? */    num_that_apply = 0;    /* If there are if-headers, fail if this resource     * does not match at least one state_list.     */    for (ifhdr_scan = if_header;	 ifhdr_scan != NULL;	 ifhdr_scan = ifhdr_scan->next) {	/* DBG2("uri=<%s>  if_uri=<%s>", uri, ifhdr_scan->uri ? ifhdr_scan->uri : "(no uri)"); */	if (ifhdr_scan->uri != NULL	    && (uri_len != ifhdr_scan->uri_len		|| memcmp(uri, ifhdr_scan->uri, uri_len) != 0)) {	    /*	    ** A tagged-list's URI doesn't match this resource's URI.	    ** Skip to the next state_list to see if it will match.	    */	    continue;	}	/* this state_list applies to this resource */	/*	** ### only one state_list should ever apply! a no-tag, or a tagged	** ### where S9.4.2 states only one can match.	**	** ### revamp this code to loop thru ifhdr_scan until we find the	** ### matching state_list. process it. stop.	*/	++num_that_apply;	/* To succeed, resource must match *all* of the states	 * specified in the state_list.	 */	for (state_list = ifhdr_scan->state;	     state_list != NULL;	     state_list = state_list->next) {	    switch(state_list->type) {	    case dav_if_etag:	    {		int mismatch = strcmp(state_list->etag, etag);		if (state_list->condition == DAV_IF_COND_NORMAL && mismatch) {		    /*		    ** The specified entity-tag does not match the		    ** entity-tag on the resource. This state_list is		    ** not going to match. Bust outta here.		    */		    reason =			"an entity-tag was specified, but the resource's "			"actual ETag does not match.";		    goto state_list_failed;		}		else if (state_list->condition == DAV_IF_COND_NOT			 && !mismatch) {		    /*		    ** The specified entity-tag DOES match the		    ** entity-tag on the resource. This state_list is		    ** not going to match. Bust outta here.		    */		    reason =			"an entity-tag was specified using the \"Not\" form, "			"but the resource's actual ETag matches the provided "			"entity-tag.";		    goto state_list_failed;		}		break;	    }	    case dav_if_opaquelock:		if (lockdb == NULL) {		    if (state_list->condition == DAV_IF_COND_NOT) {			/* the locktoken is definitely not there! (success) */			continue;		    }		    /* condition == DAV_IF_COND_NORMAL */		    /*		    ** If no lockdb is provided, then validation fails for		    ** this state_list (NORMAL means we were supposed to		    ** find the token, which we obviously cannot do without		    ** a lock database).		    **		    ** Go and try the next state list.		    */		    reason =			"a State-token was supplied, but a lock database "			"is not available for to provide the required lock.";		    goto state_list_failed;		}		/* Resource validation 'fails' if:		 *    ANY  of the lock->locktokens match		 *         a NOT state_list->locktoken,		 * OR		 *    NONE of the lock->locktokens match		 *         a NORMAL state_list->locktoken.		 */		num_matched = 0;		for (lock = lock_list; lock != NULL; lock = lock->next) {		    /*		    DBG2("compare: rsrc=%s  ifhdr=%s",			 (*locks_hooks->format_locktoken)(p, lock->locktoken),			 (*locks_hooks->format_locktoken)(p, state_list->locktoken));		    */		    /* nothing to do if the locktokens do not match. */		    if ((*locks_hooks->compare_locktoken)(state_list->locktoken, lock->locktoken)) {			continue;		    }		    /*		    ** We have now matched up one of the resource's locktokens		    ** to a locktoken in a State-token in the If: header.		    ** Note this fact, so that we can pass the overall		    ** requirement of seeing at least one of the resource's		    ** locktokens.		    */		    seen_locktoken = 1;		    if (state_list->condition == DAV_IF_COND_NOT) {			/*			** This state requires that the specified locktoken			** is NOT present on the resource. But we just found			** it. There is no way this state-list can now			** succeed, so go try another one.			*/			reason =			    "a State-token was supplied, which used a "			    "\"Not\" condition. The State-token was found "			    "in the locks on this resource";			goto state_list_failed;		    }		    /* condition == DAV_IF_COND_NORMAL */                    /* Validate auth_user:  If an authenticated user created                    ** the lock, only the same user may submit that locktoken                    ** to manipulate a resource.                    */                    if (lock->auth_user &&                         (!r->user ||                         strcmp(lock->auth_user, r->user))) {                        const char *errmsg;                        errmsg = apr_pstrcat(p, "User \"",                                            r->user,                                             "\" submitted a locktoken created "                                            "by user \"",                                            lock->auth_user, "\".", NULL);                        return dav_new_error(p, HTTP_UNAUTHORIZED, 0, errmsg);                    }		    /*		    ** We just matched a specified State-Token to one of the		    ** resource's locktokens.		    **		    ** Break out of the lock scan -- we only needed to find		    ** one match (actually, there shouldn't be any other		    ** matches in the lock list).		    */		    num_matched = 1;		    break;		}		if (num_matched == 0		    && state_list->condition == DAV_IF_COND_NORMAL) {		    /*		    ** We had a NORMAL state, meaning that we should have		    ** found the State-Token within the locks on this		    ** resource. We didn't, so this state_list must fail.		    */		    reason =			"a State-token was supplied, but it was not found "			"in the locks on this resource.";		    goto state_list_failed;		}		break;	    } /* switch */	} /* foreach ( state_list ) */	/*	** We've checked every state in this state_list and none of them	** have failed. Since all of them succeeded, then we have a matching	** state list and we may be done.	**	** The next requirement is that we have seen one of the resource's	** locktokens (if any). If we have, then we can just exit. If we	** haven't, then we need to keep looking.	*/	if (seen_locktoken) {	    /* woo hoo! */	    return NULL;	}	/*	** Haven't seen one. Let's break out of the search and just look	** for a matching locktoken.	*/	break;	/*	** This label is used when we detect that a state_list is not	** going to match this resource. We bust out and try the next	** state_list.	*/      state_list_failed:	;    } /* foreach ( ifhdr_scan ) */    /*    ** The above loop exits for one of two reasons:    **   1) a state_list matched and seen_locktoken is false.    **   2) all if_header structures were scanned, without (1) occurring    */    if (ifhdr_scan == NULL) {	/*	** We finished the loop without finding any matching state lists.	*/	/*	** If none of the state_lists apply to this resource, then we	** may have succeeded. Note that this scenario implies a	** tagged-list with no matching state_lists. If the If: header	** was a no-tag-list, then it would have applied to this resource.	**	** S9.4.2 states that when no state_lists apply, then the header	** should be ignored.	**	** If we saw one of the resource's locktokens, then we're done.	** If we did not see a locktoken, then we fail.	*/	if (num_that_apply == 0) {	    if (seen_locktoken)		return NULL;	    /*	    ** We may have aborted the scan before seeing the locktoken.	    ** Rescan the If: header to see if we can find the locktoken	    ** somewhere.            **            ** Note that seen_locktoken == 0 implies lock_list != NULL            ** which implies locks_hooks != NULL.	    */	    if (dav_find_submitted_locktoken(if_header, lock_list,					     locks_hooks)) {		/*		** We found a match! We're set... none of the If: header		** assertions apply (implicit success), and the If: header		** specified the locktoken somewhere. We're done.		*/		return NULL;	    }	    return dav_new_error(p, HTTP_LOCKED, 0 /* error_id */,				 "This resource is locked and the \"If:\" "				 "header did not specify one of the "				 "locktokens for this resource's lock(s).");	}	/* else: one or more state_lists were applicable, but failed. */	/*	** If the dummy_header did not match, then they specified an	** incorrect token in the Lock-Token header. Forget whether the	** If: statement matched or not... we'll tell them about the	** bad Lock-Token first. That is considered a 400 (Bad Request).	*/	if (if_header->dummy_header) {	    return dav_new_error(p, HTTP_BAD_REQUEST, 0,				 "The locktoken specified in the "				 "\"Lock-Token:\" header did not specify one "				 "of this resource's locktoken(s).");	}	if (reason == NULL) {	    return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0,				 "The preconditions specified by the \"If:\" "				 "header did not match this resource.");	}	return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0,			     apr_psprintf(p,					 "The precondition(s) specified by "					 "the \"If:\" header did not match "					 "this resource. At least one "					 "failure is because: %s", reason));    }    /* assert seen_locktoken == 0 */    /*    ** ifhdr_scan != NULL implies we found a matching state_list.    **    ** Since we're still here, it also means that we have not yet found    ** one the resource's locktokens in the If: header.    **    ** Scan all the if_headers and states looking for one of this    ** resource's locktokens. Note that we need to go back and scan them    ** all -- we may have aborted a scan with a failure before we saw a    ** matching token.    **    ** Note that seen_locktoken == 0 implies lock_list != NULL which implies    ** locks_hooks != NULL.    */    if (dav_find_submitted_locktoken(if_header, lock_list, locks_hooks)) {	/*	** We found a match! We're set... we have a matching state list,	** and the If: header specified the locktoken somewhere. We're done.	*/	return NULL;    }    /*    ** We had a matching state list, but the user agent did not specify one    ** of this resource's locktokens. Tell them so.    **    ** Note that we need to special-case the message on whether a "dummy"    ** header exists. If it exists, yet we didn't see a needed locktoken,    ** then that implies the dummy header (Lock-Token header) did NOT    ** specify one of this resource's locktokens. (this implies something    ** in the real If: header matched)    **    ** We want to note the 400 (Bad Request) in favor of a 423 (Locked).    */    if (if_header->dummy_header) {	return dav_new_error(p, HTTP_BAD_REQUEST, 0,			     "The locktoken specified in the "			     "\"Lock-Token:\" header did not specify one "			     "of this resource's locktoken(s).");    }    return dav_new_error(p, HTTP_LOCKED, 1 /* error_id */,			 "This resource is locked and the \"If:\" header "			 "did not specify one of the "			 "locktokens for this resource's lock(s).");}/* dav_validate_walker:  Walker callback function to validate resource state */static dav_error * dav_validate_walker(dav_walk_resource *wres, int calltype){    dav_walker_ctx *ctx = wres->walk_ctx;    dav_error *err;    if ((err = dav_validate_resource_state(ctx->w.pool, wres->resource,					   ctx->w.lockdb,					   ctx->if_header, ctx->flags,					   &ctx->work_buf, ctx->r)) == NULL) {	/* There was no error, so just bug out. */	return NULL;    }    /*    ** If we have a serious server error, or if the request itself failed,    ** then just return error (not a multistatus).    */    if (ap_is_HTTP_SERVER_ERROR(err->status)        || (*wres->resource->hooks->is_same_resource)(wres->resource,                                                      ctx->w.root)) {	/* ### maybe push a higher-level description? */	return err;    }    /* associate the error with the current URI */    dav_add_response(wres, err->status, NULL);    return NULL;}/*** dav_validate_request:  Validate if-headers (and check for locks) on:**    (1) r->filename @ depth;**    (2) Parent of r->filename if check_parent == 1**** 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_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;#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;

⌨️ 快捷键说明

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