diff -rup /tmp/libsoup-2.27.5/libsoup/soup-socket.c libsoup-2.27.5/libsoup/soup-socket.c
--- /tmp/libsoup-2.27.5/libsoup/soup-socket.c	2009-07-28 03:48:28.000000000 +0200
+++ libsoup-2.27.5/libsoup/soup-socket.c	2009-09-23 16:18:29.000000000 +0200
@@ -62,6 +62,14 @@ enum {
 };
 
 typedef struct {
+	SoupSocket *sock;
+	GCancellable *cancellable;
+	guint cancel_id;
+	SoupSocketCallback callback;
+	gpointer user_data;
+} SoupSocketAsyncConnectData;
+
+typedef struct {
 	int sockfd;
 	SoupAddress *local_addr, *remote_addr;
 	GIOChannel *iochannel;
@@ -77,6 +85,7 @@ typedef struct {
 	GSource        *read_timeout, *write_timeout;
 	GSource        *connect_timeout;
 	GByteArray     *read_buf;
+	SoupSocketAsyncConnectData *sacd;
 
 	GMutex *iolock, *addrlock;
 	guint timeout;
@@ -564,14 +573,6 @@ soup_socket_new (const char *optname1, .
 	return sock;
 }
 
-typedef struct {
-	SoupSocket *sock;
-	GCancellable *cancellable;
-	guint cancel_id;
-	SoupSocketCallback callback;
-	gpointer user_data;
-} SoupSocketAsyncConnectData;
-
 static gboolean
 idle_connect_result (gpointer user_data)
 {
@@ -592,6 +593,7 @@ idle_connect_result (gpointer user_data)
 		status = SOUP_STATUS_OK;
 
 	sacd->callback (sacd->sock, status, sacd->user_data);
+	priv->sacd = NULL;
 	g_slice_free (SoupSocketAsyncConnectData, sacd);
 	return FALSE;
 }
@@ -641,15 +643,15 @@ static void
 got_address (SoupAddress *addr, guint status, gpointer user_data)
 {
 	SoupSocketAsyncConnectData *sacd = user_data;
+	SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
 
+	priv->sacd = NULL;
 	if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
 		sacd->callback (sacd->sock, status, sacd->user_data);
-		g_slice_free (SoupSocketAsyncConnectData, sacd);
-		return;
+	} else {
+		soup_socket_connect_async (sacd->sock, sacd->cancellable,
+					   sacd->callback, sacd->user_data);
 	}
-
-	soup_socket_connect_async (sacd->sock, sacd->cancellable,
-				   sacd->callback, sacd->user_data);
 	g_slice_free (SoupSocketAsyncConnectData, sacd);
 }
 
@@ -723,24 +725,23 @@ soup_socket_connect_async (SoupSocket *s
 			   SoupSocketCallback callback, gpointer user_data)
 {
 	SoupSocketPrivate *priv;
-	SoupSocketAsyncConnectData *sacd;
 	guint status;
 
 	g_return_if_fail (SOUP_IS_SOCKET (sock));
 	priv = SOUP_SOCKET_GET_PRIVATE (sock);
 	g_return_if_fail (priv->remote_addr != NULL);
 
-	sacd = g_slice_new0 (SoupSocketAsyncConnectData);
-	sacd->sock = sock;
-	sacd->cancellable = cancellable;
-	sacd->callback = callback;
-	sacd->user_data = user_data;
+	priv->sacd = g_slice_new0 (SoupSocketAsyncConnectData);
+	priv->sacd->sock = sock;
+	priv->sacd->cancellable = cancellable;
+	priv->sacd->callback = callback;
+	priv->sacd->user_data = user_data;
 
 	if (!soup_address_get_sockaddr (priv->remote_addr, NULL)) {
 		soup_address_resolve_async (priv->remote_addr,
 					    priv->async_context,
 					    cancellable,
-					    got_address, sacd);
+					    got_address, priv->sacd);
 		return;
 	}
 
@@ -753,22 +754,22 @@ soup_socket_connect_async (SoupSocket *s
 					   G_IO_IN | G_IO_OUT |
 					   G_IO_PRI | G_IO_ERR |
 					   G_IO_HUP | G_IO_NVAL,
-					   connect_watch, sacd);
+					   connect_watch, priv->sacd);
 		if (priv->timeout) {
 			priv->connect_timeout =
 				soup_add_timeout (priv->async_context,
 						  priv->timeout * 1000,
-						  connect_timeout, sacd);
+						  connect_timeout, priv->sacd);
 		}
 		if (cancellable) {
-			sacd->cancel_id =
+			priv->sacd->cancel_id =
 				g_signal_connect (cancellable, "cancelled",
 						  G_CALLBACK (async_cancel),
-						  sacd);
+						  priv->sacd);
 		}
 	} else {
 		priv->watch_src = soup_add_completion (priv->async_context,
-						       idle_connect_result, sacd);
+						       idle_connect_result, priv->sacd);
 	}
 }
 
@@ -1057,6 +1058,15 @@ soup_socket_disconnect (SoupSocket *sock
 
 	/* Then let everyone know we're disconnected */
 	g_signal_emit (sock, signals[DISCONNECTED], 0);
+
+	if (priv->sacd) {
+		if (priv->watch_src)
+		{
+			g_source_destroy (priv->watch_src);
+			priv->watch_src = NULL;
+		}
+		idle_connect_result(priv->sacd);
+	}
 }
 
 /**
