mirror of
https://github.com/apache/httpd.git
synced 2025-08-10 02:02:49 +03:00
log2n compilation error fix, cache digest calculation fix
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1725262 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -1,6 +1,10 @@
|
||||
-*- coding: utf-8 -*-
|
||||
Changes with Apache 2.5.0
|
||||
|
||||
*) mod_http2: fixed compile issues re cc's with builtin log2n, fixed cache
|
||||
digest calculation. [Stefan Eissing]
|
||||
|
||||
pushed resources are kept. See directive H2PushDiarySize for managing this.
|
||||
*) core: Add expression support to SetHandler.
|
||||
[Eric Covener]
|
||||
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "h2_task.h"
|
||||
#include "h2_stream.h"
|
||||
#include "h2_stream_set.h"
|
||||
#include "h2_request.h"
|
||||
#include "h2_response.h"
|
||||
#include "h2_session.h"
|
||||
#include "h2_util.h"
|
||||
@@ -203,6 +204,7 @@ static apr_status_t h2_sos_h2_status_buffer(h2_sos *sos, apr_bucket_brigade *bb)
|
||||
h2_stream *stream = sos->stream;
|
||||
h2_session *session = stream->session;
|
||||
h2_mplx *mplx = session->mplx;
|
||||
h2_push_diary *diary;
|
||||
apr_status_t status;
|
||||
|
||||
if (!bb) {
|
||||
@@ -225,21 +227,24 @@ static apr_status_t h2_sos_h2_status_buffer(h2_sos *sos, apr_bucket_brigade *bb)
|
||||
bbout(" \"pushes_submitted\": %d,\n", session->pushes_submitted);
|
||||
bbout(" \"pushes_reset\": %d,\n", session->pushes_reset);
|
||||
|
||||
if (session->push_diary) {
|
||||
diary = session->push_diary;
|
||||
if (diary) {
|
||||
const char *data;
|
||||
const char *base64_digest;
|
||||
apr_size_t len;
|
||||
|
||||
status = h2_push_diary_digest_get(session->push_diary, stream->pool, 1024, &data, &len);
|
||||
status = h2_push_diary_digest_get(diary, stream->pool, 256,
|
||||
stream->request->authority, &data, &len);
|
||||
if (status == APR_SUCCESS) {
|
||||
base64_digest = h2_util_base64url_encode(data, len, stream->pool);
|
||||
bbout(" \"cache_digest\": \"%s\",\n", base64_digest);
|
||||
}
|
||||
|
||||
/* try the reverse for testing purposes */
|
||||
status = h2_push_diary_digest_set(session->push_diary, data, len);
|
||||
status = h2_push_diary_digest_set(diary, stream->request->authority, data, len);
|
||||
if (status == APR_SUCCESS) {
|
||||
status = h2_push_diary_digest_get(session->push_diary, stream->pool, 1024, &data, &len);
|
||||
status = h2_push_diary_digest_get(diary, stream->pool, 256,
|
||||
stream->request->authority, &data, &len);
|
||||
if (status == APR_SUCCESS) {
|
||||
base64_digest = h2_util_base64url_encode(data, len, stream->pool);
|
||||
bbout(" \"cache_digest^2\": \"%s\",\n", base64_digest);
|
||||
|
@@ -468,6 +468,9 @@ void h2_push_policy_determine(struct h2_request *req, apr_pool_t *p, int push_en
|
||||
* push diary
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#define GCSLOG_LEVEL APLOG_TRACE1
|
||||
|
||||
typedef struct h2_push_diary_entry {
|
||||
apr_uint64_t hash;
|
||||
} h2_push_diary_entry;
|
||||
@@ -482,22 +485,25 @@ static void sha256_update(SHA256_CTX *ctx, const char *s)
|
||||
static void calc_sha256_hash(h2_push_diary *diary, apr_uint64_t *phash, h2_push *push)
|
||||
{
|
||||
SHA256_CTX sha256;
|
||||
union {
|
||||
unsigned char hash[SHA256_DIGEST_LENGTH];
|
||||
apr_uint64_t val;
|
||||
} ctx;
|
||||
unsigned char hash[SHA256_DIGEST_LENGTH];
|
||||
int i;
|
||||
|
||||
SHA256_Init(&sha256);
|
||||
sha256_update(&sha256, push->req->scheme);
|
||||
sha256_update(&sha256, "://");
|
||||
sha256_update(&sha256, push->req->authority);
|
||||
sha256_update(&sha256, push->req->path);
|
||||
SHA256_Final(ctx.hash, &sha256);
|
||||
SHA256_Final(hash, &sha256);
|
||||
|
||||
*phash = ctx.val;
|
||||
val = 0;
|
||||
for (i = 0; i != sizeof(val); ++i)
|
||||
val = val * 256 + hash[i];
|
||||
*phash = val >> (64 - diary->mask_bits);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned int val_apr_hash(const char *str)
|
||||
{
|
||||
apr_ssize_t len = strlen(str);
|
||||
@@ -521,6 +527,7 @@ static void calc_apr_hash(h2_push_diary *diary, apr_uint64_t *phash, h2_push *pu
|
||||
|
||||
static apr_int32_t ceil_power_of_2(apr_int32_t n)
|
||||
{
|
||||
if (n <= 2) return 2;
|
||||
--n;
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
@@ -545,7 +552,7 @@ static h2_push_diary *diary_create(apr_pool_t *p, h2_push_digest_type dtype,
|
||||
* the full 64 bits.
|
||||
* If we set the diary via a compressed golomb set, we have less
|
||||
* relevant bits and need to use a smaller mask. */
|
||||
diary->mask = 0xffffffffffffffffu;
|
||||
diary->mask_bits = 64;
|
||||
/* grows by doubling, start with a power of 2 */
|
||||
diary->entries = apr_array_make(p, 16, sizeof(h2_push_diary_entry));
|
||||
|
||||
@@ -578,7 +585,6 @@ static int h2_push_diary_find(h2_push_diary *diary, apr_uint64_t hash)
|
||||
int i;
|
||||
|
||||
/* search from the end, where the last accessed digests are */
|
||||
hash &= diary->mask;
|
||||
for (i = diary->entries->nelts-1; i >= 0; --i) {
|
||||
e = &APR_ARRAY_IDX(diary->entries, i, h2_push_diary_entry);
|
||||
if (e->hash == hash) {
|
||||
@@ -618,9 +624,8 @@ static void h2_push_diary_append(h2_push_diary *diary, h2_push_diary_entry *e)
|
||||
ne = move_to_last(diary, 0);
|
||||
*ne = *e;
|
||||
}
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, diary->entries->pool,
|
||||
"push_diary_append: masking %lx", ne->hash);
|
||||
ne->hash &= diary->mask;
|
||||
ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, diary->entries->pool,
|
||||
"push_diary_append: %lx", ne->hash);
|
||||
}
|
||||
|
||||
apr_array_header_t *h2_push_diary_update(h2_session *session, apr_array_header_t *pushes)
|
||||
@@ -639,12 +644,12 @@ apr_array_header_t *h2_push_diary_update(h2_session *session, apr_array_header_t
|
||||
session->push_diary->dcalc(session->push_diary, &e.hash, push);
|
||||
idx = h2_push_diary_find(session->push_diary, e.hash);
|
||||
if (idx >= 0) {
|
||||
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
|
||||
ap_log_cerror(APLOG_MARK, GCSLOG_LEVEL, 0, session->c,
|
||||
"push_diary_update: already there PUSH %s", push->req->path);
|
||||
move_to_last(session->push_diary, idx);
|
||||
}
|
||||
else {
|
||||
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
|
||||
ap_log_cerror(APLOG_MARK, GCSLOG_LEVEL, 0, session->c,
|
||||
"push_diary_update: adding PUSH %s", push->req->path);
|
||||
if (!npushes) {
|
||||
npushes = apr_array_make(pushes->pool, 5, sizeof(h2_push_diary_entry*));
|
||||
@@ -667,7 +672,8 @@ apr_array_header_t *h2_push_collect_update(h2_stream *stream,
|
||||
apr_status_t status;
|
||||
|
||||
if (cache_digest && session->push_diary) {
|
||||
status = h2_push_diary_digest64_set(session->push_diary, cache_digest, stream->pool);
|
||||
status = h2_push_diary_digest64_set(session->push_diary, req->authority,
|
||||
cache_digest, stream->pool);
|
||||
if (status != APR_SUCCESS) {
|
||||
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, session->c,
|
||||
"h2_session(%ld): push diary set from Cache-Digest: %s",
|
||||
@@ -678,8 +684,8 @@ apr_array_header_t *h2_push_collect_update(h2_stream *stream,
|
||||
return h2_push_diary_update(stream->session, pushes);
|
||||
}
|
||||
|
||||
/* log2(n) iff n is a power of 2 */
|
||||
static unsigned char log2(apr_uint32_t n)
|
||||
/* h2_log2(n) iff n is a power of 2 */
|
||||
static unsigned char h2_log2(apr_uint32_t n)
|
||||
{
|
||||
int lz = 0;
|
||||
if (!n) {
|
||||
@@ -708,17 +714,7 @@ static unsigned char log2(apr_uint32_t n)
|
||||
return 31 - lz;
|
||||
}
|
||||
|
||||
/* log2(n) iff n is a power of 2 */
|
||||
static unsigned char log2_64(apr_uint64_t n)
|
||||
{
|
||||
apr_uint32_t i = (n & 0xffffffffu);
|
||||
if (i) {
|
||||
return log2(i);
|
||||
}
|
||||
return log2((apr_uint32_t)(n >> 32)) + 32;
|
||||
}
|
||||
|
||||
static apr_int32_t log2inv(unsigned char log2)
|
||||
static apr_int32_t h2_log2inv(unsigned char log2)
|
||||
{
|
||||
return log2? (1 << log2) : 1;
|
||||
}
|
||||
@@ -728,7 +724,7 @@ typedef struct {
|
||||
h2_push_diary *diary;
|
||||
unsigned char log2p;
|
||||
apr_uint32_t mask_bits;
|
||||
apr_uint64_t mask;
|
||||
apr_uint32_t delta_bits;
|
||||
apr_uint32_t fixed_bits;
|
||||
apr_uint64_t fixed_mask;
|
||||
apr_pool_t *pool;
|
||||
@@ -791,7 +787,7 @@ static apr_status_t gset_encode_next(gset_encoder *encoder, apr_uint64_t pval)
|
||||
delta = pval - encoder->last;
|
||||
encoder->last = pval;
|
||||
flex_bits = (delta >> encoder->fixed_bits);
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, encoder->pool,
|
||||
ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, encoder->pool,
|
||||
"h2_push_diary_enc: val=%lx, delta=%lx flex_bits=%ld, "
|
||||
"fixed_bits=%d, fixed_val=%lx",
|
||||
pval, delta, flex_bits, encoder->fixed_bits, delta&encoder->fixed_mask);
|
||||
@@ -826,11 +822,11 @@ static apr_status_t gset_encode_next(gset_encoder *encoder, apr_uint64_t pval)
|
||||
* @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,
|
||||
apr_uint32_t maxP,
|
||||
apr_uint32_t maxP, const char *authority,
|
||||
const char **pdata, apr_size_t *plen)
|
||||
{
|
||||
apr_size_t nelts, N, i;
|
||||
unsigned char log2n, log2pmax, mask_bits;
|
||||
unsigned char log2n, log2pmax;
|
||||
gset_encoder encoder;
|
||||
apr_uint64_t *hashes;
|
||||
apr_size_t hash_count;
|
||||
@@ -842,26 +838,19 @@ apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *pool,
|
||||
return APR_ENOTIMPL;
|
||||
}
|
||||
N = ceil_power_of_2(nelts);
|
||||
log2n = log2(N);
|
||||
|
||||
mask_bits = log2_64(diary->mask + 1);
|
||||
if (mask_bits <= log2n) {
|
||||
/* uhm, what? */
|
||||
return APR_ENOTIMPL;
|
||||
}
|
||||
log2n = h2_log2(N);
|
||||
|
||||
/* Now log2p is the max number of relevant bits, so that
|
||||
* log2p + log2n == mask_bits. We can uise a lower log2p
|
||||
* and have a shorter set encoding...
|
||||
*/
|
||||
log2pmax = log2(ceil_power_of_2(maxP));
|
||||
log2pmax = h2_log2(ceil_power_of_2(maxP));
|
||||
|
||||
memset(&encoder, 0, sizeof(encoder));
|
||||
encoder.diary = diary;
|
||||
encoder.log2p = H2MIN(mask_bits - log2n, log2pmax);
|
||||
encoder.log2p = H2MIN(diary->mask_bits - log2n, log2pmax);
|
||||
encoder.mask_bits = log2n + encoder.log2p;
|
||||
encoder.mask = 1;
|
||||
encoder.mask = (encoder.mask << encoder.mask_bits) - 1;
|
||||
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;
|
||||
@@ -875,17 +864,20 @@ apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *pool,
|
||||
encoder.bit = 8;
|
||||
encoder.last = 0;
|
||||
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool,
|
||||
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, enc.log2p=%d",
|
||||
(int)nelts, (int)N, (int)log2n, (int)mask_bits,
|
||||
(int)encoder.mask_bits, (int)encoder.log2p);
|
||||
"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.mask);
|
||||
>> encoder.delta_bits);
|
||||
}
|
||||
|
||||
qsort(hashes, hash_count, sizeof(apr_uint64_t), cmp_puint64);
|
||||
@@ -894,10 +886,10 @@ apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *pool,
|
||||
gset_encode_next(&encoder, hashes[i]);
|
||||
}
|
||||
}
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool,
|
||||
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;
|
||||
|
||||
@@ -958,7 +950,7 @@ static apr_status_t gset_decode_next(gset_decoder *decoder, apr_uint64_t *phash)
|
||||
*phash = delta + decoder->last_val;
|
||||
decoder->last_val = *phash;
|
||||
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, decoder->pool,
|
||||
ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, decoder->pool,
|
||||
"h2_push_diary_digest_dec: val=%lx, delta=%lx, flex=%d, fixed=%lx",
|
||||
*phash, delta, (int)flex, fixed);
|
||||
|
||||
@@ -974,7 +966,7 @@ static apr_status_t gset_decode_next(gset_decoder *decoder, apr_uint64_t *phash)
|
||||
* @param len the length of the cache digest
|
||||
* @return APR_EINVAL if digest was not successfully parsed
|
||||
*/
|
||||
apr_status_t h2_push_diary_digest_set(h2_push_diary *diary,
|
||||
apr_status_t h2_push_diary_digest_set(h2_push_diary *diary, const char *authority,
|
||||
const char *data, apr_size_t len)
|
||||
{
|
||||
gset_decoder decoder;
|
||||
@@ -983,8 +975,6 @@ apr_status_t h2_push_diary_digest_set(h2_push_diary *diary,
|
||||
apr_pool_t *pool = diary->entries->pool;
|
||||
h2_push_diary_entry e;
|
||||
apr_status_t status = APR_SUCCESS;
|
||||
apr_uint64_t mask;
|
||||
int mask_bits;
|
||||
|
||||
if (len < 2) {
|
||||
/* at least this should be there */
|
||||
@@ -992,23 +982,22 @@ apr_status_t h2_push_diary_digest_set(h2_push_diary *diary,
|
||||
}
|
||||
log2n = data[0];
|
||||
log2p = data[1];
|
||||
mask_bits = log2n + log2p;
|
||||
if (mask_bits > 64) {
|
||||
diary->mask_bits = log2n + log2p;
|
||||
if (diary->mask_bits > 64) {
|
||||
/* cannot handle */
|
||||
return APR_ENOTIMPL;
|
||||
}
|
||||
else if (mask_bits == 64) {
|
||||
mask = 0xffffffffffffffffu;
|
||||
}
|
||||
else {
|
||||
mask = 1;
|
||||
mask = (mask << mask_bits) - 1;
|
||||
}
|
||||
|
||||
/* whatever is in the digest, it replaces the diary entries */
|
||||
apr_array_clear(diary->entries);
|
||||
if (!authority || !strcmp("*", authority)) {
|
||||
diary->authority = NULL;
|
||||
}
|
||||
else if (!diary->authority || strcmp(diary->authority, authority)) {
|
||||
diary->authority = apr_pstrdup(diary->entries->pool, authority);
|
||||
}
|
||||
|
||||
N = log2inv(log2n + log2p);
|
||||
N = h2_log2inv(log2n + log2p);
|
||||
|
||||
decoder.diary = diary;
|
||||
decoder.pool = pool;
|
||||
@@ -1020,14 +1009,12 @@ apr_status_t h2_push_diary_digest_set(h2_push_diary *diary,
|
||||
decoder.last_val = 0;
|
||||
|
||||
diary->N = N;
|
||||
diary->mask = mask;
|
||||
/* Determine effective N we use for storage */
|
||||
if (!N) {
|
||||
/* a totally empty cache digest. someone tells us that she has no
|
||||
* entries in the cache at all. Use our own preferences for N+mask
|
||||
*/
|
||||
diary->N = diary->NMax;
|
||||
diary->mask = 0xffffffffffffffffu;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
else if (N > diary->NMax) {
|
||||
@@ -1036,10 +1023,10 @@ apr_status_t h2_push_diary_digest_set(h2_push_diary *diary,
|
||||
diary->N = diary->NMax;
|
||||
}
|
||||
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool,
|
||||
ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool,
|
||||
"h2_push_diary_digest_set: N=%d, log2n=%d, "
|
||||
"diary->mask=%lx, dec.log2p=%d",
|
||||
(int)diary->N, (int)log2n, diary->mask,
|
||||
"diary->mask_bits=%d, dec.log2p=%d",
|
||||
(int)diary->N, (int)log2n, diary->mask_bits,
|
||||
(int)decoder.log2p);
|
||||
|
||||
for (i = 0; i < diary->N; ++i) {
|
||||
@@ -1050,20 +1037,20 @@ apr_status_t h2_push_diary_digest_set(h2_push_diary *diary,
|
||||
h2_push_diary_append(diary, &e);
|
||||
}
|
||||
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool,
|
||||
"h2_push_diary_digest_set: diary now with %d entries, mask=%lx",
|
||||
(int)diary->entries->nelts, diary->mask);
|
||||
ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool,
|
||||
"h2_push_diary_digest_set: diary now with %d entries, mask_bits=%d",
|
||||
(int)diary->entries->nelts, diary->mask_bits);
|
||||
return status;
|
||||
}
|
||||
|
||||
apr_status_t h2_push_diary_digest64_set(h2_push_diary *diary, const char *data64url,
|
||||
apr_pool_t *pool)
|
||||
apr_status_t h2_push_diary_digest64_set(h2_push_diary *diary, const char *authority,
|
||||
const char *data64url, apr_pool_t *pool)
|
||||
{
|
||||
const char *data;
|
||||
apr_size_t len = h2_util_base64url_decode(&data, data64url, pool);
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool,
|
||||
ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool,
|
||||
"h2_push_diary_digest64_set: digest=%s, dlen=%d",
|
||||
data64url, (int)len);
|
||||
return h2_push_diary_digest_set(diary, data, len);
|
||||
return h2_push_diary_digest_set(diary, authority, data, len);
|
||||
}
|
||||
|
||||
|
@@ -45,7 +45,9 @@ struct h2_push_diary {
|
||||
apr_array_header_t *entries;
|
||||
apr_size_t NMax; /* Maximum for N, should size change be necessary */
|
||||
apr_size_t N; /* Current maximum number of entries, power of 2 */
|
||||
apr_uint64_t mask; /* applied on hash value comparision */
|
||||
apr_uint64_t mask; /* mask for relevant bits */
|
||||
unsigned int mask_bits; /* number of relevant bits */
|
||||
const char *authority;
|
||||
h2_push_digest_type dtype;
|
||||
h2_push_digest_calc *dcalc;
|
||||
};
|
||||
@@ -103,26 +105,28 @@ apr_array_header_t *h2_push_collect_update(struct h2_stream *stream,
|
||||
*
|
||||
* @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,
|
||||
apr_uint32_t maxP, const char **pdata,
|
||||
apr_size_t *plen);
|
||||
apr_uint32_t maxP, const char *authority,
|
||||
const char **pdata, apr_size_t *plen);
|
||||
|
||||
/**
|
||||
* Initialize the push diary by a cache digest as described in
|
||||
* https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/
|
||||
* .
|
||||
* @param diary the diary to set the digest into
|
||||
* @param authority the authority to set the data for
|
||||
* @param data the binary cache digest
|
||||
* @param len the length of the cache digest
|
||||
* @return APR_EINVAL if digest was not successfully parsed
|
||||
*/
|
||||
apr_status_t h2_push_diary_digest_set(h2_push_diary *diary,
|
||||
apr_status_t h2_push_diary_digest_set(h2_push_diary *diary, const char *authority,
|
||||
const char *data, apr_size_t len);
|
||||
|
||||
apr_status_t h2_push_diary_digest64_set(h2_push_diary *diary, const char *data64url,
|
||||
apr_pool_t *pool);
|
||||
apr_status_t h2_push_diary_digest64_set(h2_push_diary *diary, const char *authority,
|
||||
const char *data64url, apr_pool_t *pool);
|
||||
|
||||
#endif /* defined(__mod_h2__h2_push__) */
|
||||
|
@@ -174,7 +174,9 @@ const char *h2_util_base64url_encode(const char *data,
|
||||
((i+1 < len)? (udata[i+1] >> 4) : 0) & 0x3fu ];
|
||||
*p++ = BASE64URL_CHARS[ (udata[i+1] << 2) +
|
||||
((i+2 < len)? (udata[i+2] >> 6) : 0) & 0x3fu ];
|
||||
*p++ = (i+2 < len)? BASE64URL_CHARS[ udata[i+2] & 0x3fu ] : '=';
|
||||
if (i+2 < len) {
|
||||
*p++ = BASE64URL_CHARS[ udata[i+2] & 0x3fu ];
|
||||
}
|
||||
}
|
||||
|
||||
return enc;
|
||||
|
@@ -26,7 +26,7 @@
|
||||
* @macro
|
||||
* Version number of the http2 module as c string
|
||||
*/
|
||||
#define MOD_HTTP2_VERSION "1.1.1-DEV"
|
||||
#define MOD_HTTP2_VERSION "1.2.1"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
@@ -34,7 +34,7 @@
|
||||
* release. This is a 24 bit number with 8 bits for major number, 8 bits
|
||||
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
|
||||
*/
|
||||
#define MOD_HTTP2_VERSION_NUM 0x010101
|
||||
#define MOD_HTTP2_VERSION_NUM 0x010201
|
||||
|
||||
|
||||
#endif /* mod_h2_h2_version_h */
|
||||
|
Reference in New Issue
Block a user