예제 #1
0
파일: util.c 프로젝트: ConfusedReality/h2o
h2o_iovec_vector_t h2o_extract_push_path_from_link_header(h2o_mem_pool_t *pool, const char *value, size_t value_len, h2o_iovec_t base_path,
                                                      const h2o_url_scheme_t *input_scheme, h2o_iovec_t input_authority,
                                                      const h2o_url_scheme_t *base_scheme, h2o_iovec_t *base_authority)
{
    h2o_iovec_vector_t paths_to_push = {};
    h2o_iovec_t iter = h2o_iovec_init(value, value_len), token_value;
    const char *token;
    size_t token_len;

    /* extract URL values from Link: </pushed.css>; rel=preload */
    do {
        if ((token = h2o_next_token(&iter, ';', &token_len, NULL)) == NULL)
            break;
        /* first element should be <URL> */
        if (!(token_len >= 2 && token[0] == '<' && token[token_len - 1] == '>'))
            break;
        h2o_iovec_t url = h2o_iovec_init(token + 1, token_len - 2);
        /* find rel=preload */
        int preload = 0, nopush = 0;
        while ((token = h2o_next_token(&iter, ';', &token_len, &token_value)) != NULL &&
               !h2o_memis(token, token_len, H2O_STRLIT(","))) {
            if (h2o_lcstris(token, token_len, H2O_STRLIT("rel")) &&
                    h2o_lcstris(token_value.base, token_value.len, H2O_STRLIT("preload"))) {
                preload++;
            } else if (h2o_lcstris(token, token_len, H2O_STRLIT("nopush"))) {
                nopush++;
            }
        }
        if (!nopush && preload)
            push_one_path(pool, &paths_to_push, &url, base_path, input_scheme, input_authority, base_scheme, base_authority);
    } while (token != NULL);

    return paths_to_push;
}
예제 #2
0
파일: util.c 프로젝트: nwcs/h2o
h2o_iovec_t h2o_extract_push_path_from_link_header(h2o_mem_pool_t *pool, const char *value, size_t value_len,
                                                   const h2o_url_scheme_t *base_scheme, h2o_iovec_t *base_authority,
                                                   h2o_iovec_t *base_path)
{
    h2o_iovec_t url;
    h2o_url_t parsed, resolved;

    { /* extract URL value from: Link: </pushed.css>; rel=preload */
        h2o_iovec_t iter = h2o_iovec_init(value, value_len), token_value;
        const char *token;
        size_t token_len;
        /* first element should be <URL> */
        if ((token = h2o_next_token(&iter, ';', &token_len, NULL)) == NULL)
            goto None;
        if (!(token_len >= 2 && token[0] == '<' && token[token_len - 1] == '>'))
            goto None;
        url = h2o_iovec_init(token + 1, token_len - 2);
        /* find rel=preload */
        while ((token = h2o_next_token(&iter, ';', &token_len, &token_value)) != NULL) {
            if (h2o_lcstris(token, token_len, H2O_STRLIT("rel")) &&
                h2o_lcstris(token_value.base, token_value.len, H2O_STRLIT("preload")))
                break;
        }
        if (token == NULL)
            goto None;
    }

    /* check the authority, and extract absolute path */
    if (h2o_url_parse_relative(url.base, url.len, &parsed) != 0)
        goto None;

    /* return the URL found in Link header, if it is an absolute path-only URL */
    if (parsed.scheme == NULL && parsed.authority.base == NULL && url.len != 0 && url.base[0] == '/')
        return h2o_strdup(pool, url.base, url.len);

    /* check scheme and authority if given URL contains either of the two */
    h2o_url_t base = {base_scheme, *base_authority, {}, *base_path, 65535};
    h2o_url_resolve(pool, &base, &parsed, &resolved);
    if (base.scheme != resolved.scheme)
        goto None;
    if (parsed.authority.base != NULL &&
        !h2o_lcstris(base.authority.base, base.authority.len, resolved.authority.base, resolved.authority.len))
        goto None;
    return resolved.path;

None:
    return (h2o_iovec_t){};
}
예제 #3
0
파일: string.c 프로젝트: cubicdaiya/h2o
static void test_next_token(void)
{
    h2o_iovec_t iter;
    const char *token;
    size_t token_len;

#define NEXT()                                                                                                                     \
    if ((token = h2o_next_token(&iter, ',', &token_len, NULL)) == NULL) {                                                          \
        ok(0);                                                                                                                     \
        return;                                                                                                                    \
    }

    iter = h2o_iovec_init(H2O_STRLIT("public, max-age=86400, must-revalidate"));
    NEXT();
    ok(h2o_memis(token, token_len, H2O_STRLIT("public")));
    NEXT();
    ok(h2o_memis(token, token_len, H2O_STRLIT("max-age=86400")));
    NEXT();
    ok(h2o_memis(token, token_len, H2O_STRLIT("must-revalidate")));
    token = h2o_next_token(&iter, ',', &token_len, NULL);
    ok(token == NULL);

    iter = h2o_iovec_init(H2O_STRLIT("  public  ,max-age=86400  ,"));
    NEXT();
    ok(h2o_memis(token, token_len, H2O_STRLIT("public")));
    NEXT();
    ok(h2o_memis(token, token_len, H2O_STRLIT("max-age=86400")));
    token = h2o_next_token(&iter, ',', &token_len, NULL);
    ok(token == NULL);

    iter = h2o_iovec_init(H2O_STRLIT(""));
    token = h2o_next_token(&iter, ',', &token_len, NULL);
    ok(token == NULL);

    iter = h2o_iovec_init(H2O_STRLIT(", ,a, "));
    NEXT();
    ok(token_len == 0);
    NEXT();
    ok(token_len == 0);
    NEXT();
    ok(h2o_memis(token, token_len, H2O_STRLIT("a")));
    token = h2o_next_token(&iter, ',', &token_len, NULL);
    ok(token == NULL);

#undef NEXT
}
예제 #4
0
파일: string.c 프로젝트: cubicdaiya/h2o
static void test_next_token2(void)
{
    h2o_iovec_t iter, value;
    const char *name;
    size_t name_len;

#define NEXT()                                                                                                                     \
    if ((name = h2o_next_token(&iter, ',', &name_len, &value)) == NULL) {                                                          \
        ok(0);                                                                                                                     \
        return;                                                                                                                    \
    }

    iter = h2o_iovec_init(H2O_STRLIT("public, max-age=86400, must-revalidate"));
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("public")));
    ok(value.base == NULL);
    ok(value.len == 0);
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("max-age")));
    ok(h2o_memis(value.base, value.len, H2O_STRLIT("86400")));
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("must-revalidate")));
    ok(value.base == NULL);
    ok(value.len == 0);
    name = h2o_next_token(&iter, ',', &name_len, &value);
    ok(name == NULL);

    iter = h2o_iovec_init(H2O_STRLIT("public, max-age = 86400 = c , must-revalidate="));
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("public")));
    ok(value.base == NULL);
    ok(value.len == 0);
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("max-age")));
    ok(h2o_memis(value.base, value.len, H2O_STRLIT("86400 = c")));
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("must-revalidate")));
    name = h2o_next_token(&iter, ',', &name_len, &value);
    ok(h2o_memis(value.base, value.len, H2O_STRLIT("")));

