diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2022-10-11 14:21:16 +0200 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@gnome.org> | 2022-10-11 13:02:09 +0000 |
commit | d6200373aa0d3de427ffcaa602a7557187dee88b (patch) | |
tree | 75a092d509d23810f12f3a879ab39ac76848146b | |
parent | 7982ed911c3cf8dd2ca2a852174f64a90a428837 (diff) | |
download | libsoup-d6200373aa0d3de427ffcaa602a7557187dee88b.tar.gz |
Handle io errors on connect message while tunneling
Fixes #283
-rw-r--r-- | libsoup/http1/soup-client-message-io-http1.c | 9 | ||||
-rw-r--r-- | libsoup/soup-session.c | 5 | ||||
-rw-r--r-- | tests/proxy-test.c | 37 |
3 files changed, 45 insertions, 6 deletions
diff --git a/libsoup/http1/soup-client-message-io-http1.c b/libsoup/http1/soup-client-message-io-http1.c index dff6bbf2..8c647bfa 100644 --- a/libsoup/http1/soup-client-message-io-http1.c +++ b/libsoup/http1/soup-client-message-io-http1.c @@ -860,9 +860,12 @@ soup_client_message_io_http1_run (SoupClientMessageIO *iface, soup_client_message_io_http1_get_priority (client_io)); g_source_attach (io->io_source, g_main_context_get_thread_default ()); } else { - if ((SoupClientMessageIOHTTP1 *)soup_message_get_io_data (msg) == client_io) - soup_message_io_finish (msg, error); - g_error_free (error); + if ((SoupClientMessageIOHTTP1 *)soup_message_get_io_data (msg) == client_io) { + g_assert (!client_io->msg_io->item->error); + client_io->msg_io->item->error = g_steal_pointer (&error); + soup_message_io_finish (msg, client_io->msg_io->item->error); + } + g_clear_error (&error); } diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index de0da49c..cfd4ef07 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -1518,6 +1518,7 @@ tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion, conn = soup_message_get_connection (tunnel_item->msg); if (conn) { 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); @@ -1532,8 +1533,8 @@ tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion, soup_session_unqueue_item (session, tunnel_item); status = soup_message_get_status (tunnel_item->msg); - if (!SOUP_STATUS_IS_SUCCESSFUL (status) || item->state == SOUP_MESSAGE_RESTARTING) { - tunnel_complete (tunnel_item, status, NULL); + if (!SOUP_STATUS_IS_SUCCESSFUL (status) || tunnel_item->error || item->state == SOUP_MESSAGE_RESTARTING) { + tunnel_complete (tunnel_item, status, g_steal_pointer (&tunnel_item->error)); return; } diff --git a/tests/proxy-test.c b/tests/proxy-test.c index 9ca8699c..ec039367 100644 --- a/tests/proxy-test.c +++ b/tests/proxy-test.c @@ -340,11 +340,43 @@ do_proxy_auth_cache_test (void) g_object_unref (cache); } +static void +do_proxy_connect_error_test (gconstpointer data) +{ + GUri *base_uri = (GUri *)data; + GUri *proxy_uri; + char *proxy_uri_str; + SoupSession *session; + SoupMessage *msg; + GProxyResolver *resolver; + GBytes *body; + GError *error = NULL; + + /* Proxy connection will success, but CONNECT message to https will fail due to TLS errors */ + proxy_uri = soup_uri_copy (base_uri, SOUP_URI_SCHEME, "http", NULL); + proxy_uri_str = g_uri_to_string (proxy_uri); + g_uri_unref (proxy_uri); + + resolver = g_simple_proxy_resolver_new (proxy_uri_str, (char **)ignore_hosts); + g_free (proxy_uri_str); + session = soup_test_session_new ("proxy-resolver", resolver, NULL); + g_object_unref (resolver); + + msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); + body = soup_test_session_async_send (session, msg, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED); + + g_error_free (error); + g_bytes_unref (body); + g_object_unref (msg); + soup_test_session_abort_unref (session); +} + int main (int argc, char **argv) { SoupServer *server; - GUri *base_uri; + GUri *base_uri, *base_https_uri; char *path; int i, ret; @@ -359,6 +391,7 @@ main (int argc, char **argv) server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD); soup_server_add_handler (server, NULL, server_callback, NULL, NULL); base_uri = soup_test_server_get_uri (server, "http", NULL); + base_https_uri = soup_test_server_get_uri (server, "https", NULL); for (i = 0; i < ntests; i++) { path = g_strdup_printf ("/proxy/%s", tests[i].explanation); @@ -369,10 +402,12 @@ main (int argc, char **argv) g_test_add_data_func ("/proxy/fragment", base_uri, do_proxy_fragment_test); g_test_add_func ("/proxy/redirect", do_proxy_redirect_test); g_test_add_func ("/proxy/auth-cache", do_proxy_auth_cache_test); + g_test_add_data_func ("/proxy/connect-error", base_https_uri, do_proxy_connect_error_test); ret = g_test_run (); g_uri_unref (base_uri); + g_uri_unref (base_https_uri); soup_test_server_quit_unref (server); for (i = 0; i < 3; i++) g_object_unref (proxy_resolvers[i]); |