From 1d8c9314c1096b40c8b170edff3f91056c5f8393 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Fri, 5 Jun 2026 12:55:24 +0100 Subject: [PATCH] * mod_http2/h2_push.c (h2_push_diary_digest_get, gset_encode_next, gset_encode_bit, cmp_puint64): Remove unused cache digest functions and supporting golomb set encoder. * mod_http2/h2_push.h (h2_push_diary_digest_get): Remove declaration. Co-Authored-By: Claude Opus 4.6 --- mod_http2/h2_push.c | 176 -------------------------------------------- mod_http2/h2_push.h | 15 ---- 2 files changed, 191 deletions(-) diff --git a/mod_http2/h2_push.c b/mod_http2/h2_push.c index e6a10c5a..589862ce 100644 --- a/mod_http2/h2_push.c +++ b/mod_http2/h2_push.c @@ -699,179 +699,3 @@ apr_array_header_t *h2_push_collect_update(struct h2_stream *stream, pushes = h2_push_collect(stream->pool, req, stream->push_policy, res); return h2_push_diary_update(stream->session, pushes); } - -typedef struct { - h2_push_diary *diary; - unsigned char log2p; - int mask_bits; - int delta_bits; - int fixed_bits; - apr_uint64_t fixed_mask; - apr_pool_t *pool; - unsigned char *data; - apr_size_t datalen; - apr_size_t offset; - unsigned int bit; - apr_uint64_t last; -} gset_encoder; - -static int cmp_puint64(const void *p1, const void *p2) -{ - const apr_uint64_t *pu1 = p1, *pu2 = p2; - return (*pu1 > *pu2)? 1 : ((*pu1 == *pu2)? 0 : -1); -} - -/* in golomb bit stream encoding, bit 0 is the 8th of the first char, or - * more generally: - * char(bit/8) & cbit_mask[(bit % 8)] - */ -static unsigned char cbit_mask[] = { - 0x80u, - 0x40u, - 0x20u, - 0x10u, - 0x08u, - 0x04u, - 0x02u, - 0x01u, -}; - -static apr_status_t gset_encode_bit(gset_encoder *encoder, int bit) -{ - if (++encoder->bit >= 8) { - if (++encoder->offset >= encoder->datalen) { - apr_size_t nlen = encoder->datalen*2; - unsigned char *ndata = apr_pcalloc(encoder->pool, nlen); - if (!ndata) { - return APR_ENOMEM; - } - memcpy(ndata, encoder->data, encoder->datalen); - encoder->data = ndata; - encoder->datalen = nlen; - } - encoder->bit = 0; - encoder->data[encoder->offset] = 0xffu; - } - if (!bit) { - encoder->data[encoder->offset] &= ~cbit_mask[encoder->bit]; - } - return APR_SUCCESS; -} - -static apr_status_t gset_encode_next(gset_encoder *encoder, apr_uint64_t pval) -{ - apr_uint64_t delta, flex_bits; - apr_status_t status = APR_SUCCESS; - int i; - - delta = pval - encoder->last; - encoder->last = pval; - flex_bits = (delta >> encoder->fixed_bits); - /* Intentional no APLOGNO */ - ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, encoder->pool, - "h2_push_diary_enc: val=%"APR_UINT64_T_HEX_FMT", delta=%" - APR_UINT64_T_HEX_FMT" flex_bits=%"APR_UINT64_T_FMT", " - ", fixed_bits=%d, fixed_val=%"APR_UINT64_T_HEX_FMT, - pval, delta, flex_bits, encoder->fixed_bits, delta&encoder->fixed_mask); - for (; flex_bits != 0; --flex_bits) { - status = gset_encode_bit(encoder, 1); - if (status != APR_SUCCESS) { - return status; - } - } - status = gset_encode_bit(encoder, 0); - if (status != APR_SUCCESS) { - return status; - } - - for (i = encoder->fixed_bits-1; i >= 0; --i) { - status = gset_encode_bit(encoder, (delta >> i) & 1); - if (status != APR_SUCCESS) { - return status; - } - } - return APR_SUCCESS; -} - -/** - * Get a cache digest as described in - * https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/ - * from the contents of the push diary. - * - * @param diary the diary to calculdate the digest from - * @param p the pool to use - * @param pdata on successful return, the binary cache digest - * @param plen on successful return, the length of the binary data - */ -apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *pool, - int maxP, const char *authority, - const char **pdata, apr_size_t *plen) -{ - int nelts, N; - unsigned char log2n, log2pmax; - gset_encoder encoder; - apr_uint64_t *hashes; - apr_size_t hash_count, i; - - nelts = diary->entries->nelts; - N = ceil_power_of_2(nelts); - log2n = h2_log2(N); - - /* Now log2p is the max number of relevant bits, so that - * log2p + log2n == mask_bits. We can use a lower log2p - * and have a shorter set encoding... - */ - log2pmax = h2_log2(ceil_power_of_2(maxP)); - - memset(&encoder, 0, sizeof(encoder)); - encoder.diary = diary; - encoder.log2p = H2MIN(diary->mask_bits - log2n, log2pmax); - encoder.mask_bits = log2n + encoder.log2p; - encoder.delta_bits = diary->mask_bits - encoder.mask_bits; - encoder.fixed_bits = encoder.log2p; - encoder.fixed_mask = 1; - encoder.fixed_mask = (encoder.fixed_mask << encoder.fixed_bits) - 1; - encoder.pool = pool; - encoder.datalen = 512; - encoder.data = apr_pcalloc(encoder.pool, encoder.datalen); - - encoder.data[0] = log2n; - encoder.data[1] = encoder.log2p; - encoder.offset = 1; - encoder.bit = 8; - encoder.last = 0; - - /* Intentional no APLOGNO */ - ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool, - "h2_push_diary_digest_get: %d entries, N=%d, log2n=%d, " - "mask_bits=%d, enc.mask_bits=%d, delta_bits=%d, enc.log2p=%d, authority=%s", - (int)nelts, (int)N, (int)log2n, diary->mask_bits, - (int)encoder.mask_bits, (int)encoder.delta_bits, - (int)encoder.log2p, authority); - - if (!authority || !diary->authority - || !strcmp("*", authority) || !strcmp(diary->authority, authority)) { - hash_count = diary->entries->nelts; - hashes = apr_pcalloc(encoder.pool, hash_count); - for (i = 0; i < hash_count; ++i) { - hashes[i] = ((&APR_ARRAY_IDX(diary->entries, i, h2_push_diary_entry))->hash - >> encoder.delta_bits); - } - - qsort(hashes, hash_count, sizeof(apr_uint64_t), cmp_puint64); - for (i = 0; i < hash_count; ++i) { - if (!i || (hashes[i] != hashes[i-1])) { - gset_encode_next(&encoder, hashes[i]); - } - } - /* Intentional no APLOGNO */ - ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool, - "h2_push_diary_digest_get: golomb compressed hashes, %d bytes", - (int)encoder.offset + 1); - } - *pdata = (const char *)encoder.data; - *plen = encoder.offset + 1; - - return APR_SUCCESS; -} - diff --git a/mod_http2/h2_push.h b/mod_http2/h2_push.h index 947b73bc..630d461d 100644 --- a/mod_http2/h2_push.h +++ b/mod_http2/h2_push.h @@ -140,19 +140,4 @@ apr_array_header_t *h2_push_collect_update(struct h2_stream *stream, const struct h2_headers *res); #endif -/** - * Get a cache digest as described in - * https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/ - * from the contents of the push diary. - * - * @param diary the diary to calculdate the digest from - * @param p the pool to use - * @param authority the authority to get the data for, use NULL/"*" for all - * @param pdata on successful return, the binary cache digest - * @param plen on successful return, the length of the binary data - */ -apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *p, - int maxP, const char *authority, - const char **pdata, apr_size_t *plen); - #endif /* defined(__mod_h2__h2_push__) */