diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index 75be754f..1debddd6 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -1328,6 +1328,41 @@ static int nghttp2_session_predicate_window_update_send return 0; } +/* + * This function checks ALTSVC with the stream ID |stream_id| can be + * sent at this time. If |stream_id| is 0, ATLSVC frame is always + * allowed to send. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * NGHTTP2_ERR_STREAM_CLOSED + * The stream is already closed or does not exist. + * NGHTTP2_ERR_STREAM_CLOSING + * RST_STREAM was queued for this stream. + */ +static int nghttp2_session_predicate_altsvc_send +(nghttp2_session *session, int32_t stream_id) +{ + nghttp2_stream *stream; + + if(stream_id == 0) { + return 0; + } + + stream = nghttp2_session_get_stream(session, stream_id); + + if(stream == NULL) { + return NGHTTP2_ERR_STREAM_CLOSED; + } + + if(stream->state == NGHTTP2_STREAM_CLOSING) { + return NGHTTP2_ERR_STREAM_CLOSING; + } + + return 0; +} + /* * This function checks SETTINGS can be sent at this time. * @@ -1678,6 +1713,11 @@ static int nghttp2_session_prep_frame(nghttp2_session *session, } break; case NGHTTP2_ALTSVC: + rv = nghttp2_session_predicate_altsvc_send(session, frame->hd.stream_id); + if(rv != 0) { + return rv; + } + framerv = nghttp2_frame_pack_altsvc(&session->aob.framebufs, &frame->altsvc); diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index 5f5f451b..8b11289f 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -3496,6 +3496,8 @@ void test_nghttp2_submit_altsvc(void) nghttp2_session_server_new(&session, &callbacks, &ud); + open_stream(session, 9); + CU_ASSERT(0 == nghttp2_submit_altsvc(session, NGHTTP2_FLAG_NONE, 9, 12345, 3000,