[libsoup] Correctly handle unsuccessful CONNECTs via request API



commit f06455cacd4772f68cfa50a12ea5dc3c4be3abf0
Author: Dan Winship <danw gnome org>
Date:   Tue May 15 23:02:50 2012 -0400

    Correctly handle unsuccessful CONNECTs via request API
    
    and add tests to proxy-test to make sure that the request API works
    for each case as well (based on a patch from Sergio)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=675865

 libsoup/soup-session-async.c |    5 ++
 libsoup/soup-session-sync.c  |    5 +-
 tests/proxy-test.c           |  135 +++++++++++++++++++++++------------------
 3 files changed, 84 insertions(+), 61 deletions(-)
---
diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c
index 4f88206..90c44e2 100644
--- a/libsoup/soup-session-async.c
+++ b/libsoup/soup-session-async.c
@@ -595,6 +595,11 @@ send_request_finished (SoupSession *session, SoupMessageQueueItem *item)
 		 * after we return;
 		 */
 		return;
+	} else {
+		/* The message finished before even being started;
+		 * probably a tunnel connect failure.
+		 */
+		istream = g_memory_input_stream_new ();
 	}
 
 	send_request_return_result (item, istream, error);
diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c
index 3bdb347..f4cfd6e 100644
--- a/libsoup/soup-session-sync.c
+++ b/libsoup/soup-session-sync.c
@@ -503,7 +503,7 @@ soup_session_send_request (SoupSession   *session,
 	while (!stream) {
 		/* Get a connection, etc */
 		process_queue_item (item);
-		if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
+		if (item->state != SOUP_MESSAGE_RUNNING)
 			break;
 
 		/* Send request, read headers */
@@ -561,7 +561,8 @@ soup_session_send_request (SoupSession   *session,
 		}
 		g_set_error_literal (error, SOUP_HTTP_ERROR, msg->status_code,
 				     msg->reason_phrase);
-	}
+	} else if (!stream)
+		stream = g_memory_input_stream_new ();
 
 	if (!stream) {
 		if (soup_message_io_in_progress (msg))
diff --git a/tests/proxy-test.c b/tests/proxy-test.c
index be315fa..3f478c0 100644
--- a/tests/proxy-test.c
+++ b/tests/proxy-test.c
@@ -88,44 +88,18 @@ set_close_on_connect (SoupSession *session, SoupMessage *msg,
 }
 
 
-static gboolean
-loop_idle_quit (gpointer loop)
-{
-	g_main_loop_quit (loop);
-	return FALSE;
-}
-
 static void
-request_completed (GObject *source, GAsyncResult *result, gpointer loop)
-{
-	SoupRequest *one = SOUP_REQUEST (source);
-	GError *error = NULL;
-
-	debug_printf (2, "  Request completed\n");
-	if (!soup_request_send_finish (one, result, &error)) {
-		debug_printf (1, "  Unexpected error on Request: %s\n",
-			      error->message);
-		errors++;
-	}
-	g_clear_error (&error);
-
-	g_idle_add (loop_idle_quit, loop);
-}
-
-static void
-test_url_new_api (const char *url, int proxy, guint expected, gboolean close)
+test_url (const char *url, int proxy, guint expected,
+	  gboolean sync, gboolean close)
 {
 	SoupSession *session;
 	SoupURI *proxy_uri;
 	SoupMessage *msg;
-	SoupRequester *requester;
-	SoupRequest *request;
-	GMainLoop *loop;
 
 	if (!tls_available && g_str_has_prefix (url, "https:"))
 		return;
 
-	debug_printf (1, "  GET (requester API) %s via %s%s\n", url, proxy_names[proxy],
+	debug_printf (1, "  GET %s via %s%s\n", url, proxy_names[proxy],
 		      close ? " (with Connection: close)" : "");
 	if (proxy == UNAUTH_PROXY && expected != SOUP_STATUS_FORBIDDEN)
 		expected = SOUP_STATUS_PROXY_UNAUTHORIZED;
@@ -134,14 +108,10 @@ test_url_new_api (const char *url, int proxy, guint expected, gboolean close)
 	 * connections/auth aren't cached between tests.
 	 */
 	proxy_uri = soup_uri_new (proxies[proxy]);
-	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
-					 SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER,
-					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+	session = soup_test_session_new (sync ? SOUP_TYPE_SESSION_SYNC : SOUP_TYPE_SESSION_ASYNC,
 					 SOUP_SESSION_PROXY_URI, proxy_uri,
 					 NULL);
 	soup_uri_free (proxy_uri);
-	g_object_add_weak_pointer (G_OBJECT (session), (gpointer *)&session);
-
 	g_signal_connect (session, "authenticate",
 			  G_CALLBACK (authenticate), NULL);
 	if (close) {
@@ -149,43 +119,60 @@ test_url_new_api (const char *url, int proxy, guint expected, gboolean close)
 				  G_CALLBACK (set_close_on_connect), NULL);
 	}
 
-	requester = (SoupRequester *)soup_session_get_feature (session, SOUP_TYPE_REQUESTER);
-	request = soup_requester_request (requester, url, NULL);
-	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
-
-	loop = g_main_loop_new (NULL, TRUE);
-	soup_request_send_async (request, NULL, request_completed, loop);
-	g_object_unref (request);
+	msg = soup_message_new (SOUP_METHOD_GET, url);
+	if (!msg) {
+		fprintf (stderr, "proxy-test: Could not parse URI\n");
+		exit (1);
+	}
 
-	g_main_loop_run (loop);
-	g_main_loop_unref (loop);
+	soup_session_send_message (session, msg);
 
+	debug_printf (1, "  %d %s\n", msg->status_code, msg->reason_phrase);
 	if (msg->status_code != expected) {
-		debug_printf (1, "    GET failed: %d %s (expected %d)\n",
-			      msg->status_code, msg->reason_phrase,
-			      expected);
-		g_object_unref (msg);
+		debug_printf (1, "  EXPECTED %d!\n", expected);
 		errors++;
-		return;
 	}
-	g_object_unref (msg);
 
+	g_object_unref (msg);
 	soup_test_session_abort_unref (session);
 }
 
+static GMainLoop *loop;
 
 static void
-test_url (const char *url, int proxy, guint expected,
-	  gboolean sync, gboolean close)
+request_completed (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+	SoupRequest *req = SOUP_REQUEST (source);
+	GInputStream **stream_p = user_data;
+	GError *error = NULL;
+
+	debug_printf (2, "  Request completed\n");
+	*stream_p = soup_request_send_finish (req, result, &error);
+	if (!*stream_p) {
+		debug_printf (1, "  Unexpected error on Request: %s\n",
+			      error->message);
+		errors++;
+		g_error_free (error);
+	}
+
+	g_main_loop_quit (loop);
+}
+
+static void
+test_url_new_api (const char *url, int proxy, guint expected,
+		  gboolean sync, gboolean close)
 {
 	SoupSession *session;
 	SoupURI *proxy_uri;
 	SoupMessage *msg;
+	SoupRequester *requester;
+	SoupRequest *request;
+	GInputStream *stream;
 
 	if (!tls_available && g_str_has_prefix (url, "https:"))
 		return;
 
-	debug_printf (1, "  GET %s via %s%s\n", url, proxy_names[proxy],
+	debug_printf (1, "  GET (requester API) %s via %s%s\n", url, proxy_names[proxy],
 		      close ? " (with Connection: close)" : "");
 	if (proxy == UNAUTH_PROXY && expected != SOUP_STATUS_FORBIDDEN)
 		expected = SOUP_STATUS_PROXY_UNAUTHORIZED;
@@ -195,9 +182,12 @@ test_url (const char *url, int proxy, guint expected,
 	 */
 	proxy_uri = soup_uri_new (proxies[proxy]);
 	session = soup_test_session_new (sync ? SOUP_TYPE_SESSION_SYNC : SOUP_TYPE_SESSION_ASYNC,
+					 SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER,
+					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
 					 SOUP_SESSION_PROXY_URI, proxy_uri,
 					 NULL);
 	soup_uri_free (proxy_uri);
+
 	g_signal_connect (session, "authenticate",
 			  G_CALLBACK (authenticate), NULL);
 	if (close) {
@@ -205,13 +195,29 @@ test_url (const char *url, int proxy, guint expected,
 				  G_CALLBACK (set_close_on_connect), NULL);
 	}
 
-	msg = soup_message_new (SOUP_METHOD_GET, url);
-	if (!msg) {
-		fprintf (stderr, "proxy-test: Could not parse URI\n");
-		exit (1);
+	requester = (SoupRequester *)soup_session_get_feature (session, SOUP_TYPE_REQUESTER);
+	request = soup_requester_request (requester, url, NULL);
+	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
+
+	if (sync) {
+		GError *error = NULL;
+
+		stream = soup_request_send (request, NULL, &error);
+		if (!stream) {
+			debug_printf (1, "  Unexpected error on Request: %s\n",
+				      error->message);
+			errors++;
+			g_error_free (error);
+		}
+	} else {
+		loop = g_main_loop_new (NULL, TRUE);
+		soup_request_send_async (request, NULL, request_completed, &stream);
+		g_main_loop_run (loop);
+		g_main_loop_unref (loop);
 	}
 
-	soup_session_send_message (session, msg);
+	if (stream)
+		g_input_stream_close (stream, NULL, NULL);
 
 	debug_printf (1, "  %d %s\n", msg->status_code, msg->reason_phrase);
 	if (msg->status_code != expected) {
@@ -220,6 +226,8 @@ test_url (const char *url, int proxy, guint expected,
 	}
 
 	g_object_unref (msg);
+	g_object_unref (request);
+
 	soup_test_session_abort_unref (session);
 }
 
@@ -238,15 +246,23 @@ run_test (int i, gboolean sync)
 		http_url = g_strconcat (HTTP_SERVER, tests[i].url, NULL);
 		https_url = g_strconcat (HTTPS_SERVER, tests[i].url, NULL);
 	}
+
 	test_url (http_url, SIMPLE_PROXY, tests[i].final_status, sync, FALSE);
+	test_url_new_api (http_url, SIMPLE_PROXY, tests[i].final_status, sync, FALSE);
 	test_url (https_url, SIMPLE_PROXY, tests[i].final_status, sync, FALSE);
+	test_url_new_api (https_url, SIMPLE_PROXY, tests[i].final_status, sync, FALSE);
+
 	test_url (http_url, AUTH_PROXY, tests[i].final_status, sync, FALSE);
+	test_url_new_api (http_url, AUTH_PROXY, tests[i].final_status, sync, FALSE);
 	test_url (https_url, AUTH_PROXY, tests[i].final_status, sync, FALSE);
+	test_url_new_api (https_url, AUTH_PROXY, tests[i].final_status, sync, FALSE);
 	test_url (https_url, AUTH_PROXY, tests[i].final_status, sync, TRUE);
+	test_url_new_api (https_url, AUTH_PROXY, tests[i].final_status, sync, TRUE);
+
 	test_url (http_url, UNAUTH_PROXY, tests[i].final_status, sync, FALSE);
+	test_url_new_api (http_url, UNAUTH_PROXY, tests[i].final_status, sync, FALSE);
 	test_url (https_url, UNAUTH_PROXY, tests[i].final_status, sync, FALSE);
-
-	test_url_new_api (https_url, SIMPLE_PROXY, tests[i].final_status, FALSE);
+	test_url_new_api (https_url, UNAUTH_PROXY, tests[i].final_status, sync, FALSE);
 
 	g_free (http_url);
 	g_free (https_url);
@@ -347,6 +363,7 @@ main (int argc, char **argv)
 		run_test (i, FALSE);
 		run_test (i, TRUE);
 	}
+	return 0;
 
 	server = soup_test_server_new (TRUE);
 	soup_server_add_handler (server, NULL, server_callback, NULL, NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]