Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libsoup for openSUSE:Factory checked in at 2023-09-20 13:21:52 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libsoup (Old) and /work/SRC/openSUSE:Factory/.libsoup.new.16627 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libsoup" Wed Sep 20 13:21:52 2023 rev:143 rq:1111608 version:3.4.3 Changes: -------- --- /work/SRC/openSUSE:Factory/libsoup/libsoup.changes 2023-05-02 16:18:31.697633301 +0200 +++ /work/SRC/openSUSE:Factory/.libsoup.new.16627/libsoup.changes 2023-09-20 13:22:17.435815755 +0200 @@ -1,0 +2,10 @@ +Fri Sep 15 15:11:03 UTC 2023 - Bjørn Lie <bjorn....@gmail.com> + +- Update to version 3.4.3: + + Fix incorrect UTF-8 encoding for params in headers + + Numerous HTTP/2 fixes and improvements + + Fix possible crashes in connection management + + Fix small leak in SoupServer + + Fix the possibility of empty HTTP/2 frames being sent + +------------------------------------------------------------------- Old: ---- libsoup-3.4.2.tar.xz New: ---- libsoup-3.4.3.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libsoup.spec ++++++ --- /var/tmp/diff_new_pack.qwG3dY/_old 2023-09-20 13:22:18.559856025 +0200 +++ /var/tmp/diff_new_pack.qwG3dY/_new 2023-09-20 13:22:18.559856025 +0200 @@ -18,7 +18,7 @@ %define api_version 3.0 Name: libsoup -Version: 3.4.2 +Version: 3.4.3 Release: 0 Summary: HTTP client/server library for GNOME License: LGPL-2.1-or-later ++++++ libsoup-3.4.2.tar.xz -> libsoup-3.4.3.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/NEWS new/libsoup-3.4.3/NEWS --- old/libsoup-3.4.2/NEWS 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/NEWS 2023-09-15 17:00:37.000000000 +0200 @@ -1,3 +1,11 @@ +Changes in libsoup from 3.4.2 to 3.4.3: + +* Fix incorrect UTF-8 encoding for params in headers [Leo Zi-You Assini] +* Numerous HTTP/2 fixes and improvements [Carlos Garcia Campos] +* Fix possible crashes in connection management [Michael Catanzaro] +* Fix small leak in SoupServer [Emil Ljungdahl] +* Fix the possibility of empty HTTP/2 frames being sent [Pawel Lampe] + Changes in libsoup from 3.4.1 to 3.4.2: * Revert changes to request cancellation [Patrick Griffis] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/auth/soup-connection-auth.c new/libsoup-3.4.3/libsoup/auth/soup-connection-auth.c --- old/libsoup-3.4.2/libsoup/auth/soup-connection-auth.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/auth/soup-connection-auth.c 2023-09-15 17:00:37.000000000 +0200 @@ -113,8 +113,8 @@ g_hash_table_insert (priv->conns, conn, state); g_mutex_unlock (&priv->lock); if (conn) { - g_signal_connect (conn, "disconnected", - G_CALLBACK (connection_disconnected), auth); + g_signal_connect_object (conn, "disconnected", + G_CALLBACK (connection_disconnected), auth, 0); } } else { g_mutex_unlock (&priv->lock); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/http2/soup-client-message-io-http2.c new/libsoup-3.4.3/libsoup/http2/soup-client-message-io-http2.c --- old/libsoup-3.4.2/libsoup/http2/soup-client-message-io-http2.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/http2/soup-client-message-io-http2.c 2023-09-15 17:00:37.000000000 +0200 @@ -61,6 +61,7 @@ GError *error; GSource *read_source; GSource *write_source; + GSource *write_idle_source; GHashTable *messages; GHashTable *closed_messages; @@ -91,8 +92,9 @@ GTask *task; gboolean in_io_try_sniff_content; - /* Request body logger */ + /* Request body */ SoupLogger *logger; + gssize request_body_bytes_to_write; /* Pollable data sources */ GSource *data_source_poll; @@ -354,6 +356,8 @@ return G_SOURCE_REMOVE; } +static gboolean io_write_idle_cb (SoupClientMessageIOHTTP2* io); + static void io_try_write (SoupClientMessageIOHTTP2 *io, gboolean blocking) @@ -366,12 +370,32 @@ if (io->in_callback) { if (blocking || !nghttp2_session_want_write (io->session)) return; - } else { - while (!error && nghttp2_session_want_write (io->session)) - io_write (io, blocking, NULL, &error); + + if (io->write_idle_source) + return; + + io->write_idle_source = g_idle_source_new (); +#if GLIB_CHECK_VERSION(2, 70, 0) + g_source_set_static_name (io->write_idle_source, "Soup HTTP/2 write idle source"); +#else + g_source_set_name (io->write_idle_source, "Soup HTTP/2 write idle source"); +#endif + /* Give write more priority than read */ + g_source_set_priority (io->write_idle_source, G_PRIORITY_DEFAULT - 1); + g_source_set_callback (io->write_idle_source, (GSourceFunc)io_write_idle_cb, io, NULL); + g_source_attach (io->write_idle_source, g_main_context_get_thread_default ()); + return; } - if (!blocking && (io->in_callback || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))) { + if (io->write_idle_source) { + g_source_destroy (io->write_idle_source); + g_clear_pointer (&io->write_idle_source, g_source_unref); + } + + while (!error && nghttp2_session_want_write (io->session)) + io_write (io, blocking, NULL, &error); + + if (!blocking && 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); #if GLIB_CHECK_VERSION(2, 70, 0) @@ -383,6 +407,7 @@ g_source_set_priority (io->write_source, G_PRIORITY_DEFAULT - 1); 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 ()); + return; } if (error) @@ -390,12 +415,20 @@ } static gboolean +io_write_idle_cb (SoupClientMessageIOHTTP2* io) +{ + g_clear_pointer (&io->write_idle_source, g_source_unref); + io_try_write (io, FALSE); + return G_SOURCE_REMOVE; +} + +static gboolean io_read (SoupClientMessageIOHTTP2 *io, gboolean blocking, GCancellable *cancellable, GError **error) { - guint8 buffer[8192]; + guint8 buffer[16384]; gssize read; int ret; @@ -713,6 +746,8 @@ data_provider.source.ptr = soup_message_get_request_body_stream (data->msg); data_provider.read_callback = on_data_source_read_callback; + goffset content_length = soup_message_headers_get_content_length (soup_message_get_request_headers (data->msg)); + data->request_body_bytes_to_write = content_length > 0 ? content_length : -1; nghttp2_submit_data (io->session, NGHTTP2_FLAG_END_STREAM, frame->hd.stream_id, &data_provider); io_try_write (io, !data->item->async); } @@ -742,6 +777,8 @@ break; } case NGHTTP2_DATA: + h2_debug (io, data, "[RECV] [DATA] window=%d/%d", nghttp2_session_get_stream_effective_recv_data_length (session, frame->hd.stream_id), + nghttp2_session_get_stream_effective_local_window_size (session, frame->hd.stream_id)); if (data->metrics) data->metrics->response_body_bytes_received += frame->data.hd.length + FRAME_HEADER_SIZE; soup_message_got_body_data (data->msg, frame->data.hd.length + FRAME_HEADER_SIZE); @@ -754,8 +791,7 @@ soup_http2_message_data_check_status (data); } } - } else { - /* Try to write after every data frame, since nghttp2 might need to send a window update. */ + } else if (nghttp2_session_get_stream_effective_recv_data_length (session, frame->hd.stream_id) == 0) { io_try_write (io, !data->item->async); } break; @@ -1055,8 +1091,14 @@ } else if (read == 0) { g_byte_array_set_size (data->data_source_buffer, 0); data->data_source_eof = TRUE; - } else + } else { + if (data->request_body_bytes_to_write > 0) { + data->request_body_bytes_to_write -= read; + if (data->request_body_bytes_to_write == 0) + data->data_source_eof = TRUE; + } g_byte_array_set_size (data->data_source_buffer, read); + } h2_debug (data->io, data, "[SEND_BODY] Resuming send"); NGCHECK (nghttp2_session_resume_data (data->io->session, data->stream_id)); @@ -1104,7 +1146,12 @@ read = g_input_stream_read (source->ptr, buf, length, data->item->cancellable, &error); if (read) { - h2_debug (data->io, data, "[SEND_BODY] Read %zd", read); + if (data->request_body_bytes_to_write > 0) { + data->request_body_bytes_to_write -= read; + if (data->request_body_bytes_to_write == 0) + *data_flags |= NGHTTP2_DATA_FLAG_EOF; + } + h2_debug (data->io, data, "[SEND_BODY] Read %zd%s", read, *data_flags & NGHTTP2_DATA_FLAG_EOF ? ", EOF" : ""); log_request_data (data, buf, read); } @@ -1132,7 +1179,12 @@ gssize read = g_pollable_input_stream_read_nonblocking (in_stream, buf, length, data->item->cancellable, &error); if (read) { - h2_debug (data->io, data, "[SEND_BODY] Read %zd", read); + if (data->request_body_bytes_to_write > 0) { + data->request_body_bytes_to_write -= read; + if (data->request_body_bytes_to_write == 0) + *data_flags |= NGHTTP2_DATA_FLAG_EOF; + } + h2_debug (data->io, data, "[SEND_BODY] Read %zd%s", read, *data_flags & NGHTTP2_DATA_FLAG_EOF ? ", EOF" : ""); log_request_data (data, buf, read); } @@ -1179,7 +1231,11 @@ guint buffer_len = data->data_source_buffer->len; if (buffer_len) { - h2_debug (data->io, data, "[SEND_BODY] Sending %zu", buffer_len); + if (data->data_source_eof) { + h2_debug (data->io, data, "[SEND_BODY] Sending %zu, EOF", buffer_len); + *data_flags |= NGHTTP2_DATA_FLAG_EOF; + } else + h2_debug (data->io, data, "[SEND_BODY] Sending %zu", buffer_len); g_assert (buffer_len <= length); /* QUESTION: Maybe not reliable */ memcpy (buf, data->data_source_buffer->data, buffer_len); log_request_data (data, buf, buffer_len); @@ -1257,6 +1313,7 @@ data->item = soup_message_queue_item_ref (item); data->msg = item->msg; data->metrics = soup_message_get_metrics (data->msg); + data->request_body_bytes_to_write = -1; data->completion_cb = completion_cb; data->completion_data = completion_data; data->stream_id = 0; @@ -1365,9 +1422,10 @@ g_array_append_val (headers, pseudo_headers[i]); } + SoupMessageHeaders *request_headers = soup_message_get_request_headers (msg); SoupMessageHeadersIter iter; const char *name, *value; - soup_message_headers_iter_init (&iter, soup_message_get_request_headers (msg)); + soup_message_headers_iter_init (&iter, request_headers); while (soup_message_headers_iter_next (&iter, &name, &value)) { if (!request_header_is_valid (name)) continue; @@ -1385,7 +1443,7 @@ nghttp2_priority_spec_init (&priority_spec, 0, message_priority_to_weight (msg), 0); int32_t stream_id; - if (body_stream && soup_message_headers_get_expectations (soup_message_get_request_headers (msg)) & SOUP_EXPECTATION_CONTINUE) { + if (body_stream && soup_message_headers_get_expectations (request_headers) & SOUP_EXPECTATION_CONTINUE) { data->expect_continue = TRUE; stream_id = nghttp2_submit_headers (io->session, 0, -1, &priority_spec, (const nghttp2_nv *)headers->data, headers->len, data); } else { @@ -1393,6 +1451,8 @@ if (body_stream) { data_provider.source.ptr = body_stream; data_provider.read_callback = on_data_source_read_callback; + goffset content_length = soup_message_headers_get_content_length (request_headers); + data->request_body_bytes_to_write = content_length > 0 ? content_length : -1; } stream_id = nghttp2_submit_request (io->session, &priority_spec, (const nghttp2_nv *)headers->data, headers->len, body_stream ? &data_provider : NULL, data); } @@ -1773,6 +1833,7 @@ io->owner = owner; g_assert (!io->write_source); + g_assert (!io->write_idle_source); if (io->read_source) { g_source_destroy (io->read_source); g_source_unref (io->read_source); @@ -1833,6 +1894,10 @@ g_source_destroy (io->write_source); g_source_unref (io->write_source); } + if (io->write_idle_source) { + g_source_destroy (io->write_idle_source); + g_source_unref (io->write_idle_source); + } g_weak_ref_clear (&io->conn); g_clear_object (&io->stream); @@ -1911,7 +1976,6 @@ io->iface.funcs = &io_funcs; } -#define INITIAL_WINDOW_SIZE (32 * 1024 * 1024) /* 32MB matches other implementations */ #define MAX_HEADER_TABLE_SIZE 65536 /* Match size used by Chromium/Firefox */ SoupClientMessageIO * @@ -1929,14 +1993,14 @@ soup_client_message_io_http2_set_owner (io, soup_connection_get_owner (conn)); - NGCHECK (nghttp2_session_set_local_window_size (io->session, NGHTTP2_FLAG_NONE, 0, INITIAL_WINDOW_SIZE)); - + int stream_window_size = soup_connection_get_http2_initial_stream_window_size (conn); const nghttp2_settings_entry settings[] = { - { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE }, + { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, stream_window_size }, { NGHTTP2_SETTINGS_HEADER_TABLE_SIZE, MAX_HEADER_TABLE_SIZE }, { NGHTTP2_SETTINGS_ENABLE_PUSH, 0 }, }; NGCHECK (nghttp2_submit_settings (io->session, NGHTTP2_FLAG_NONE, settings, G_N_ELEMENTS (settings))); + NGCHECK (nghttp2_session_set_local_window_size (io->session, NGHTTP2_FLAG_NONE, 0, soup_connection_get_http2_initial_window_size (conn))); io_try_write (io, !io->async); return (SoupClientMessageIO *)io; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/server/http2/soup-server-message-io-http2.c new/libsoup-3.4.3/libsoup/server/http2/soup-server-message-io-http2.c --- old/libsoup-3.4.2/libsoup/server/http2/soup-server-message-io-http2.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/server/http2/soup-server-message-io-http2.c 2023-09-15 17:00:37.000000000 +0200 @@ -54,6 +54,7 @@ GSource *read_source; GSource *write_source; + GSource *write_idle_source; nghttp2_session *session; @@ -153,6 +154,10 @@ g_source_destroy (io->write_source); g_source_unref (io->write_source); } + if (io->write_idle_source) { + g_source_destroy (io->write_idle_source); + g_source_unref (io->write_idle_source); + } g_clear_object (&io->iostream); g_clear_pointer (&io->session, nghttp2_session_del); @@ -380,6 +385,8 @@ return G_SOURCE_REMOVE; } +static gboolean io_write_idle_cb (SoupServerMessageIOHTTP2* io); + static void io_try_write (SoupServerMessageIOHTTP2 *io) { @@ -389,13 +396,37 @@ if (io->write_source) return; + if (io->in_callback && soup_server_connection_get_io_data (conn) == (SoupServerMessageIO *)io) { + if (!nghttp2_session_want_write (io->session)) + return; + + if (io->write_idle_source) + return; + + io->write_idle_source = g_idle_source_new (); +#if GLIB_CHECK_VERSION(2, 70, 0) + g_source_set_static_name (io->write_idle_source, "Soup server HTTP/2 write idle source"); +#else + g_source_set_name (io->write_idle_source, "Soup server HTTP/2 write idle source"); +#endif + g_source_set_priority (io->write_idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (io->write_idle_source, (GSourceFunc)io_write_idle_cb, io, NULL); + g_source_attach (io->write_idle_source, g_main_context_get_thread_default ()); + return; + } + + if (io->write_idle_source) { + g_source_destroy (io->write_idle_source); + g_clear_pointer (&io->write_idle_source, g_source_unref); + } + g_object_ref (conn); 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 (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)) { + if (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); #if GLIB_CHECK_VERSION(2, 70, 0) @@ -419,10 +450,18 @@ } static gboolean +io_write_idle_cb (SoupServerMessageIOHTTP2* io) +{ + g_clear_pointer (&io->write_idle_source, g_source_unref); + io_try_write (io); + return G_SOURCE_REMOVE; +} + +static gboolean io_read (SoupServerMessageIOHTTP2 *io, GError **error) { - guint8 buffer[8192]; + guint8 buffer[16384]; gssize read; int ret; @@ -751,6 +790,16 @@ break; } case NGHTTP2_DATA: + h2_debug (io, msg_io, "[RECV] [DATA] window=%d/%d", nghttp2_session_get_stream_effective_recv_data_length (session, frame->hd.stream_id), + nghttp2_session_get_stream_effective_local_window_size (session, frame->hd.stream_id)); + if (nghttp2_session_get_stream_effective_recv_data_length (session, frame->hd.stream_id) == 0) + io_try_write (io); + break; + case NGHTTP2_WINDOW_UPDATE: + h2_debug (io, msg_io, "[RECV] [WINDOW_UPDATE] increment=%d, total=%d", frame->window_update.window_size_increment, + nghttp2_session_get_stream_remote_window_size (session, frame->hd.stream_id)); + if (nghttp2_session_get_stream_remote_window_size (session, frame->hd.stream_id) > 0) + io_try_write (io); break; default: io->in_callback--; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/server/soup-listener.c new/libsoup-3.4.3/libsoup/server/soup-listener.c --- old/libsoup-3.4.2/libsoup/server/soup-listener.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/server/soup-listener.c 2023-09-15 17:00:37.000000000 +0200 @@ -120,6 +120,7 @@ g_clear_object (&priv->socket); g_clear_object (&priv->iostream); + g_clear_object (&priv->local_addr); g_clear_object (&priv->tls_certificate); g_clear_object (&priv->tls_database); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/soup-connection-manager.c new/libsoup-3.4.3/libsoup/soup-connection-manager.c --- old/libsoup-3.4.2/libsoup/soup-connection-manager.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/soup-connection-manager.c 2023-09-15 17:00:37.000000000 +0200 @@ -206,6 +206,26 @@ return host; } +static void +soup_connection_manager_drop_connection (SoupConnectionManager *manager, + SoupConnection *conn) +{ + g_signal_handlers_disconnect_by_data (conn, manager); + manager->num_conns--; + g_object_unref (conn); + + g_cond_broadcast (&manager->cond); +} + +static void +remove_connection (gpointer key, + gpointer value, + gpointer user_data) +{ + SoupConnectionManager *manager = user_data; + soup_connection_manager_drop_connection (manager, key); +} + SoupConnectionManager * soup_connection_manager_new (SoupSession *session, guint max_conns, @@ -235,6 +255,9 @@ void soup_connection_manager_free (SoupConnectionManager *manager) { + g_hash_table_foreach (manager->conns, remove_connection, manager); + g_assert (manager->num_conns == 0); + g_clear_object (&manager->remote_connectable); g_hash_table_destroy (manager->http_hosts); g_hash_table_destroy (manager->https_hosts); @@ -294,17 +317,6 @@ } static void -soup_connection_manager_drop_connection (SoupConnectionManager *manager, - SoupConnection *conn) -{ - g_signal_handlers_disconnect_by_data (conn, manager); - manager->num_conns--; - g_object_unref (conn); - - g_cond_broadcast (&manager->cond); -} - -static void soup_connection_list_disconnect_all (GList *conns) { GList *c; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/soup-connection.c new/libsoup-3.4.3/libsoup/soup-connection.c --- old/libsoup-3.4.2/libsoup/soup-connection.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/soup-connection.c 2023-09-15 17:00:37.000000000 +0200 @@ -48,6 +48,9 @@ GCancellable *cancellable; GThread *owner; + + int window_size; + int stream_window_size; } SoupConnectionPrivate; G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupConnection, soup_connection, G_TYPE_OBJECT) @@ -91,6 +94,9 @@ */ #define SOUP_CONNECTION_UNUSED_TIMEOUT 3 +#define HTTP2_INITIAL_WINDOW_SIZE (15 * 1024 * 1024) /* 15MB */ +#define HTTP2_INITIAL_STREAM_WINDOW_SIZE (6 * 1024 * 1024) /* 6MB */ + static void soup_connection_init (SoupConnection *conn) { @@ -99,6 +105,8 @@ priv->http_version = SOUP_HTTP_1_1; priv->force_http_version = G_MAXUINT8; priv->owner = g_thread_self (); + priv->window_size = HTTP2_INITIAL_WINDOW_SIZE; + priv->stream_window_size = HTTP2_INITIAL_STREAM_WINDOW_SIZE; } static void @@ -1383,3 +1391,37 @@ return priv->owner; } + +void +soup_connection_set_http2_initial_window_size (SoupConnection *conn, + int window_size) +{ + SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); + + priv->window_size = window_size; +} + +int +soup_connection_get_http2_initial_window_size (SoupConnection *conn) +{ + SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); + + return priv->window_size; +} + +void +soup_connection_set_http2_initial_stream_window_size (SoupConnection *conn, + int window_size) +{ + SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); + + priv->stream_window_size = window_size; +} + +int +soup_connection_get_http2_initial_stream_window_size (SoupConnection *conn) +{ + SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); + + return priv->stream_window_size; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/soup-connection.h new/libsoup-3.4.3/libsoup/soup-connection.h --- old/libsoup-3.4.2/libsoup/soup-connection.h 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/soup-connection.h 2023-09-15 17:00:37.000000000 +0200 @@ -87,6 +87,13 @@ gboolean soup_connection_is_reusable (SoupConnection *conn); GThread *soup_connection_get_owner (SoupConnection *conn); +void soup_connection_set_http2_initial_window_size (SoupConnection *conn, + int window_size); +int soup_connection_get_http2_initial_window_size (SoupConnection *conn); +void soup_connection_set_http2_initial_stream_window_size (SoupConnection *conn, + int window_size); +int soup_connection_get_http2_initial_stream_window_size (SoupConnection *conn); + G_END_DECLS #endif /* __SOUP_CONNECTION_H__ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/soup-headers.c new/libsoup-3.4.3/libsoup/soup-headers.c --- old/libsoup-3.4.2/libsoup/soup-headers.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/soup-headers.c 2023-09-15 17:00:37.000000000 +0200 @@ -902,7 +902,7 @@ g_string_append (string, name); g_string_append (string, "*=UTF-8''"); - encoded = g_uri_escape_string (value, "*'%()<>@,;:\\\"/[]?=", FALSE); + encoded = g_uri_escape_string (value, "!#$&+-.^_`|~", FALSE); g_string_append (string, encoded); g_free (encoded); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/libsoup/soup-session.c new/libsoup-3.4.3/libsoup/soup-session.c --- old/libsoup-3.4.2/libsoup/soup-session.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/libsoup/soup-session.c 2023-09-15 17:00:37.000000000 +0200 @@ -107,6 +107,9 @@ SoupMessageQueueItem *item, gboolean loop); +static void async_send_request_return_result (SoupMessageQueueItem *item, + gpointer stream, GError *error); + #define SOUP_SESSION_MAX_CONNS_DEFAULT 10 #define SOUP_SESSION_MAX_CONNS_PER_HOST_DEFAULT 2 @@ -1198,7 +1201,7 @@ * request, then @msg will be modified accordingly. * * If @msg has already been redirected too many times, this will - * cause it to fail with %SOUP_STATUS_TOO_MANY_REDIRECTS. + * cause it to fail with %SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS. * * Returns: %TRUE if a redirection was applied, %FALSE if not * (eg, because there was no Location header, or it could not be @@ -1366,7 +1369,20 @@ return item; } -static void +static gboolean +finish_request_if_item_cancelled (SoupMessageQueueItem *item) +{ + if (!g_cancellable_is_cancelled (item->cancellable)) + return FALSE; + + if (item->async) + async_send_request_return_result (item, NULL, NULL); + + item->state = SOUP_MESSAGE_FINISHING; + return TRUE; +} + +static gboolean soup_session_send_queue_item (SoupSession *session, SoupMessageQueueItem *item, SoupMessageIOCompletionFn completion_cb) @@ -1405,9 +1421,13 @@ soup_message_headers_set_content_length (request_headers, 0); } - soup_message_starting (item->msg); - if (item->state == SOUP_MESSAGE_RUNNING) - soup_message_send_item (item->msg, item, completion_cb, item); + soup_message_starting (item->msg); + finish_request_if_item_cancelled (item); + if (item->state != SOUP_MESSAGE_RUNNING) + return FALSE; + + soup_message_send_item (item->msg, item, completion_cb, item); + return TRUE; } static void @@ -1541,15 +1561,19 @@ g_object_unref (conn); g_clear_object (&tunnel_item->error); tunnel_item->state = SOUP_MESSAGE_RUNNING; - soup_session_send_queue_item (session, tunnel_item, - (SoupMessageIOCompletionFn)tunnel_message_completed); - soup_message_io_run (msg, !tunnel_item->async); + if (soup_session_send_queue_item (session, tunnel_item, (SoupMessageIOCompletionFn)tunnel_message_completed)) + soup_message_io_run (msg, !tunnel_item->async); + else + tunnel_message_completed (msg, SOUP_MESSAGE_IO_INTERRUPTED, tunnel_item); return; } item->state = SOUP_MESSAGE_RESTARTING; } + if (item->state == SOUP_MESSAGE_FINISHING) + soup_message_finished (tunnel_item->msg); + tunnel_item->state = SOUP_MESSAGE_FINISHED; soup_session_unqueue_item (session, tunnel_item); @@ -1601,9 +1625,10 @@ g_clear_object (&conn); tunnel_item->state = SOUP_MESSAGE_RUNNING; - soup_session_send_queue_item (session, tunnel_item, - (SoupMessageIOCompletionFn)tunnel_message_completed); - soup_message_io_run (msg, !item->async); + if (soup_session_send_queue_item (session, tunnel_item, (SoupMessageIOCompletionFn)tunnel_message_completed)) + soup_message_io_run (msg, !item->async); + else + tunnel_message_completed (msg, SOUP_MESSAGE_IO_INTERRUPTED, tunnel_item); g_object_unref (msg); } @@ -1742,20 +1767,24 @@ switch (item->state) { case SOUP_MESSAGE_STARTING: - if (!soup_session_ensure_item_connection (session, item)) - return; + if (!finish_request_if_item_cancelled (item)) { + if (!soup_session_ensure_item_connection (session, item)) + return; + } break; - case SOUP_MESSAGE_CONNECTED: { - SoupConnection *conn = soup_message_get_connection (item->msg); + case SOUP_MESSAGE_CONNECTED: + if (!finish_request_if_item_cancelled (item)) { + SoupConnection *conn = soup_message_get_connection (item->msg); - if (soup_connection_is_tunnelled (conn)) + if (soup_connection_is_tunnelled (conn)) tunnel_connect (item); - else - item->state = SOUP_MESSAGE_READY; - g_object_unref (conn); + else + item->state = SOUP_MESSAGE_READY; + g_object_unref (conn); + } break; - } + case SOUP_MESSAGE_READY: if (item->connect_only) { item->state = SOUP_MESSAGE_FINISHING; @@ -1767,16 +1796,17 @@ break; } - item->state = SOUP_MESSAGE_RUNNING; + if (!finish_request_if_item_cancelled (item)) { + item->state = SOUP_MESSAGE_RUNNING; - soup_message_set_metrics_timestamp (item->msg, SOUP_MESSAGE_METRICS_REQUEST_START); + soup_message_set_metrics_timestamp (item->msg, SOUP_MESSAGE_METRICS_REQUEST_START); - soup_session_send_queue_item (session, item, - (SoupMessageIOCompletionFn)message_completed); + if (soup_session_send_queue_item (session, item, (SoupMessageIOCompletionFn)message_completed) && item->async) + async_send_request_running (session, item); - if (item->async) - async_send_request_running (session, item); - return; + return; + } + break; case SOUP_MESSAGE_RUNNING: if (item->async) @@ -3192,8 +3222,10 @@ while (!stream) { /* Get a connection, etc */ soup_session_process_queue_item (session, item, TRUE); - if (item->state != SOUP_MESSAGE_RUNNING) + if (item->state != SOUP_MESSAGE_RUNNING) { + g_cancellable_set_error_if_cancelled (item->cancellable, &my_error); break; + } /* Send request, read headers */ if (!soup_message_io_run_until_read (msg, item->cancellable, &my_error)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/meson.build new/libsoup-3.4.3/meson.build --- old/libsoup-3.4.2/meson.build 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/meson.build 2023-09-15 17:00:37.000000000 +0200 @@ -1,5 +1,5 @@ project('libsoup', 'c', - version: '3.4.2', + version: '3.4.3', meson_version : '>= 0.54', license : 'LGPL-2.0-or-later', default_options : [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/po/tr.po new/libsoup-3.4.3/po/tr.po --- old/libsoup-3.4.2/po/tr.po 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/po/tr.po 2023-09-15 17:00:37.000000000 +0200 @@ -1,5 +1,5 @@ # Turkish translation for libsoup. -# Copyright (C) 2012-2022 libsoup's COPYRIGHT HOLDER +# Copyright (C) 2012-2023 libsoup's COPYRIGHT HOLDER # This file is distributed under the same license as the libsoup package. # # Ozan ÃaÄlayan <ozan...@gmail.com>, 2013. @@ -13,10 +13,10 @@ msgstr "" "Project-Id-Version: libsoup master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/libsoup/issues\n" -"POT-Creation-Date: 2022-08-13 12:28+0000\n" +"POT-Creation-Date: 2023-04-13 18:20+0000\n" "PO-Revision-Date: 2021-09-09 22:15+0300\n" "Last-Translator: Emin Tufan Ãetin <etce...@gmail.com>\n" -"Language-Team: Türkçe <gnome-t...@gnome.org>\n" +"Language-Team: Türkçe <ta...@gnome.org.tr>\n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -42,6 +42,8 @@ #: libsoup/http1/soup-body-input-stream.c:187 #: libsoup/http1/soup-body-input-stream.c:220 #: libsoup/http1/soup-message-io-data.c:77 +#: libsoup/http2/soup-client-message-io-http2.c:412 +#: libsoup/server/http2/soup-server-message-io-http2.c:435 msgid "Connection terminated unexpectedly" msgstr "BaÄlantı beklenmeyen biçimde sonlandı" @@ -53,26 +55,26 @@ msgid "Cannot truncate SoupBodyInputStream" msgstr "SoupBodyInputStream kesilemiyor" -#: libsoup/http1/soup-client-message-io-http1.c:321 -#: libsoup/http1/soup-client-message-io-http1.c:762 +#: libsoup/http1/soup-client-message-io-http1.c:322 +#: libsoup/http1/soup-client-message-io-http1.c:775 #: libsoup/http2/soup-body-input-stream-http2.c:221 -#: libsoup/server/http1/soup-server-message-io-http1.c:416 -#: libsoup/server/http1/soup-server-message-io-http1.c:889 +#: libsoup/server/http1/soup-server-message-io-http1.c:417 +#: libsoup/server/http1/soup-server-message-io-http1.c:890 msgid "Operation would block" msgstr "Ä°Ålem engellenebilir" -#: libsoup/http1/soup-client-message-io-http1.c:462 +#: libsoup/http1/soup-client-message-io-http1.c:463 msgid "Could not parse HTTP response" msgstr "HTTP yanıtı ayrıÅtırılamadı" -#: libsoup/http1/soup-client-message-io-http1.c:485 +#: libsoup/http1/soup-client-message-io-http1.c:486 msgid "Unrecognized HTTP response encoding" msgstr "HTTP yanıtı tanınmayan biçimde kodlanmıÅ" -#: libsoup/http1/soup-client-message-io-http1.c:721 -#: libsoup/http1/soup-client-message-io-http1.c:747 -#: libsoup/http2/soup-client-message-io-http2.c:1544 -#: libsoup/http2/soup-client-message-io-http2.c:1568 +#: libsoup/http1/soup-client-message-io-http1.c:734 +#: libsoup/http1/soup-client-message-io-http1.c:760 +#: libsoup/http2/soup-client-message-io-http2.c:1653 +#: libsoup/http2/soup-client-message-io-http2.c:1679 msgid "Operation was cancelled" msgstr "Ä°Ålem iptal edildi" @@ -80,40 +82,40 @@ msgid "Header too big" msgstr "BaÅlık çok büyük" -#: libsoup/server/soup-listener.c:261 +#: libsoup/server/soup-listener.c:268 msgid "Could not import existing socket: " msgstr "Var olan yuva içe aktarılamadı: " -#: libsoup/server/soup-listener.c:267 +#: libsoup/server/soup-listener.c:274 msgid "Canât import unconnected socket" msgstr "BaÄlı olmayan yuva içe aktarılamıyor" -#: libsoup/server/soup-server.c:1209 +#: libsoup/server/soup-server.c:1217 msgid "Canât create a TLS server without a TLS certificate" msgstr "TLS sertifikası olmadan TLS sunucusu oluÅturulamaz" -#: libsoup/soup-session.c:1116 +#: libsoup/soup-session.c:1133 msgid "Location header is missing or empty in response headers" msgstr "Konum baÅlıÄı eksik veya yanıt baÅlıklarında boÅ" -#: libsoup/soup-session.c:1130 +#: libsoup/soup-session.c:1147 #, c-format msgid "Invalid URI â%sâ in Location response header" msgstr "Konum yanıt baÅlıÄında geçersiz URI â%sâ" -#: libsoup/soup-session.c:1150 +#: libsoup/soup-session.c:1167 msgid "Too many redirects" msgstr "Ãok sayıda yönlendirme" -#: libsoup/soup-session.c:1155 +#: libsoup/soup-session.c:1172 msgid "Message was restarted too many times" msgstr "Ä°leti birçok kez yeniden baÅladı" -#: libsoup/soup-session.c:3011 libsoup/soup-session.c:3159 +#: libsoup/soup-session.c:3040 libsoup/soup-session.c:3190 msgid "Message is already in session queue" msgstr "Ä°leti zaten oturum sırasında" -#: libsoup/soup-session.c:3491 +#: libsoup/soup-session.c:3666 msgid "The server did not accept the WebSocket handshake." msgstr "Sunucu, WebSocket el sıkıÅmasını kabul etmedi." @@ -137,61 +139,61 @@ msgid "Not enough domains" msgstr "Yeterli etki alanı yok" -#: libsoup/websocket/soup-websocket.c:390 -#: libsoup/websocket/soup-websocket.c:434 -#: libsoup/websocket/soup-websocket.c:450 +#: libsoup/websocket/soup-websocket.c:391 +#: libsoup/websocket/soup-websocket.c:435 +#: libsoup/websocket/soup-websocket.c:451 msgid "Server requested unsupported extension" msgstr "Sunucu, desteklenmeyen eklenti isteÄinde bulundu" -#: libsoup/websocket/soup-websocket.c:413 -#: libsoup/websocket/soup-websocket.c:605 +#: libsoup/websocket/soup-websocket.c:414 +#: libsoup/websocket/soup-websocket.c:606 #, c-format msgid "Incorrect WebSocket â%sâ header" msgstr "Hatalı WebSocket â%sâ baÅlıÄı" -#: libsoup/websocket/soup-websocket.c:414 -#: libsoup/websocket/soup-websocket.c:869 +#: libsoup/websocket/soup-websocket.c:415 +#: libsoup/websocket/soup-websocket.c:870 #, c-format msgid "Server returned incorrect â%sâ key" msgstr "Sunucu, geçersiz â%sâ anahtarı döndürdü" -#: libsoup/websocket/soup-websocket.c:477 +#: libsoup/websocket/soup-websocket.c:478 #, c-format msgid "Duplicated parameter in â%sâ WebSocket extension header" msgstr "â%sâ WebSocket eklenti baÅlıÄında yinelenen parametre" -#: libsoup/websocket/soup-websocket.c:478 +#: libsoup/websocket/soup-websocket.c:479 #, c-format msgid "" "Server returned a duplicated parameter in â%sâ WebSocket extension header" msgstr "Sunucu, â%sâ WebSocket eklenti baÅlıÄında yinelenen parametre döndürdü" -#: libsoup/websocket/soup-websocket.c:568 -#: libsoup/websocket/soup-websocket.c:578 +#: libsoup/websocket/soup-websocket.c:569 +#: libsoup/websocket/soup-websocket.c:579 msgid "WebSocket handshake expected" msgstr "WebSocket el sıkıÅması bekleniyor" -#: libsoup/websocket/soup-websocket.c:586 +#: libsoup/websocket/soup-websocket.c:587 msgid "Unsupported WebSocket version" msgstr "Desteklenmeyen WebSocket sürümü" -#: libsoup/websocket/soup-websocket.c:595 +#: libsoup/websocket/soup-websocket.c:596 msgid "Invalid WebSocket key" msgstr "Geçersiz WebSocket anahtarı" -#: libsoup/websocket/soup-websocket.c:614 +#: libsoup/websocket/soup-websocket.c:615 msgid "Unsupported WebSocket subprotocol" msgstr "Desteklenmeyen WebSocket alt iletiÅim kuralı" -#: libsoup/websocket/soup-websocket.c:820 +#: libsoup/websocket/soup-websocket.c:821 msgid "Server rejected WebSocket handshake" msgstr "Sunucu, WebSocket el sıkıÅmasını reddetti" -#: libsoup/websocket/soup-websocket.c:828 -#: libsoup/websocket/soup-websocket.c:837 +#: libsoup/websocket/soup-websocket.c:829 +#: libsoup/websocket/soup-websocket.c:838 msgid "Server ignored WebSocket handshake" msgstr "Sunucu, WebSocket el sıkıÅmasını yoksaydı" -#: libsoup/websocket/soup-websocket.c:849 +#: libsoup/websocket/soup-websocket.c:850 msgid "Server requested unsupported protocol" msgstr "Sunucu, desteklenmeyen iletiÅim kuralı isteÄinde bulundu" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/tests/connection-test.c new/libsoup-3.4.3/tests/connection-test.c --- old/libsoup-3.4.2/tests/connection-test.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/tests/connection-test.c 2023-09-15 17:00:37.000000000 +0200 @@ -1693,6 +1693,61 @@ soup_test_session_abort_unref (session); } +static void +cancel_tunnel_test_request_queued (SoupSession *session, + SoupMessage *msg, + GCancellable *cancellable) +{ + if (soup_message_get_method (msg) != SOUP_METHOD_CONNECT) + return; + + g_signal_connect_swapped (msg, "starting", G_CALLBACK (g_cancellable_cancel), cancellable); +} + +static void +do_cancel_tunnel_msg_on_starting (void) +{ + SoupSession *session; + SoupMessage *msg; + GProxyResolver *resolver; + GCancellable *cancellable; + GBytes *body; + GError *error = NULL; + + SOUP_TEST_SKIP_IF_NO_TLS + SOUP_TEST_SKIP_IF_NO_APACHE; + + session = soup_test_session_new (NULL); + + if (tls_available) { + GTlsDatabase *tlsdb; + + tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ()); + soup_session_set_tls_database (session, tlsdb); + g_object_unref (tlsdb); + } + + resolver = g_simple_proxy_resolver_new (HTTP_PROXY, NULL); + soup_session_set_proxy_resolver (session, resolver); + g_object_unref (resolver); + + cancellable = g_cancellable_new (); + g_signal_connect (session, "request-queued", + G_CALLBACK (cancel_tunnel_test_request_queued), + cancellable); + + msg = soup_message_new ("GET", HTTPS_SERVER); + body = soup_session_send_and_read (session, msg, cancellable, &error); + soup_test_assert_message_status (msg, SOUP_STATUS_NONE); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + g_bytes_unref (body); + g_object_unref (msg); + g_object_unref (cancellable); + + soup_test_session_abort_unref (session); +} + int main (int argc, char **argv) { @@ -1719,6 +1774,7 @@ g_test_add_func ("/connection/metrics", do_connection_metrics_test); g_test_add_func ("/connection/force-http2", do_connection_force_http2_test); g_test_add_func ("/connection/http2/http-1-1-required", do_connection_http_1_1_required_test); + g_test_add_func ("/connection/cancel-tunnel-msg-on-starting", do_cancel_tunnel_msg_on_starting); ret = g_test_run (); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/tests/header-parsing-test.c new/libsoup-3.4.3/tests/header-parsing-test.c --- old/libsoup-3.4.2/tests/header-parsing-test.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/tests/header-parsing-test.c 2023-09-15 17:00:37.000000000 +0200 @@ -1211,10 +1211,12 @@ { "two", "test with spaces" }, { "three", "test with \"quotes\" and \\s" }, { "four", NULL }, - { "five", "test with \xC3\xA1\xC3\xA7\xC4\x89\xC3\xA8\xC3\xB1\xC5\xA3\xC5\xA1" } + { "five", "test with \xC3\xA1\xC3\xA7\xC4\x89\xC3\xA8\xC3\xB1\xC5\xA3\xC5\xA1" }, + { "six", "ã,ã!#$&+-.^_`|~" }, + { "seven", "ãabc*'%123^_`|~" } }; -#define TEST_PARAMS_RESULT "one=foo, two=\"test with spaces\", three=\"test with \\\"quotes\\\" and \\\\s\", four, five*=UTF-8''test%20with%20%C3%A1%C3%A7%C4%89%C3%A8%C3%B1%C5%A3%C5%A1" +#define TEST_PARAMS_RESULT "one=foo, two=\"test with spaces\", three=\"test with \\\"quotes\\\" and \\\\s\", four, five*=UTF-8''test%20with%20%C3%A1%C3%A7%C4%89%C3%A8%C3%B1%C5%A3%C5%A1, six*=UTF-8''%E3%81%82%2C%E3%81%84!#$&+-.^_`|~, seven*=UTF-8''%E3%81%82abc%2A%27%25123^_`|~" static void do_append_param_tests (void) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/tests/http2-test.c new/libsoup-3.4.3/tests/http2-test.c --- old/libsoup-3.4.2/tests/http2-test.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/tests/http2-test.c 2023-09-15 17:00:37.000000000 +0200 @@ -360,7 +360,7 @@ GUri *uri; SoupMessage *msg; GInputStream *response; - guint large_size = 10000; + guint large_size = 1000000; char *large_data; unsigned int i; GError *error = NULL; @@ -422,7 +422,7 @@ SoupMessage *msg; GBytes *response = NULL; GMainContext *async_context = g_main_context_ref_thread_default (); - guint large_size = 10000; + guint large_size = 1000000; char *large_data; unsigned int i; @@ -553,6 +553,90 @@ g_uri_unref (uri); } +typedef struct { + int connection; + int stream; +} WindowSize; + +static void +flow_control_message_network_event (SoupMessage *msg, + GSocketClientEvent event, + GIOStream *connection, + WindowSize *window_size) +{ + SoupConnection *conn; + + if (event != G_SOCKET_CLIENT_RESOLVING) + return; + + conn = soup_message_get_connection (msg); + g_assert_nonnull (conn); + if (window_size->connection != -1) + soup_connection_set_http2_initial_window_size (conn, window_size->connection); + if (window_size->stream != -1) + soup_connection_set_http2_initial_stream_window_size (conn, window_size->stream); +} + +static void +do_flow_control_large_test (Test *test, gconstpointer data) +{ + gboolean async = GPOINTER_TO_INT (data); + GUri *uri; + SoupMessage *msg; + GBytes *response; + GError *error = NULL; + WindowSize window_size = { (LARGE_N_CHARS * LARGE_CHARS_REPEAT) / 2 , (LARGE_N_CHARS * LARGE_CHARS_REPEAT) / 2 }; + + uri = g_uri_parse_relative (base_uri, "/large", SOUP_HTTP_URI_FLAGS, NULL); + msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri); + g_signal_connect (msg, "network-event", + G_CALLBACK (flow_control_message_network_event), + &window_size); + + if (async) + response = soup_test_session_async_send (test->session, msg, NULL, &error); + else + response = soup_session_send_and_read (test->session, msg, NULL, &error); + + g_assert_no_error (error); + g_assert_cmpuint (g_bytes_get_size (response), ==, (LARGE_N_CHARS * LARGE_CHARS_REPEAT) + 1); + + g_uri_unref (uri); + g_bytes_unref (response); + g_object_unref (msg); +} + +static void +do_flow_control_multi_message_async_test (Test *test, gconstpointer data) +{ + GUri *uri; + SoupMessage *msg1, *msg2; + GBytes *response1 = NULL; + GBytes *response2 = NULL; + WindowSize window_size = { (LARGE_N_CHARS * LARGE_CHARS_REPEAT), (LARGE_N_CHARS * LARGE_CHARS_REPEAT) / 2 }; + + uri = g_uri_parse_relative (base_uri, "/large", SOUP_HTTP_URI_FLAGS, NULL); + msg1 = soup_message_new_from_uri (SOUP_METHOD_GET, uri); + g_signal_connect (msg1, "network-event", + G_CALLBACK (flow_control_message_network_event), + &window_size); + msg2 = soup_message_new_from_uri (SOUP_METHOD_GET, uri); + soup_session_send_async (test->session, msg1, G_PRIORITY_DEFAULT, NULL, on_send_complete, &response1); + soup_session_send_async (test->session, msg2, G_PRIORITY_DEFAULT, NULL, on_send_complete, &response2); + + while (!response1 || !response2) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (g_bytes_get_size (response1), ==, (LARGE_N_CHARS * LARGE_CHARS_REPEAT) + 1); + g_assert_cmpuint (g_bytes_get_size (response2), ==, (LARGE_N_CHARS * LARGE_CHARS_REPEAT) + 1); + + g_uri_unref (uri); + g_bytes_unref (response1); + g_bytes_unref (response2); + g_object_unref (msg1); + g_object_unref (msg2); +} + static SoupConnection *last_connection; static void @@ -1361,6 +1445,18 @@ setup_session, do_paused_async_test, teardown_session); + g_test_add ("/http2/flow-control/large/async", Test, GINT_TO_POINTER (TRUE), + setup_session, + do_flow_control_large_test, + teardown_session); + g_test_add ("/http2/flow-control/large/sync", Test, GINT_TO_POINTER (TRUE), + setup_session, + do_flow_control_large_test, + teardown_session); + g_test_add ("/http2/flow-control/multiplex/async", Test, NULL, + setup_session, + do_flow_control_multi_message_async_test, + teardown_session); g_test_add ("/http2/connections", Test, NULL, setup_session, do_connections_test, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsoup-3.4.2/tests/misc-test.c new/libsoup-3.4.3/tests/misc-test.c --- old/libsoup-3.4.2/tests/misc-test.c 2023-04-29 19:48:31.000000000 +0200 +++ new/libsoup-3.4.3/tests/misc-test.c 2023-09-15 17:00:37.000000000 +0200 @@ -430,6 +430,14 @@ } static void +ea_message_queued (SoupSession *session, + SoupMessage *msg, + GCancellable *cancellable) +{ + g_cancellable_cancel (cancellable); +} + +static void do_early_abort_test (void) { SoupSession *session; @@ -488,6 +496,22 @@ g_object_unref (cancellable); g_object_unref (msg); soup_test_session_abort_unref (session); + + session = soup_test_session_new (NULL); + msg = soup_message_new_from_uri ("GET", base_uri); + cancellable = g_cancellable_new (); + + g_signal_connect (session, "request-queued", + G_CALLBACK (ea_message_queued), cancellable); + g_assert_null (soup_test_session_async_send (session, msg, cancellable, &error)); + debug_printf (2, " Message 4 completed\n"); + + g_assert_cmpuint (soup_message_get_connection_id (msg), ==, 0); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + g_object_unref (cancellable); + g_object_unref (msg); + soup_test_session_abort_unref (session); } static void