Skip to content

Commit

Permalink
Contribute flow control window for each byte PAD_HIGH and _LOW in DATA
Browse files Browse the repository at this point in the history
This may help the pathological situation where window is too small.
  • Loading branch information
tatsuhiro-t committed Feb 12, 2014
1 parent c7a1709 commit 082876d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 33 deletions.
78 changes: 45 additions & 33 deletions lib/nghttp2_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -3534,7 +3534,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
break;
}
if(rv == 1) {
iframe->state = NGHTTP2_IB_READ_NBYTE;
iframe->state = NGHTTP2_IB_READ_PAD_DATA;
break;
}
iframe->state = NGHTTP2_IB_READ_DATA;
Expand Down Expand Up @@ -3675,38 +3675,6 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
return in - first;
}
switch(iframe->frame.hd.type) {
case NGHTTP2_DATA:
busy = 1;
rv = inbound_frame_compute_pad(iframe);
if(rv < 0) {
rv = nghttp2_session_terminate_session(session,
NGHTTP2_PROTOCOL_ERROR);
if(nghttp2_is_fatal(rv)) {
return rv;
}
iframe->state = NGHTTP2_IB_IGN_DATA;
break;
}
iframe->frame.data.padlen = rv;
iframe->state = NGHTTP2_IB_READ_DATA;
/* PAD_HIGH and PAD_LOW are subject to flow control */
rv = nghttp2_session_update_recv_connection_window_size
(session, iframe->buflen);
if(nghttp2_is_fatal(rv)) {
return rv;
}
stream = nghttp2_session_get_stream(session,
iframe->frame.hd.stream_id);
if(stream) {
rv = nghttp2_session_update_recv_stream_window_size
(session, stream, iframe->buflen,
iframe->payloadleft ||
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
if(nghttp2_is_fatal(rv)) {
return rv;
}
}
break;
case NGHTTP2_HEADERS:
if(iframe->padlen == 0 &&
iframe->frame.hd.flags & NGHTTP2_FLAG_PAD_LOW) {
Expand Down Expand Up @@ -4072,6 +4040,50 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
}
break;
case NGHTTP2_IB_READ_PAD_DATA:
DEBUGF(fprintf(stderr, "[IB_READ_PAD_DATA]\n"));
readlen = inbound_frame_buf_read(iframe, in, last);
in += readlen;
iframe->payloadleft -= readlen;
DEBUGF(fprintf(stderr, "readlen=%zu, payloadleft=%zu, left=%zu\n",
readlen, iframe->payloadleft, iframe->left));

/* PAD_HIGH and PAD_LOW are subject to flow control */
rv = nghttp2_session_update_recv_connection_window_size
(session, readlen);
if(nghttp2_is_fatal(rv)) {
return rv;
}
stream = nghttp2_session_get_stream(session,
iframe->frame.hd.stream_id);
if(stream) {
rv = nghttp2_session_update_recv_stream_window_size
(session, stream, readlen,
iframe->payloadleft ||
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
if(nghttp2_is_fatal(rv)) {
return rv;
}
}

if(iframe->left) {
return in - first;
}

busy = 1;
rv = inbound_frame_compute_pad(iframe);
if(rv < 0) {
rv = nghttp2_session_terminate_session(session,
NGHTTP2_PROTOCOL_ERROR);
if(nghttp2_is_fatal(rv)) {
return rv;
}
iframe->state = NGHTTP2_IB_IGN_DATA;
break;
}
iframe->frame.data.padlen = rv;
iframe->state = NGHTTP2_IB_READ_DATA;
break;
case NGHTTP2_IB_READ_DATA:
DEBUGF(fprintf(stderr, "[IB_READ_DATA]\n"));
readlen = inbound_frame_payload_readlen(iframe, in, last);
Expand Down
1 change: 1 addition & 0 deletions lib/nghttp2_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ typedef enum {
NGHTTP2_IB_IGN_CONTINUATION,
NGHTTP2_IB_READ_PAD_CONTINUATION,
NGHTTP2_IB_IGN_PAD_CONTINUATION,
NGHTTP2_IB_READ_PAD_DATA,
NGHTTP2_IB_READ_DATA,
NGHTTP2_IB_IGN_DATA
} nghttp2_inbound_state;
Expand Down

0 comments on commit 082876d

Please sign in to comment.