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

📄 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 页
字号:
    }

    cdata = s = apr_palloc(pool, len + 1);

    for (scan = elem->first_cdata.first; scan != NULL; scan = scan->next) {
        tlen = strlen(scan->text);
        memcpy(s, scan->text, tlen);
        s += tlen;
    }

    for (child = elem->first_child; child != NULL; child = child->next) {
        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) {
            /* In cases where the state token is invalid, we'll just skip
             * it rather than return 400.
             */
            if (err->error_id == DAV_ERR_LOCK_UNK_STATE_TOKEN) {
                return NULL;
            }
            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;

⌨️ 快捷键说明

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