diff options
Diffstat (limited to 'web/server/h2o/libh2o/lib/http2/cache_digests.c')
-rw-r--r-- | web/server/h2o/libh2o/lib/http2/cache_digests.c | 201 |
1 files changed, 0 insertions, 201 deletions
diff --git a/web/server/h2o/libh2o/lib/http2/cache_digests.c b/web/server/h2o/libh2o/lib/http2/cache_digests.c deleted file mode 100644 index fa28bd238..000000000 --- a/web/server/h2o/libh2o/lib/http2/cache_digests.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include <limits.h> -#include <openssl/sha.h> -#include <stdlib.h> -#include "golombset.h" -#include "h2o/string_.h" -#include "h2o/cache_digests.h" - -struct st_h2o_cache_digests_frame_t { - H2O_VECTOR(uint64_t) keys; - unsigned capacity_bits; -}; - -static void dispose_frame_vector(h2o_cache_digests_frame_vector_t *v) -{ - size_t i; - for (i = 0; i != v->size; ++i) - free(v->entries[i].keys.entries); - free(v->entries); -} - -static void dispose_digests(h2o_cache_digests_t *digests) -{ - dispose_frame_vector(&digests->fresh.url_only); - dispose_frame_vector(&digests->fresh.url_and_etag); -} - -void h2o_cache_digests_destroy(h2o_cache_digests_t *digests) -{ - dispose_digests(digests); - free(digests); -} - -static void load_digest(h2o_cache_digests_t **digests, const char *gcs_base64, size_t gcs_base64_len, int with_validators, - int complete) -{ - h2o_cache_digests_frame_t frame = {{NULL}}; - h2o_iovec_t gcs_bin; - struct st_golombset_decode_t ctx = {NULL}; - uint64_t nbits, pbits; - - /* decode base64 */ - if ((gcs_bin = h2o_decode_base64url(NULL, gcs_base64, gcs_base64_len)).base == NULL) - goto Exit; - - /* prepare GCS context */ - ctx.src = (void *)(gcs_bin.base - 1); - ctx.src_max = (void *)(gcs_bin.base + gcs_bin.len); - ctx.src_shift = 0; - - /* decode nbits and pbits */ - if (golombset_decode_bits(&ctx, 5, &nbits) != 0 || golombset_decode_bits(&ctx, 5, &pbits) != 0) - goto Exit; - frame.capacity_bits = (unsigned)(nbits + pbits); - - /* decode the values */ - uint64_t value = UINT64_MAX, decoded; - while (golombset_decode_value(&ctx, (unsigned)pbits, &decoded) == 0) { - value += decoded + 1; - if (value >= (uint64_t)1 << frame.capacity_bits) - goto Exit; - h2o_vector_reserve(NULL, &frame.keys, frame.keys.size + 1); - frame.keys.entries[frame.keys.size++] = value; - } - - /* store the result */ - if (*digests == NULL) { - *digests = h2o_mem_alloc(sizeof(**digests)); - **digests = (h2o_cache_digests_t){{{NULL}}}; - } - h2o_cache_digests_frame_vector_t *target = with_validators ? &(*digests)->fresh.url_and_etag : &(*digests)->fresh.url_only; - h2o_vector_reserve(NULL, target, target->size + 1); - target->entries[target->size++] = frame; - frame = (h2o_cache_digests_frame_t){{NULL}}; - (*digests)->fresh.complete = complete; - -Exit: - free(frame.keys.entries); - free(gcs_bin.base); -} - -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); -} - -static uint64_t calc_hash(const char *url, size_t url_len, const char *etag, size_t etag_len) -{ - SHA256_CTX ctx; - union { - unsigned char bytes[SHA256_DIGEST_LENGTH]; - uint64_t u64; - } md; - - SHA256_Init(&ctx); - SHA256_Update(&ctx, url, url_len); - SHA256_Update(&ctx, etag, etag_len); - SHA256_Final(md.bytes, &ctx); - - if (*(uint16_t *)"\xde\xad" == 0xdead) - return md.u64; - else - return __builtin_bswap64(md.u64); -} - -static int cmp_key(const void *_x, const void *_y) -{ - uint64_t x = *(uint64_t *)_x, y = *(uint64_t *)_y; - - if (x < y) { - return -1; - } else if (x > y) { - return 1; - } else { - return 0; - } -} - -static int lookup(h2o_cache_digests_frame_vector_t *vector, const char *url, size_t url_len, const char *etag, size_t etag_len, - int is_fresh, int is_complete) -{ - if (vector->size != 0) { - uint64_t hash = calc_hash(url, url_len, etag, etag_len); - size_t i = 0; - do { - h2o_cache_digests_frame_t *frame = vector->entries + i; - uint64_t key = hash >> (64 - frame->capacity_bits); - if (frame->keys.entries != NULL && - bsearch(&key, frame->keys.entries, frame->keys.size, sizeof(frame->keys.entries[0]), cmp_key) != NULL) - return is_fresh ? H2O_CACHE_DIGESTS_STATE_FRESH : H2O_CACHE_DIGESTS_STATE_STALE; - } while (++i != vector->size); - } - - return is_complete ? H2O_CACHE_DIGESTS_STATE_NOT_CACHED : H2O_CACHE_DIGESTS_STATE_UNKNOWN; -} - -h2o_cache_digests_state_t h2o_cache_digests_lookup_by_url(h2o_cache_digests_t *digests, const char *url, size_t url_len) -{ - return lookup(&digests->fresh.url_only, url, url_len, "", 0, 1, digests->fresh.complete); -} - -h2o_cache_digests_state_t h2o_cache_digests_lookup_by_url_and_etag(h2o_cache_digests_t *digests, const char *url, size_t url_len, - const char *etag, size_t etag_len) -{ - return lookup(&digests->fresh.url_and_etag, url, url_len, etag, etag_len, 1, digests->fresh.complete); -} |