Exemple #1
0
static void rfc_cookie(dAT)
{
    apreq_cookie_t *c = apreq_cookie_make(p,"rfc",3,"out",3);
    const char *expected;
    long expires;

    AT_str_eq(c->v.data, "out");

    apreq_cookie_version_set(c, 1);
    AT_int_eq(apreq_cookie_version(c), 1);
    AT_str_eq(apreq_cookie_as_string(c,p),"rfc=out; Version=1");

    c->domain = apr_pstrdup(p, "example.com");

#ifndef WIN32

    AT_str_eq(apreq_cookie_as_string(c,p),
              "rfc=out; Version=1; domain=\"example.com\"");
    c->path = apr_pstrdup(p, "/quux");
    AT_str_eq(apreq_cookie_as_string(c,p),
              "rfc=out; Version=1; path=\"/quux\"; domain=\"example.com\"");

    apreq_cookie_expires(c, "+3m");
    expires = apreq_atoi64t("+3m");
    expected = apr_psprintf(p, "rfc=out; Version=1; path=\"/quux\"; "
                       "domain=\"example.com\"; max-age=%ld",
                       expires);
    AT_str_eq(apreq_cookie_as_string(c,p), expected);

#else

    expected = "rfc=out; Version=1; domain=\"example.com\"";
    AT_str_eq(apreq_cookie_as_string(c,p), expected);

    c->path = apr_pstrdup(p, "/quux");
    expected = "rfc=out; Version=1; path=\"/quux\"; domain=\"example.com\"";
    AT_str_eq(apreq_cookie_as_string(c,p), expected);

    apreq_cookie_expires(c, "+3m");
    expires = apreq_atoi64t("+3m");
    expected = apr_psprintf(p, "rfc=out; Version=1; path=\"/quux\"; "
                           "domain=\"example.com\"; max-age=%ld",
                           expires);
    AT_str_eq(apreq_cookie_as_string(c,p), expected);

#endif

}
APREQ_DECLARE(apr_status_t)apreq_parse_cookie_header(apr_pool_t *p,
                                                     apr_table_t *j,
                                                     const char *hdr)
{
    apreq_cookie_t *c;
    unsigned version;
    apr_status_t rv = APR_SUCCESS;

 parse_cookie_header:

    c = NULL;
    version = NETSCAPE;

    while (apr_isspace(*hdr))
        ++hdr;


    if (*hdr == '$' && strncasecmp(hdr, "$Version", 8) == 0) {
        /* XXX cheat: assume "$Version" => RFC Cookie header */
        version = RFC;
    skip_version_string:
        switch (*hdr++) {
        case 0:
            return rv;
        case ',':
            goto parse_cookie_header;
        case ';':
            break;
        default:
            goto skip_version_string;
        }
    }

    for (;;) {
        apr_status_t status;
        const char *name, *value;
        apr_size_t nlen = 0, vlen;

        while (*hdr == ';' || apr_isspace(*hdr))
            ++hdr;

        switch (*hdr) {

        case 0:
            /* this is the normal exit point */
            if (c != NULL) {
                ADD_COOKIE(j, c);
            }
            return rv;

        case ',':
            ++hdr;
            if (c != NULL) {
                ADD_COOKIE(j, c);
            }
            goto parse_cookie_header;

        case '$':
            ++hdr;
            if (c == NULL) {
                rv = APREQ_ERROR_BADCHAR;
                goto parse_cookie_error;
            }
            else if (version == NETSCAPE) {
                rv = APREQ_ERROR_MISMATCH;
            }

            status = get_pair(p, &hdr, &name, &nlen, &value, &vlen, 1);
            if (status != APR_SUCCESS) {
                rv = status;
                goto parse_cookie_error;
            }

            status = apreq_cookie_attr(p, c, name, nlen, value, vlen);

            switch (status) {

            case APR_ENOTIMPL:
                rv = APREQ_ERROR_BADATTR;
                /* fall thru */

            case APR_SUCCESS:
                break;

            default:
                rv = status;
                goto parse_cookie_error;
            }

            break;

        default:
            if (c != NULL) {
                ADD_COOKIE(j, c);
            }

            status = get_pair(p, &hdr, &name, &nlen, &value, &vlen, 0);

            if (status != APR_SUCCESS) {
                c = NULL;
                rv = status;
                goto parse_cookie_error;
            }

            c = apreq_cookie_make(p, name, nlen, value, vlen);
            apreq_cookie_tainted_on(c);
            if (version != NETSCAPE)
                apreq_cookie_version_set(c, version);
        }
    }

 parse_cookie_error:

    switch (*hdr) {

    case 0:
        return rv;

    case ',':
    case ';':
        if (c != NULL)
            ADD_COOKIE(j, c);
        ++hdr;
        goto parse_cookie_header;

    default:
        ++hdr;
        goto parse_cookie_error;
    }

    /* not reached */
    return rv;
}