diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2022-11-10 12:50:19 +0100 |
---|---|---|
committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2022-11-10 12:50:19 +0100 |
commit | ab3767f07a075c9e1e847ac45559924eed9b4a3e (patch) | |
tree | 78b337fe847ab522f11df235bff9fe492b94865b | |
parent | d20c6601664624116f3dc43f21c7ec4a186cf8d3 (diff) | |
download | libsoup-ab3767f07a075c9e1e847ac45559924eed9b4a3e.tar.gz |
server: close http/2 connection after io error or goaway received
-rw-r--r-- | libsoup/server/http2/soup-server-message-io-http2.c | 44 | ||||
-rw-r--r-- | tests/server-test.c | 13 |
2 files changed, 43 insertions, 14 deletions
diff --git a/libsoup/server/http2/soup-server-message-io-http2.c b/libsoup/server/http2/soup-server-message-io-http2.c index e9e2fbfb..f782dcef 100644 --- a/libsoup/server/http2/soup-server-message-io-http2.c +++ b/libsoup/server/http2/soup-server-message-io-http2.c @@ -364,12 +364,18 @@ io_write_ready (GObject *stream, return G_SOURCE_CONTINUE; } - if (error && soup_server_connection_get_io_data (conn) == (SoupServerMessageIO *)io) - h2_debug (io, NULL, "[SESSION] IO error: %s", error->message); + if (soup_server_connection_get_io_data (conn) == (SoupServerMessageIO *)io) { + if (error) + h2_debug (io, NULL, "[SESSION] IO error: %s", error->message); + + g_clear_pointer (&io->write_source, g_source_unref); + + if (error || (!nghttp2_session_want_read (io->session) && !nghttp2_session_want_write (io->session))) + soup_server_connection_disconnect (conn); + } g_clear_error (&error); g_object_unref (conn); - g_clear_pointer (&io->write_source, g_source_unref); return G_SOURCE_REMOVE; } @@ -388,16 +394,21 @@ io_try_write (SoupServerMessageIOHTTP2 *io) while (!error && soup_server_connection_get_io_data (conn) == (SoupServerMessageIO *)io && !io->in_callback && nghttp2_session_want_write (io->session)) io_write (io, &error); - if (io->in_callback || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { - g_clear_error (&error); - io->write_source = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (io->ostream), NULL); - g_source_set_name (io->write_source, "Soup server HTTP/2 write source"); - g_source_set_callback (io->write_source, (GSourceFunc)io_write_ready, io, NULL); - g_source_attach (io->write_source, g_main_context_get_thread_default ()); - } + if (soup_server_connection_get_io_data (conn) == (SoupServerMessageIO *)io) { + if (io->in_callback || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { + g_clear_error (&error); + io->write_source = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (io->ostream), NULL); + g_source_set_name (io->write_source, "S oup server HTTP/2 write source"); + g_source_set_callback (io->write_source, (GSourceFunc)io_write_ready, io, NULL); + g_source_attach (io->write_source, g_main_context_get_thread_default ()); + } - if (error && soup_server_connection_get_io_data (conn) == (SoupServerMessageIO *)io) - h2_debug (io, NULL, "[SESSION] IO error: %s", error->message); + if (error) + h2_debug (io, NULL, "[SESSION] IO error: %s", error->message); + + if (error || (!nghttp2_session_want_read (io->session) && !nghttp2_session_want_write (io->session))) + soup_server_connection_disconnect (conn); + } g_clear_error (&error); g_object_unref (conn); @@ -450,8 +461,13 @@ io_read_ready (GObject *stream, return G_SOURCE_CONTINUE; } - if (error && soup_server_connection_get_io_data (conn) == (SoupServerMessageIO *)io) - h2_debug (io, NULL, "[SESSION] IO error: %s", error->message); + if (soup_server_connection_get_io_data (conn) == (SoupServerMessageIO *)io) { + if (error) + h2_debug (io, NULL, "[SESSION] IO error: %s", error->message); + + if (error || (!nghttp2_session_want_read (io->session) && !nghttp2_session_want_write (io->session))) + soup_server_connection_disconnect (conn); + } g_clear_error (&error); g_object_unref (conn); diff --git a/tests/server-test.c b/tests/server-test.c index 12bfd980..8d0c38bb 100644 --- a/tests/server-test.c +++ b/tests/server-test.c @@ -1325,6 +1325,8 @@ do_idle_connection_closed_test (ServerData *sd, gconstpointer test_data) GError *error = NULL; GSList *clients; + soup_server_set_http2_enabled (sd->server, tls_available); + session = soup_test_session_new (NULL); msg = soup_message_new_from_uri ("GET", sd->base_uri); @@ -1336,6 +1338,17 @@ do_idle_connection_closed_test (ServerData *sd, gconstpointer test_data) clients = soup_server_get_clients (sd->server); g_assert_cmpuint (g_slist_length (clients), ==, 1); + if (tls_available) { + msg = soup_message_new_from_uri ("GET", sd->ssl_base_uri); + body = soup_session_send_and_read (session, msg, NULL, &error); + g_assert_no_error (error); + g_bytes_unref (body); + g_object_unref (msg); + + clients = soup_server_get_clients (sd->server); + g_assert_cmpuint (g_slist_length (clients), ==, 2); + } + soup_test_session_abort_unref (session); while (soup_server_get_clients (sd->server)) |