Fix outbound flow control count

We wrongly added the whole payload length even if we sent part of it.
This commit is contained in:
Tatsuhiro Tsujikawa 2013-10-18 19:43:59 +09:00
parent 7bd145fd23
commit 0efa6e657f
2 changed files with 23 additions and 4 deletions

View File

@ -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);

View File

@ -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)
@ -2949,12 +2959,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);