Fix DATA is not consumed if nghttp2_http_on_data_chunk failed
This commit fixes the bug that DATA is not consumed if nghttp2_http_on_data_chunk is failed. It also simplify the handling of missing stream in NGHTTP2_IB_READ_DATA state.
This commit is contained in:
parent
693fba3b64
commit
c70cfe64c4
|
@ -5739,6 +5739,14 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|||
|
||||
break;
|
||||
case NGHTTP2_IB_READ_DATA:
|
||||
stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
|
||||
|
||||
if (!stream) {
|
||||
busy = 1;
|
||||
iframe->state = NGHTTP2_IB_IGN_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUGF(fprintf(stderr, "recv: [IB_READ_DATA]\n"));
|
||||
|
||||
readlen = inbound_frame_payload_readlen(iframe, in, last);
|
||||
|
@ -5756,68 +5764,65 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|||
return rv;
|
||||
}
|
||||
|
||||
stream =
|
||||
nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
|
||||
if (stream) {
|
||||
rv = session_update_recv_stream_window_size(
|
||||
session, stream, readlen,
|
||||
iframe->payloadleft ||
|
||||
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
|
||||
rv = 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;
|
||||
}
|
||||
|
||||
data_readlen = inbound_frame_effective_readlen(
|
||||
iframe, iframe->payloadleft, readlen);
|
||||
|
||||
padlen = readlen - data_readlen;
|
||||
|
||||
if (padlen > 0) {
|
||||
/* Padding is considered as "consumed" immediately */
|
||||
rv = nghttp2_session_consume(session, iframe->frame.hd.stream_id,
|
||||
padlen);
|
||||
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
data_readlen = inbound_frame_effective_readlen(
|
||||
iframe, iframe->payloadleft, readlen);
|
||||
DEBUGF(fprintf(stderr, "recv: data_readlen=%zd\n", data_readlen));
|
||||
|
||||
padlen = readlen - data_readlen;
|
||||
if (data_readlen > 0) {
|
||||
if (session_enforce_http_messaging(session)) {
|
||||
if (nghttp2_http_on_data_chunk(stream, data_readlen) != 0) {
|
||||
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
||||
/* Consume all data for connection immediately here */
|
||||
rv = session_update_connection_consumed_size(session,
|
||||
data_readlen);
|
||||
|
||||
if (padlen > 0) {
|
||||
/* Padding is considered as "consumed" immediately */
|
||||
rv = nghttp2_session_consume(session, iframe->frame.hd.stream_id,
|
||||
padlen);
|
||||
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUGF(fprintf(stderr, "recv: data_readlen=%zd\n", data_readlen));
|
||||
|
||||
if (data_readlen > 0) {
|
||||
if (session_enforce_http_messaging(session)) {
|
||||
if (nghttp2_http_on_data_chunk(stream, data_readlen) != 0) {
|
||||
rv = nghttp2_session_add_rst_stream(session,
|
||||
iframe->frame.hd.stream_id,
|
||||
NGHTTP2_PROTOCOL_ERROR);
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
busy = 1;
|
||||
iframe->state = NGHTTP2_IB_IGN_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (session->callbacks.on_data_chunk_recv_callback) {
|
||||
rv = session->callbacks.on_data_chunk_recv_callback(
|
||||
session, iframe->frame.hd.flags, iframe->frame.hd.stream_id,
|
||||
in - readlen, data_readlen, session->user_data);
|
||||
if (rv == NGHTTP2_ERR_PAUSE) {
|
||||
return in - first;
|
||||
}
|
||||
|
||||
rv = nghttp2_session_add_rst_stream(
|
||||
session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR);
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
busy = 1;
|
||||
iframe->state = NGHTTP2_IB_IGN_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
||||
/* stream was closed or does not exist. Consume all data
|
||||
for connection immediately here */
|
||||
rv = session_update_connection_consumed_size(session, readlen);
|
||||
if (session->callbacks.on_data_chunk_recv_callback) {
|
||||
rv = session->callbacks.on_data_chunk_recv_callback(
|
||||
session, iframe->frame.hd.flags, iframe->frame.hd.stream_id,
|
||||
in - readlen, data_readlen, session->user_data);
|
||||
if (rv == NGHTTP2_ERR_PAUSE) {
|
||||
return in - first;
|
||||
}
|
||||
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue