Merge branch 'master' into hpack-exp
Conflicts: lib/nghttp2_hd.c
This commit is contained in:
commit
4e4fab01b1
|
@ -462,16 +462,14 @@ static int ensure_write_buffer(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
|
||||||
static size_t count_encoded_length(size_t n, int prefix)
|
static size_t count_encoded_length(size_t n, int prefix)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
|
||||||
if(prefix > 0) {
|
|
||||||
size_t k = (1 << prefix) - 1;
|
size_t k = (1 << prefix) - 1;
|
||||||
|
size_t len = 0;
|
||||||
if(n >= k) {
|
if(n >= k) {
|
||||||
n -= k;
|
n -= k;
|
||||||
++len;
|
++len;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
++len;
|
++len;
|
||||||
if(n >= 128) {
|
if(n >= 128) {
|
||||||
|
@ -485,9 +483,8 @@ static size_t count_encoded_length(size_t n, int prefix)
|
||||||
|
|
||||||
static size_t encode_length(uint8_t *buf, size_t n, int prefix)
|
static size_t encode_length(uint8_t *buf, size_t n, int prefix)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
|
||||||
if(prefix > 0) {
|
|
||||||
size_t k = (1 << prefix) - 1;
|
size_t k = (1 << prefix) - 1;
|
||||||
|
size_t len = 0;
|
||||||
if(n >= k) {
|
if(n >= k) {
|
||||||
*buf++ = k;
|
*buf++ = k;
|
||||||
n -= k;
|
n -= k;
|
||||||
|
@ -496,7 +493,6 @@ static size_t encode_length(uint8_t *buf, size_t n, int prefix)
|
||||||
*buf++ = n;
|
*buf++ = n;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
++len;
|
++len;
|
||||||
if(n >= 128) {
|
if(n >= 128) {
|
||||||
|
@ -528,7 +524,6 @@ static uint8_t* decode_length(ssize_t *res, uint8_t *in, uint8_t *last,
|
||||||
*res = -1;
|
*res = -1;
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
if(prefix > 0) {
|
|
||||||
if((*in & k) == k) {
|
if((*in & k) == k) {
|
||||||
*res = k;
|
*res = k;
|
||||||
} else {
|
} else {
|
||||||
|
@ -536,9 +531,6 @@ static uint8_t* decode_length(ssize_t *res, uint8_t *in, uint8_t *last,
|
||||||
return in + 1;
|
return in + 1;
|
||||||
}
|
}
|
||||||
++in;
|
++in;
|
||||||
} else {
|
|
||||||
*res = 0;
|
|
||||||
}
|
|
||||||
for(r = 0; in != last; ++in, r += 7) {
|
for(r = 0; in != last; ++in, r += 7) {
|
||||||
*res += (*in & 0x7f) << r;
|
*res += (*in & 0x7f) << r;
|
||||||
if(*res >= (1 << 16)) {
|
if(*res >= (1 << 16)) {
|
||||||
|
@ -549,7 +541,7 @@ static uint8_t* decode_length(ssize_t *res, uint8_t *in, uint8_t *last,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(*in & (1 << 7)) {
|
if(in == last || *in & (1 << 7)) {
|
||||||
*res = -1;
|
*res = -1;
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -584,14 +576,14 @@ static int emit_indname_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
uint8_t *bufp;
|
uint8_t *bufp;
|
||||||
size_t encvallen = nghttp2_hd_huff_encode_count(value, valuelen, side);
|
size_t encvallen = nghttp2_hd_huff_encode_count(value, valuelen, side);
|
||||||
size_t blocklen = count_encoded_length(index + 1, 6) +
|
size_t blocklen = count_encoded_length(index + 1, 6) +
|
||||||
count_encoded_length(encvallen, 0) + encvallen;
|
count_encoded_length(encvallen, 8) + encvallen;
|
||||||
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
bufp = *buf_ptr + *offset_ptr;
|
bufp = *buf_ptr + *offset_ptr;
|
||||||
bufp += encode_length(bufp, index + 1, 6);
|
bufp += encode_length(bufp, index + 1, 6);
|
||||||
bufp += encode_length(bufp, encvallen, 0);
|
bufp += encode_length(bufp, encvallen, 8);
|
||||||
nghttp2_hd_huff_encode(bufp, *buflen_ptr - (bufp - *buf_ptr),
|
nghttp2_hd_huff_encode(bufp, *buflen_ptr - (bufp - *buf_ptr),
|
||||||
value, valuelen, side);
|
value, valuelen, side);
|
||||||
if(!inc_indexing) {
|
if(!inc_indexing) {
|
||||||
|
@ -613,19 +605,19 @@ static int emit_newname_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
nghttp2_hd_huff_encode_count(nv->name, nv->namelen, side);
|
nghttp2_hd_huff_encode_count(nv->name, nv->namelen, side);
|
||||||
size_t encvallen =
|
size_t encvallen =
|
||||||
nghttp2_hd_huff_encode_count(nv->value, nv->valuelen, side);
|
nghttp2_hd_huff_encode_count(nv->value, nv->valuelen, side);
|
||||||
size_t blocklen = 1 + count_encoded_length(encnamelen, 0) + encnamelen +
|
size_t blocklen = 1 + count_encoded_length(encnamelen, 8) + encnamelen +
|
||||||
count_encoded_length(encvallen, 0) + encvallen;
|
count_encoded_length(encvallen, 8) + encvallen;
|
||||||
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
bufp = *buf_ptr + *offset_ptr;
|
bufp = *buf_ptr + *offset_ptr;
|
||||||
*bufp++ = inc_indexing ? 0 : 0x40u;
|
*bufp++ = inc_indexing ? 0 : 0x40u;
|
||||||
bufp += encode_length(bufp, encnamelen, 0);
|
bufp += encode_length(bufp, encnamelen, 8);
|
||||||
nghttp2_hd_huff_encode(bufp, *buflen_ptr - (bufp - *buf_ptr),
|
nghttp2_hd_huff_encode(bufp, *buflen_ptr - (bufp - *buf_ptr),
|
||||||
nv->name, nv->namelen, side);
|
nv->name, nv->namelen, side);
|
||||||
bufp += encnamelen;
|
bufp += encnamelen;
|
||||||
bufp += encode_length(bufp, encvallen, 0);
|
bufp += encode_length(bufp, encvallen, 8);
|
||||||
nghttp2_hd_huff_encode(bufp, *buflen_ptr - (bufp - *buf_ptr),
|
nghttp2_hd_huff_encode(bufp, *buflen_ptr - (bufp - *buf_ptr),
|
||||||
nv->value, nv->valuelen, side);
|
nv->value, nv->valuelen, side);
|
||||||
*offset_ptr += blocklen;
|
*offset_ptr += blocklen;
|
||||||
|
@ -988,7 +980,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
in = decode_length(&namelen, in, last, 0);
|
in = decode_length(&namelen, in, last, 8);
|
||||||
if(namelen < 0 || in + namelen > last) {
|
if(namelen < 0 || in + namelen > last) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1006,7 +998,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
in = decode_length(&valuelen, in, last, 0);
|
in = decode_length(&valuelen, in, last, 8);
|
||||||
if(valuelen < 0 || in + valuelen > last) {
|
if(valuelen < 0 || in + valuelen > last) {
|
||||||
free(nv.name);
|
free(nv.name);
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
@ -1057,7 +1049,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
ent = nghttp2_hd_table_get(inflater, index);
|
ent = nghttp2_hd_table_get(inflater, index);
|
||||||
in = decode_length(&valuelen, in , last, 0);
|
in = decode_length(&valuelen, in , last, 8);
|
||||||
if(valuelen < 0 || in + valuelen > last) {
|
if(valuelen < 0 || in + valuelen > last) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -1597,11 +1597,16 @@ int nghttp2_session_send(nghttp2_session *session)
|
||||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
session->aob.framebufoff += sentlen;
|
if(session->aob.item->frame_cat == NGHTTP2_CAT_DATA &&
|
||||||
if(session->aob.item->frame_cat == NGHTTP2_CAT_DATA) {
|
session->aob.framebufoff + sentlen > NGHTTP2_FRAME_HEAD_LENGTH) {
|
||||||
nghttp2_data *frame;
|
nghttp2_data *frame;
|
||||||
nghttp2_stream *stream;
|
nghttp2_stream *stream;
|
||||||
uint16_t len = nghttp2_get_uint16(&session->aob.framebuf[0]);
|
uint16_t len;
|
||||||
|
if(session->aob.framebufoff < NGHTTP2_FRAME_HEAD_LENGTH) {
|
||||||
|
len = session->aob.framebufoff + sentlen - NGHTTP2_FRAME_HEAD_LENGTH;
|
||||||
|
} else {
|
||||||
|
len = sentlen;
|
||||||
|
}
|
||||||
frame = nghttp2_outbound_item_get_data_frame(session->aob.item);
|
frame = nghttp2_outbound_item_get_data_frame(session->aob.item);
|
||||||
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||||
if(stream && stream->remote_flow_control) {
|
if(stream && stream->remote_flow_control) {
|
||||||
|
@ -1611,6 +1616,7 @@ int nghttp2_session_send(nghttp2_session *session)
|
||||||
session->remote_window_size -= len;
|
session->remote_window_size -= len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
session->aob.framebufoff += sentlen;
|
||||||
if(session->aob.framebufoff == session->aob.framebuflen) {
|
if(session->aob.framebufoff == session->aob.framebuflen) {
|
||||||
/* Frame has completely sent */
|
/* Frame has completely sent */
|
||||||
r = nghttp2_session_after_frame_sent(session);
|
r = nghttp2_session_after_frame_sent(session);
|
||||||
|
|
|
@ -68,6 +68,7 @@ typedef struct {
|
||||||
int data_chunk_recv_cb_called;
|
int data_chunk_recv_cb_called;
|
||||||
int data_recv_cb_called;
|
int data_recv_cb_called;
|
||||||
const nghttp2_frame *frame;
|
const nghttp2_frame *frame;
|
||||||
|
size_t fixed_sendlen;
|
||||||
} my_user_data;
|
} my_user_data;
|
||||||
|
|
||||||
static void scripted_data_feed_init(scripted_data_feed *df,
|
static void scripted_data_feed_init(scripted_data_feed *df,
|
||||||
|
@ -94,6 +95,15 @@ static ssize_t fail_send_callback(nghttp2_session *session,
|
||||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t fixed_bytes_send_callback(nghttp2_session *session,
|
||||||
|
const uint8_t *data, size_t len,
|
||||||
|
int flags, void *user_data)
|
||||||
|
{
|
||||||
|
size_t fixed_sendlen = ((my_user_data*)user_data)->fixed_sendlen;
|
||||||
|
return fixed_sendlen < len ? fixed_sendlen : len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t scripted_recv_callback(nghttp2_session *session,
|
static ssize_t scripted_recv_callback(nghttp2_session *session,
|
||||||
uint8_t* data, size_t len, int flags,
|
uint8_t* data, size_t len, int flags,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
|
@ -2979,12 +2989,15 @@ void test_nghttp2_session_flow_control(void)
|
||||||
nghttp2_frame settings_frame;
|
nghttp2_frame settings_frame;
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||||
callbacks.send_callback = null_send_callback;
|
callbacks.send_callback = fixed_bytes_send_callback;
|
||||||
callbacks.on_frame_send_callback = on_frame_send_callback;
|
callbacks.on_frame_send_callback = on_frame_send_callback;
|
||||||
data_prd.read_callback = fixed_length_data_source_read_callback;
|
data_prd.read_callback = fixed_length_data_source_read_callback;
|
||||||
|
|
||||||
ud.frame_send_cb_called = 0;
|
ud.frame_send_cb_called = 0;
|
||||||
ud.data_source_length = 128*1024;
|
ud.data_source_length = 128*1024;
|
||||||
|
/* Use smaller emission count so that we can check outbound flow
|
||||||
|
control window calculation is correct. */
|
||||||
|
ud.fixed_sendlen = 2*1024;
|
||||||
|
|
||||||
/* Initial window size to 64KiB - 1*/
|
/* Initial window size to 64KiB - 1*/
|
||||||
nghttp2_session_client_new(&session, &callbacks, &ud);
|
nghttp2_session_client_new(&session, &callbacks, &ud);
|
||||||
|
|
Loading…
Reference in New Issue