summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2022-10-11 14:21:16 +0200
committerCarlos Garcia Campos <carlosgc@gnome.org>2022-10-11 13:02:09 +0000
commitd6200373aa0d3de427ffcaa602a7557187dee88b (patch)
tree75a092d509d23810f12f3a879ab39ac76848146b
parent7982ed911c3cf8dd2ca2a852174f64a90a428837 (diff)
downloadlibsoup-d6200373aa0d3de427ffcaa602a7557187dee88b.tar.gz
Handle io errors on connect message while tunneling
Fixes #283
-rw-r--r--libsoup/http1/soup-client-message-io-http1.c9
-rw-r--r--libsoup/soup-session.c5
-rw-r--r--tests/proxy-test.c37
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]);