#undef NEXT
}
예제 #5
0
void h2o_cache_digests_load_header(h2o_cache_digests_t **digests, const char *value, size_t len)
{
    h2o_iovec_t iter = h2o_iovec_init(value, len);
    const char *token;
    size_t token_len;

    do {
        const char *gcs_base64;
        size_t gcs_base64_len;
        int reset = 0, validators = 0, complete = 0, skip = 0;
        h2o_iovec_t token_value;

        if ((gcs_base64 = h2o_next_token(&iter, ';', &gcs_base64_len, NULL)) == NULL)
            return;
        while ((token = h2o_next_token(&iter, ';', &token_len, &token_value)) != NULL &&
               !h2o_memis(token, token_len, H2O_STRLIT(","))) {
            if (h2o_lcstris(token, token_len, H2O_STRLIT("reset"))) {
                reset = 1;
            } else if (h2o_lcstris(token, token_len, H2O_STRLIT("validators"))) {
                validators = 1;
            } else if (h2o_lcstris(token, token_len, H2O_STRLIT("complete"))) {
                complete = 1;
            } else {
                skip = 1;
            }
        }

        if (reset && *digests != NULL) {
            h2o_cache_digests_destroy(*digests);
            *digests = NULL;
        }

        if (skip) {
            /* not supported for the time being */
        } else {
            load_digest(digests, gcs_base64, gcs_base64_len, validators, complete);
        }
    } while (token != NULL);
}
예제 #6
0
파일: string.c 프로젝트: cubicdaiya/h2o
static void test_next_token3(void)
{
    h2o_iovec_t iter, value;
    const char *name;
    size_t name_len;

#define NEXT()                                                                                                                     \
    if ((name = h2o_next_token(&iter, ';', &name_len, &value)) == NULL) {                                                          \
        ok(0);                                                                                                                     \
        return;                                                                                                                    \
    }

    iter = h2o_iovec_init(H2O_STRLIT("</foo.css>; rel=preload; xxx=,</bar.js>, </zzz.js>"));
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("</foo.css>")));
    ok(value.base == NULL);
    ok(value.len == 0);
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("rel")));
    ok(h2o_memis(value.base, value.len, H2O_STRLIT("preload")));
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("xxx")));
    ok(value.base != NULL); /* xxx _has_ a value! */
    ok(value.len == 0);
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT(",")));
    ok(value.base == NULL);
    ok(value.len == 0);
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("</bar.js>")));
    ok(value.base == NULL);
    ok(value.len == 0);
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT(",")));
    ok(value.base == NULL);
    ok(value.len == 0);
    NEXT();
    ok(h2o_memis(name, name_len, H2O_STRLIT("</zzz.js>")));
    ok(value.base == NULL);
    ok(value.len == 0);
    name = h2o_next_token(&iter, ',', &name_len, &value);
    ok(name == NULL);

#undef NEXT
}
예제 #7
0
파일: util.c 프로젝트: ConfusedReality/h2o
int h2o_get_compressible_types(const h2o_headers_t *headers)
{
    size_t header_index;
    int compressible_types = 0;

    for (header_index = 0; header_index != headers->size; ++header_index) {
        const h2o_header_t *header = headers->entries + header_index;
        if (H2O_UNLIKELY(header->name == &H2O_TOKEN_ACCEPT_ENCODING->buf)) {
            h2o_iovec_t iter = h2o_iovec_init(header->value.base, header->value.len);
            const char *token = NULL;
            size_t token_len = 0;
            while ((token = h2o_next_token(&iter, ',', &token_len, NULL)) != NULL) {
                if (h2o_lcstris(token, token_len, H2O_STRLIT("gzip")))
                    compressible_types |= H2O_COMPRESSIBLE_GZIP;
                else if (h2o_lcstris(token, token_len, H2O_STRLIT("br")))
                    compressible_types |= H2O_COMPRESSIBLE_BROTLI;
            }
        }
    }

    return compressible_types;
}