[libsoup] io-http2: ensure we always finish the stream
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] io-http2: ensure we always finish the stream
- Date: Thu, 20 May 2021 12:32:50 +0000 (UTC)
commit c8d96bb31481e8027146e823a25bd629b8521f12
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Thu May 20 14:28:59 2021 +0200
io-http2: ensure we always finish the stream
In case of cancellation, we destroy the io data for the message but the
session keeps processing the stream.
libsoup/http2/soup-client-message-io-http2.c | 5 ++--
tests/http2-test.c | 42 ++++++++++++++++++++++------
2 files changed, 36 insertions(+), 11 deletions(-)
---
diff --git a/libsoup/http2/soup-client-message-io-http2.c b/libsoup/http2/soup-client-message-io-http2.c
index 8979592d..1fec42ab 100644
--- a/libsoup/http2/soup-client-message-io-http2.c
+++ b/libsoup/http2/soup-client-message-io-http2.c
@@ -918,9 +918,6 @@ soup_client_message_io_http2_finished (SoupClientMessageIO *iface,
h2_debug (io, data, "Finished: %s", completion == SOUP_MESSAGE_IO_COMPLETE ? "completed" :
"interrupted");
- // int ret;
- // ret = nghttp2_submit_rst_stream (io->session, NGHTTP2_FLAG_NONE, data->stream_id,
NGHTTP2_STREAM_CLOSED);
- // g_assert (ret == 0);
// ret = nghttp2_session_terminate_session (io->session, NGHTTP2_NO_ERROR);
// g_assert (ret == 0);
@@ -929,6 +926,8 @@ soup_client_message_io_http2_finished (SoupClientMessageIO *iface,
g_object_ref (msg);
+ NGCHECK (nghttp2_submit_rst_stream (io->session, NGHTTP2_FLAG_NONE, data->stream_id,
+ completion == SOUP_MESSAGE_IO_COMPLETE ? NGHTTP2_NO_ERROR :
NGHTTP2_CANCEL));
nghttp2_session_set_stream_user_data (io->session, data->stream_id, NULL);
if (!g_hash_table_remove (io->messages, msg))
g_warn_if_reached ();
diff --git a/tests/http2-test.c b/tests/http2-test.c
index c12f86a0..26d2b5c9 100644
--- a/tests/http2-test.c
+++ b/tests/http2-test.c
@@ -173,28 +173,44 @@ do_multi_message_async_test (Test *test, gconstpointer data)
static void
-on_send_and_read_complete (GObject *source, GAsyncResult *res, gpointer user_data)
+on_send_and_read_cancelled_complete (SoupSession *session,
+ GAsyncResult *result,
+ gboolean *done)
{
- SoupSession *sess = SOUP_SESSION (source);
- gboolean *done = user_data;
GError *error = NULL;
- GBytes *response = soup_session_send_and_read_finish (sess, res, &error);
+ GBytes *response = soup_session_send_and_read_finish (session, result, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
g_assert_null (response);
+ g_error_free (error);
+ *done = TRUE;
+}
+
+static void
+on_send_and_read_complete (SoupSession *session,
+ GAsyncResult *result,
+ gboolean *done)
+{
+ GError *error = NULL;
+ GBytes *response = soup_session_send_and_read_finish (session, result, &error);
+
+ g_assert_no_error (error);
+ g_assert_nonnull (response);
+ g_bytes_unref (response);
*done = TRUE;
}
static void
do_cancellation_test (Test *test, gconstpointer data)
{
- test->msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/large");
+ SoupMessage *msg;
GMainContext *async_context = g_main_context_ref_thread_default ();
GCancellable *cancellable = g_cancellable_new ();
gboolean done = FALSE;
- soup_session_send_and_read_async (test->session, test->msg, G_PRIORITY_DEFAULT, cancellable,
- on_send_and_read_complete, &done);
+ msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/large");
+ soup_session_send_and_read_async (test->session, msg, G_PRIORITY_DEFAULT, cancellable,
+ (GAsyncReadyCallback)on_send_and_read_cancelled_complete, &done);
/* Just iterate until a partial read is happening */
for (guint i = 100000; i; i--)
@@ -206,7 +222,17 @@ do_cancellation_test (Test *test, gconstpointer data)
while (!done)
g_main_context_iteration (async_context, FALSE);
- g_object_unref (test->msg);
+ g_object_unref (msg);
+
+ done = FALSE;
+ msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/large");
+ soup_session_send_and_read_async (test->session, msg, G_PRIORITY_DEFAULT, NULL,
+ (GAsyncReadyCallback)on_send_and_read_complete, &done);
+
+ while (!done)
+ g_main_context_iteration (async_context, FALSE);
+
+ g_object_unref (msg);
g_object_unref (cancellable);
g_main_context_unref (async_context);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]