@@ -64,6 +64,9 @@ static int stream_open(h2_session *session, int stream_id)
6464 stream = h2_mplx_open_io (session -> mplx , stream_id );
6565 if (stream ) {
6666 h2_stream_set_add (session -> streams , stream );
67+ if (stream -> id > session -> max_stream_received ) {
68+ session -> max_stream_received = stream -> id ;
69+ }
6770
6871 ap_log_cerror (APLOG_MARK , APLOG_DEBUG , 0 , session -> c ,
6972 "h2_session: stream(%ld-%d): opened" ,
@@ -223,10 +226,25 @@ static int on_frame_not_send_cb(nghttp2_session *ngh2,
223226 return 0 ;
224227}
225228
226- static apr_status_t stream_destroy (h2_session * session , h2_stream * stream )
229+ static apr_status_t stream_destroy (h2_session * session ,
230+ h2_stream * stream ,
231+ uint32_t error_code )
227232{
228- ap_log_cerror (APLOG_MARK , APLOG_DEBUG , 0 , session -> c ,
229- "h2_stream(%ld-%d): closing" , session -> id , (int )stream -> id );
233+ if (!error_code ) {
234+ ap_log_cerror (APLOG_MARK , APLOG_DEBUG , 0 , session -> c ,
235+ "h2_stream(%ld-%d): handled, closing" ,
236+ session -> id , (int )stream -> id );
237+ if (stream -> id > session -> max_stream_handled ) {
238+ session -> max_stream_handled = stream -> id ;
239+ }
240+ }
241+ else {
242+ ap_log_cerror (APLOG_MARK , APLOG_DEBUG , 0 , session -> c ,
243+ "h2_stream(%ld-%d): closing with err=%d %s" ,
244+ session -> id , (int )stream -> id , (int )error_code ,
245+ nghttp2_strerror (error_code ));
246+ }
247+
230248 h2_stream_set_remove (session -> streams , stream );
231249 return h2_mplx_cleanup_stream (session -> mplx , stream );
232250}
@@ -243,7 +261,7 @@ static int on_stream_close_cb(nghttp2_session *ngh2, int32_t stream_id,
243261 }
244262 stream = h2_stream_set_get (session -> streams , stream_id );
245263 if (stream ) {
246- stream_destroy (session , stream );
264+ stream_destroy (session , stream , error_code );
247265 }
248266
249267 if (error_code ) {
@@ -655,50 +673,43 @@ void h2_session_destroy(h2_session *session)
655673 }
656674}
657675
658- apr_status_t h2_session_goaway (h2_session * session , apr_status_t reason )
659- {
660- apr_status_t status = APR_SUCCESS ;
661- int rv ;
662- AP_DEBUG_ASSERT (session );
663- if (session -> aborted ) {
664- return APR_EINVAL ;
665- }
666-
667- rv = 0 ;
668- if (reason == APR_SUCCESS ) {
669- rv = nghttp2_submit_shutdown_notice (session -> ngh2 );
670- }
671- else {
672- int err = 0 ;
673- int last_id = nghttp2_session_get_last_proc_stream_id (session -> ngh2 );
674- rv = nghttp2_submit_goaway (session -> ngh2 , last_id ,
675- NGHTTP2_FLAG_NONE , err , NULL , 0 );
676- }
677- if (rv != 0 ) {
678- status = APR_EGENERAL ;
679- ap_log_cerror (APLOG_MARK , APLOG_ERR , status , session -> c ,
680- APLOGNO (02930 ) "session(%ld): submit goaway: %s" ,
681- session -> id , nghttp2_strerror (rv ));
682- }
683- return status ;
684- }
685-
686676static apr_status_t h2_session_abort_int (h2_session * session , int reason )
687677{
688678 AP_DEBUG_ASSERT (session );
689679 if (!session -> aborted ) {
690680 session -> aborted = 1 ;
691681 if (session -> ngh2 ) {
692- if (reason ) {
693- ap_log_cerror (APLOG_MARK , (reason == NGHTTP2_ERR_EOF )?
694- APLOG_DEBUG : APLOG_INFO , 0 , session -> c ,
682+
683+ if (!reason ) {
684+ nghttp2_submit_goaway (session -> ngh2 , NGHTTP2_FLAG_NONE ,
685+ session -> max_stream_received ,
686+ reason , NULL , 0 );
687+ nghttp2_session_send (session -> ngh2 );
688+ h2_conn_io_flush (& session -> io );
689+ }
690+ else {
691+ const char * err = nghttp2_strerror (reason );
692+
693+ ap_log_cerror (APLOG_MARK , APLOG_DEBUG , 0 , session -> c ,
695694 "session(%ld): aborting session, reason=%d %s" ,
696- session -> id , reason , nghttp2_strerror (reason ));
695+ session -> id , reason , err );
696+
697+ if (NGHTTP2_ERR_EOF == reason ) {
698+ /* This is our way of indication that the connection is
699+ * gone. No use to send any GOAWAY frames. */
700+ nghttp2_session_terminate_session (session -> ngh2 , reason );
701+ }
702+ else {
703+ /* The connection might still be there and we shut down
704+ * with GOAWAY and reason information. */
705+ nghttp2_submit_goaway (session -> ngh2 , NGHTTP2_FLAG_NONE ,
706+ session -> max_stream_received ,
707+ reason , (const uint8_t * )err ,
708+ strlen (err ));
709+ nghttp2_session_send (session -> ngh2 );
710+ h2_conn_io_flush (& session -> io );
711+ }
697712 }
698- nghttp2_session_terminate_session (session -> ngh2 , reason );
699- nghttp2_submit_goaway (session -> ngh2 , 0 , 0 , reason , NULL , 0 );
700- nghttp2_session_send (session -> ngh2 );
701- h2_conn_io_flush (& session -> io );
702713 }
703714 h2_mplx_abort (session -> mplx );
704715 }
@@ -714,10 +725,12 @@ apr_status_t h2_session_abort(h2_session *session, apr_status_t reason, int rv)
714725 case APR_ENOMEM :
715726 rv = NGHTTP2_ERR_NOMEM ;
716727 break ;
717- case APR_EOF :
718- rv = 0 ;
728+ case APR_SUCCESS : /* all fine, just... */
729+ case APR_EOF : /* client closed its end... */
730+ case APR_TIMEUP : /* got bored waiting... */
731+ rv = 0 ; /* ...gracefully shut down */
719732 break ;
720- case APR_EBADF :
733+ case APR_EBADF : /* connection unusable, terminate silently */
721734 case APR_ECONNABORTED :
722735 rv = NGHTTP2_ERR_EOF ;
723736 break ;
@@ -1006,7 +1019,7 @@ apr_status_t h2_session_read(h2_session *session, apr_read_type_e block)
10061019apr_status_t h2_session_close (h2_session * session )
10071020{
10081021 AP_DEBUG_ASSERT (session );
1009- return h2_conn_io_flush (& session -> io );
1022+ return session -> aborted ? APR_SUCCESS : h2_conn_io_flush (& session -> io );
10101023}
10111024
10121025/* The session wants to send more DATA for the given stream.
0 commit comments