📄 util.c
字号:
for (scan = child->following_cdata.first; scan != NULL; scan = scan->next) { tlen = strlen(scan->text); memcpy(s, scan->text, tlen); s += tlen; } } *s = '\0'; if (strip_white) { /* trim leading whitespace */ while (apr_isspace(*cdata)) /* assume: return false for '\0' */ ++cdata; /* trim trailing whitespace */ while (len-- > 0 && apr_isspace(cdata[len])) continue; cdata[len + 1] = '\0'; } return cdata;}DAV_DECLARE(dav_xmlns_info *) dav_xmlns_create(apr_pool_t *pool){ dav_xmlns_info *xi = apr_pcalloc(pool, sizeof(*xi)); xi->pool = pool; xi->uri_prefix = apr_hash_make(pool); xi->prefix_uri = apr_hash_make(pool); return xi;}DAV_DECLARE(void) dav_xmlns_add(dav_xmlns_info *xi, const char *prefix, const char *uri){ /* this "should" not overwrite a prefix mapping */ apr_hash_set(xi->prefix_uri, prefix, APR_HASH_KEY_STRING, uri); /* note: this may overwrite an existing URI->prefix mapping, but it doesn't matter -- any prefix is usuable to specify the URI. */ apr_hash_set(xi->uri_prefix, uri, APR_HASH_KEY_STRING, prefix);}DAV_DECLARE(const char *) dav_xmlns_add_uri(dav_xmlns_info *xi, const char *uri){ const char *prefix; if ((prefix = apr_hash_get(xi->uri_prefix, uri, APR_HASH_KEY_STRING)) != NULL) return prefix; prefix = apr_psprintf(xi->pool, "g%d", xi->count++); dav_xmlns_add(xi, prefix, uri); return prefix;}DAV_DECLARE(const char *) dav_xmlns_get_uri(dav_xmlns_info *xi, const char *prefix){ return apr_hash_get(xi->prefix_uri, prefix, APR_HASH_KEY_STRING);}DAV_DECLARE(const char *) dav_xmlns_get_prefix(dav_xmlns_info *xi, const char *uri){ return apr_hash_get(xi->uri_prefix, uri, APR_HASH_KEY_STRING);}DAV_DECLARE(void) dav_xmlns_generate(dav_xmlns_info *xi, apr_text_header *phdr){ apr_hash_index_t *hi = apr_hash_first(xi->pool, xi->prefix_uri); for (; hi != NULL; hi = apr_hash_next(hi)) { const void *prefix; void *uri; const char *s; apr_hash_this(hi, &prefix, NULL, &uri); s = apr_psprintf(xi->pool, " xmlns:%s=\"%s\"", (const char *)prefix, (const char *)uri); apr_text_append(xi->pool, phdr, s); }}/* ---------------------------------------------------------------**** Timeout header processing***//* dav_get_timeout: If the Timeout: header exists, return a time_t * when this lock is expected to expire. Otherwise, return * a time_t of DAV_TIMEOUT_INFINITE. * * It's unclear if DAV clients are required to understand * Seconds-xxx and Infinity time values. We assume that they do. * In addition, for now, that's all we understand, too. */DAV_DECLARE(time_t) dav_get_timeout(request_rec *r){ time_t now, expires = DAV_TIMEOUT_INFINITE; const char *timeout_const = apr_table_get(r->headers_in, "Timeout"); const char *timeout = apr_pstrdup(r->pool, timeout_const), *val; if (timeout == NULL) return DAV_TIMEOUT_INFINITE; /* Use the first thing we understand, or infinity if * we don't understand anything. */ while ((val = ap_getword_white(r->pool, &timeout)) && strlen(val)) { if (!strncmp(val, "Infinite", 8)) { return DAV_TIMEOUT_INFINITE; } if (!strncmp(val, "Second-", 7)) { val += 7; /* ### We need to handle overflow better: * ### timeout will be <= 2^32 - 1 */ expires = atol(val); now = time(NULL); return now + expires; } } return DAV_TIMEOUT_INFINITE;}/* ---------------------------------------------------------------**** If Header processing***//* add_if_resource returns a new if_header, linking it to next_ih. */static dav_if_header *dav_add_if_resource(apr_pool_t *p, dav_if_header *next_ih, const char *uri, apr_size_t uri_len){ dav_if_header *ih; if ((ih = apr_pcalloc(p, sizeof(*ih))) == NULL) return NULL; ih->uri = uri; ih->uri_len = uri_len; ih->next = next_ih; return ih;}/* add_if_state adds a condition to an if_header. */static dav_error * dav_add_if_state(apr_pool_t *p, dav_if_header *ih, const char *state_token, dav_if_state_type t, int condition, const dav_hooks_locks *locks_hooks){ dav_if_state_list *new_sl; new_sl = apr_pcalloc(p, sizeof(*new_sl)); new_sl->condition = condition; new_sl->type = t; if (t == dav_if_opaquelock) { dav_error *err; if ((err = (*locks_hooks->parse_locktoken)(p, state_token, &new_sl->locktoken)) != NULL) { /* If the state token cannot be parsed, treat it as an * unknown state; this will evaluate to "false" later * during If header validation. */ if (err->error_id == DAV_ERR_LOCK_UNK_STATE_TOKEN) { new_sl->type = dav_if_unknown; } else { /* ### maybe add a higher-level description */ return err; } } } else new_sl->etag = state_token; new_sl->next = ih->state; ih->state = new_sl; return NULL;}/* fetch_next_token returns the substring from str+1 * to the next occurence of char term, or \0, whichever * occurs first. Leading whitespace is ignored. */static char *dav_fetch_next_token(char **str, char term){ char *sp; char *token; token = *str + 1; while (*token && (*token == ' ' || *token == '\t')) token++; if ((sp = strchr(token, term)) == NULL) return NULL; *sp = '\0'; *str = sp; return token;}/* dav_process_if_header: * * If NULL (no error) is returned, then **if_header points to the * "If" productions structure (or NULL if "If" is not present). * * ### this part is bogus: * If an error is encountered, the error is logged. Parent should * return err->status. */static dav_error * dav_process_if_header(request_rec *r, dav_if_header **p_ih){ dav_error *err; char *str; char *list; const char *state_token; const char *uri = NULL; /* scope of current production; NULL=no-tag */ apr_size_t uri_len = 0; dav_if_header *ih = NULL; apr_uri_t parsed_uri; const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); enum {no_tagged, tagged, unknown} list_type = unknown; int condition; *p_ih = NULL; if ((str = apr_pstrdup(r->pool, apr_table_get(r->headers_in, "If"))) == NULL) return NULL; while (*str) { switch(*str) { case '<': /* Tagged-list production - following states apply to this uri */ if (list_type == no_tagged || ((uri = dav_fetch_next_token(&str, '>')) == NULL)) { return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_TAGGED, "Invalid If-header: unclosed \"<\" or " "unexpected tagged-list production."); } /* 2518 specifies this must be an absolute URI; just take the * relative part for later comparison against r->uri */ if (apr_uri_parse(r->pool, uri, &parsed_uri) != APR_SUCCESS) { return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_TAGGED, "Invalid URI in tagged If-header."); } /* note that parsed_uri.path is allocated; we can trash it */ /* clean up the URI a bit */ ap_getparents(parsed_uri.path); uri_len = strlen(parsed_uri.path); if (uri_len > 1 && parsed_uri.path[uri_len - 1] == '/') parsed_uri.path[--uri_len] = '\0'; uri = parsed_uri.path; list_type = tagged; break; case '(': /* List production */ /* If a uri has not been encountered, this is a No-Tagged-List */ if (list_type == unknown) list_type = no_tagged; if ((list = dav_fetch_next_token(&str, ')')) == NULL) { return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_UNCLOSED_PAREN, "Invalid If-header: unclosed \"(\"."); } if ((ih = dav_add_if_resource(r->pool, ih, uri, uri_len)) == NULL) { /* ### dav_add_if_resource() should return an error for us! */ return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_PARSE, "Internal server error parsing \"If:\" " "header."); } condition = DAV_IF_COND_NORMAL; while (*list) { /* List is the entire production (in a uri scope) */ switch (*list) { case '<': if ((state_token = dav_fetch_next_token(&list, '>')) == NULL) { /* ### add a description to this error */ return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_PARSE, NULL); } if ((err = dav_add_if_state(r->pool, ih, state_token, dav_if_opaquelock, condition, locks_hooks)) != NULL) { /* ### maybe add a higher level description */ return err; } condition = DAV_IF_COND_NORMAL; break; case '[': if ((state_token = dav_fetch_next_token(&list, ']')) == NULL) { /* ### add a description to this error */ return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_PARSE, NULL); } if ((err = dav_add_if_state(r->pool, ih, state_token, dav_if_etag, condition, locks_hooks)) != NULL) { /* ### maybe add a higher level description */ return err; } condition = DAV_IF_COND_NORMAL; break; case 'N': if (list[1] == 'o' && list[2] == 't') { if (condition != DAV_IF_COND_NORMAL) { return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_MULTIPLE_NOT, "Invalid \"If:\" header: " "Multiple \"not\" entries " "for the same state."); } condition = DAV_IF_COND_NOT; } list += 2; break; case ' ': case '\t': break; default: return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_UNK_CHAR, apr_psprintf(r->pool,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -