[libsoup] SoupConnection: fix up ::event signal emissions



commit 646f1cd7b54692a6b4b0f349c2e737745378be07
Author: Dan Winship <danw gnome org>
Date:   Tue Aug 14 15:37:32 2012 -0400

    SoupConnection: fix up ::event signal emissions
    
    And add a test to make sure that all expected events are emitted, in
    the correct order.

 libsoup/soup-connection.c |   50 +++++++++----------
 tests/connection-test.c   |  116 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+), 26 deletions(-)
---
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 3c5c516..d2746e8 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -337,6 +337,20 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
 				     G_PARAM_READABLE));
 }
 
+static void
+soup_connection_event (SoupConnection      *conn,
+		       GSocketClientEvent   event,
+		       GIOStream           *connection)
+{
+	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
+
+	if (!connection && priv->socket)
+		connection = soup_socket_get_connection (priv->socket);
+
+	g_signal_emit (conn, signals[EVENT], 0,
+		       event, connection);
+}
+
 static gboolean
 idle_timeout (gpointer conn)
 {
@@ -394,11 +408,9 @@ set_current_item (SoupConnection *conn, SoupMessageQueueItem *item)
 	g_signal_connect (item->msg, "restarted",
 			  G_CALLBACK (current_item_restarted), conn);
 
-	if (item->msg->method == SOUP_METHOD_CONNECT) {
-		g_signal_emit (conn, signals[EVENT], 0,
-			       G_SOCKET_CLIENT_PROXY_NEGOTIATING,
-			       soup_socket_get_connection (priv->socket));
-	} else if (priv->state == SOUP_CONNECTION_IDLE)
+	if (item->msg->method == SOUP_METHOD_CONNECT)
+		soup_connection_event (conn, G_SOCKET_CLIENT_PROXY_NEGOTIATING, NULL);
+	else if (priv->state == SOUP_CONNECTION_IDLE)
 		soup_connection_set_state (conn, SOUP_CONNECTION_IN_USE);
 
 	g_object_thaw_notify (G_OBJECT (conn));
@@ -425,9 +437,7 @@ clear_current_item (SoupConnection *conn)
 
 		if (item->msg->method == SOUP_METHOD_CONNECT &&
 		    SOUP_STATUS_IS_SUCCESSFUL (item->msg->status_code)) {
-			g_signal_emit (conn, signals[EVENT], 0,
-				       G_SOCKET_CLIENT_PROXY_NEGOTIATED,
-				       soup_socket_get_connection (priv->socket));
+			soup_connection_event (conn, G_SOCKET_CLIENT_PROXY_NEGOTIATED, NULL);
 
 			/* We're now effectively no longer proxying */
 			soup_uri_free (priv->proxy_uri);
@@ -446,20 +456,6 @@ clear_current_item (SoupConnection *conn)
 }
 
 static void
-soup_connection_event (SoupConnection      *conn,
-		       GSocketClientEvent   event,
-		       GIOStream           *connection)
-{
-	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
-
-	if (!connection && priv->socket)
-		connection = soup_socket_get_connection (priv->socket);
-
-	g_signal_emit (conn, signals[EVENT], 0,
-		       event, connection);
-}
-
-static void
 proxy_socket_event (SoupSocket          *socket,
 		    GSocketClientEvent   event,
 		    GIOStream           *connection,
@@ -774,9 +770,10 @@ soup_connection_start_ssl_sync (SoupConnection *conn,
 
 	soup_connection_event (conn, G_SOCKET_CLIENT_TLS_HANDSHAKING, NULL);
 	status = soup_socket_handshake_sync (priv->socket, cancellable);
-	if (status == SOUP_STATUS_OK)
+	if (status == SOUP_STATUS_OK) {
 		soup_connection_event (conn, G_SOCKET_CLIENT_TLS_HANDSHAKED, NULL);
-	else if (status == SOUP_STATUS_TLS_FAILED) {
+		soup_connection_event (conn, G_SOCKET_CLIENT_COMPLETE, NULL);
+	} else if (status == SOUP_STATUS_TLS_FAILED) {
 		priv->ssl_fallback = TRUE;
 		status = SOUP_STATUS_TRY_AGAIN;
 	}
@@ -790,9 +787,10 @@ start_ssl_completed (SoupSocket *socket, guint status, gpointer user_data)
 	SoupConnectionAsyncConnectData *data = user_data;
 	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (data->conn);
 
-	if (status == SOUP_STATUS_OK)
+	if (status == SOUP_STATUS_OK) {
 		soup_connection_event (data->conn, G_SOCKET_CLIENT_TLS_HANDSHAKED, NULL);
-	else if (status == SOUP_STATUS_TLS_FAILED) {
+		soup_connection_event (data->conn, G_SOCKET_CLIENT_COMPLETE, NULL);
+	} else if (status == SOUP_STATUS_TLS_FAILED) {
 		priv->ssl_fallback = TRUE;
 		status = SOUP_STATUS_TRY_AGAIN;
 	}
diff --git a/tests/connection-test.c b/tests/connection-test.c
index f0a1703..b9dce7f 100644
--- a/tests/connection-test.c
+++ b/tests/connection-test.c
@@ -804,6 +804,121 @@ do_connection_state_test (void)
 	soup_test_session_abort_unref (session);
 }
 
+
+static const char *event_names[] = {
+	"RESOLVING", "RESOLVED", "CONNECTING", "CONNECTED",
+	"PROXY_NEGOTIATING", "PROXY_NEGOTIATED",
+	"TLS_HANDSHAKING", "TLS_HANDSHAKED", "COMPLETE"
+};
+
+static const char event_abbrevs[] = {
+	'r', 'R', 'c', 'C', 'p', 'P', 't', 'T', 'x', '\0'
+};
+
+static const char *
+event_name_from_abbrev (char abbrev)
+{
+	int evt;
+
+	for (evt = 0; event_abbrevs[evt]; evt++) {
+		if (event_abbrevs[evt] == abbrev)
+			return event_names[evt];
+	}
+	return "???";
+}
+
+static void
+network_event (SoupMessage *msg, GSocketClientEvent event,
+	       GIOStream *connection, gpointer user_data)
+{
+	const char **events = user_data;
+
+	if (!**events) {
+		debug_printf (1, "      Unexpected event: %s\n",
+			      event_names[event]);
+		errors++;
+	} else {
+		if (**events == event_abbrevs[event])
+			debug_printf (2, "      %s\n", event_names[event]);
+		else {
+			debug_printf (1, "      Unexpected event: %s (expected %s)\n",
+				      event_names[event],
+				      event_name_from_abbrev (**events));
+			errors++;
+		}
+		*events = *events + 1;
+	}
+}
+
+static void
+do_one_connection_event_test (SoupSession *session, const char *uri,
+			      const char *events)
+{
+	SoupMessage *msg;
+
+	msg = soup_message_new ("GET", uri);
+	g_signal_connect (msg, "network-event",
+			  G_CALLBACK (network_event),
+			  &events);
+	soup_session_send_message (session, msg);
+	if (msg->status_code != SOUP_STATUS_OK) {
+		debug_printf (1, "      Unexpected response: %d %s\n",
+			      msg->status_code, msg->reason_phrase);
+		errors++;
+	} else {
+		while (*events) {
+			debug_printf (1, "      Expected %s\n",
+				      event_name_from_abbrev (*events));
+			events++;
+			errors++;
+		}
+	}
+	g_object_unref (msg);
+	soup_session_abort (session);
+}
+
+static void
+do_connection_event_test_for_session (SoupSession *session)
+{
+	SoupURI *proxy_uri;
+
+	debug_printf (1, "    http\n");
+	do_one_connection_event_test (session, HTTP_SERVER, "rRcCx");
+
+	debug_printf (1, "    https\n");
+	do_one_connection_event_test (session, HTTPS_SERVER, "rRcCtTx");
+
+	proxy_uri = soup_uri_new (HTTP_PROXY);
+	g_object_set (G_OBJECT (session),
+		      SOUP_SESSION_PROXY_URI, proxy_uri,
+		      NULL);
+	soup_uri_free (proxy_uri);
+
+	debug_printf (1, "    http with proxy\n");
+	do_one_connection_event_test (session, HTTP_SERVER, "rRcCx");
+
+	debug_printf (1, "    https with proxy\n");
+	do_one_connection_event_test (session, HTTPS_SERVER, "rRcCpPtTx");
+}
+
+static void
+do_connection_event_test (void)
+{
+	SoupSession *session;
+
+	debug_printf (1, "\nConnection events\n");
+
+	debug_printf (1, "  Async session\n");
+	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
+	do_connection_event_test_for_session (session);
+	soup_test_session_abort_unref (session);
+
+	debug_printf (1, "  Sync session\n");
+	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
+	do_connection_event_test_for_session (session);
+	soup_test_session_abort_unref (session);
+}
+
 #endif
 
 int
@@ -826,6 +941,7 @@ main (int argc, char **argv)
 	do_non_idempotent_connection_test ();
 #ifdef HAVE_APACHE
 	do_connection_state_test ();
+	do_connection_event_test ();
 #endif
 
 	soup_uri_free (base_uri);



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