[libsoup] Fix SoupMessage https status information to be set more reliably



commit 25cb090d660e8f678fbac171ffc2f587b9973800
Author: Dan Winship <danw gnome org>
Date:   Thu Oct 20 17:05:05 2011 -0400

    Fix SoupMessage https status information to be set more reliably
    
    In particular, make sure it gets set when a connection fails, so that
    soup_message_get_https_status() on the message will tell you *why* it
    failed.
    
    Also, update tests/get to display the tls-certificate-errors

 libsoup/soup-message-io.c      |   21 ---------------------
 libsoup/soup-message-private.h |    4 ++++
 libsoup/soup-message.c         |   29 +++++++++++++++++++++++++++++
 libsoup/soup-session-async.c   |    2 ++
 libsoup/soup-session-sync.c    |    1 +
 libsoup/soup-session.c         |    1 +
 libsoup/soup-socket.c          |   13 +++++++++----
 tests/get.c                    |    7 +++++++
 8 files changed, 53 insertions(+), 25 deletions(-)
---
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index aa33187..4f2e839 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -1076,27 +1076,6 @@ new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
 	io->read_state  = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
 	io->write_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
 
-	if (soup_socket_is_ssl (io->sock)) {
-		GTlsCertificate *certificate;
-		GTlsCertificateFlags errors;
-
-		g_object_get (sock,
-			      SOUP_SOCKET_TLS_CERTIFICATE, &certificate,
-			      SOUP_SOCKET_TLS_ERRORS, &errors,
-			      NULL);
-		g_object_set (msg,
-			      SOUP_MESSAGE_TLS_CERTIFICATE, certificate,
-			      SOUP_MESSAGE_TLS_ERRORS, errors,
-			      NULL);
-		if (certificate)
-			g_object_unref (certificate);
-	} else {
-		g_object_set (msg,
-			      SOUP_MESSAGE_TLS_CERTIFICATE, NULL,
-			      SOUP_MESSAGE_TLS_ERRORS, 0,
-			      NULL);
-	}
-
 	if (priv->io_data)
 		soup_message_io_cleanup (msg);
 	priv->io_data = io;
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index ce866dc..1bb2aab 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -96,4 +96,8 @@ gboolean            soup_message_io_in_progress (SoupMessage          *msg);
 
 gboolean soup_message_disables_feature (SoupMessage *msg,
 					gpointer     feature);
+
+void soup_message_set_https_status (SoupMessage    *msg,
+				    SoupConnection *conn);
+
 #endif /* SOUP_MESSAGE_PRIVATE_H */
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 4efba5c..a8d8ba3 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -10,11 +10,13 @@
 
 #include "soup-address.h"
 #include "soup-auth.h"
+#include "soup-connection.h"
 #include "soup-enum-types.h"
 #include "soup-marshal.h"
 #include "soup-message.h"
 #include "soup-message-private.h"
 #include "soup-misc.h"
+#include "soup-socket.h"
 #include "soup-uri.h"
 
 /**
@@ -1879,6 +1881,33 @@ soup_message_set_first_party (SoupMessage *msg,
 	g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FIRST_PARTY);
 }
 
+void
+soup_message_set_https_status (SoupMessage *msg, SoupConnection *conn)
+{
+	SoupSocket *sock = soup_connection_get_socket (conn);
+
+	if (sock && soup_socket_is_ssl (sock)) {
+		GTlsCertificate *certificate;
+		GTlsCertificateFlags errors;
+
+		g_object_get (sock,
+			      SOUP_SOCKET_TLS_CERTIFICATE, &certificate,
+			      SOUP_SOCKET_TLS_ERRORS, &errors,
+			      NULL);
+		g_object_set (msg,
+			      SOUP_MESSAGE_TLS_CERTIFICATE, certificate,
+			      SOUP_MESSAGE_TLS_ERRORS, errors,
+			      NULL);
+		if (certificate)
+			g_object_unref (certificate);
+	} else {
+		g_object_set (msg,
+			      SOUP_MESSAGE_TLS_CERTIFICATE, NULL,
+			      SOUP_MESSAGE_TLS_ERRORS, 0,
+			      NULL);
+	}
+}
+
 /**
  * soup_message_get_https_status:
  * @msg: a #SoupMessage
diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c
index c4684d7..33bf202 100644
--- a/libsoup/soup-session-async.c
+++ b/libsoup/soup-session-async.c
@@ -314,6 +314,8 @@ got_connection (SoupConnection *conn, guint status, gpointer user_data)
 		return;
 	}
 
+	soup_message_set_https_status (item->msg, conn);
+
 	if (status != SOUP_STATUS_OK) {
 		soup_connection_disconnect (conn);
 
diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c
index 7bd76ea..b6494d0 100644
--- a/libsoup/soup-session-sync.c
+++ b/libsoup/soup-session-sync.c
@@ -171,6 +171,7 @@ tunnel_connect (SoupSession *session, SoupMessageQueueItem *related)
 	if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
 		if (!soup_connection_start_ssl_sync (conn, related->cancellable))
 			status = SOUP_STATUS_SSL_FAILED;
+		soup_message_set_https_status (item->msg, conn);
 	}
 
 	if (!SOUP_STATUS_IS_SUCCESSFUL (status))
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index bd593dc..e46b19d 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -1510,6 +1510,7 @@ soup_session_get_connection (SoupSession *session,
 			soup_connection_set_state (conns->data, SOUP_CONNECTION_IN_USE);
 			g_mutex_unlock (priv->host_lock);
 			item->conn = g_object_ref (conns->data);
+			soup_message_set_https_status (item->msg, item->conn);
 			return TRUE;
 		} else if (soup_connection_get_state (conns->data) == SOUP_CONNECTION_CONNECTING)
 			num_pending++;
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 19991bd..ee83a3f 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -74,6 +74,7 @@ typedef struct {
 
 	guint non_blocking:1;
 	guint is_server:1;
+	guint ssl:1;
 	guint ssl_strict:1;
 	guint ssl_fallback:1;
 	guint clean_dispose:1;
@@ -794,6 +795,7 @@ listen_watch (GObject *pollable, gpointer data)
 		new_priv->async_context = g_main_context_ref (priv->async_context);
 	new_priv->non_blocking = priv->non_blocking;
 	new_priv->is_server = TRUE;
+	new_priv->ssl = priv->ssl;
 	if (priv->ssl_creds)
 		new_priv->ssl_creds = priv->ssl_creds;
 	finish_socket_setup (new_priv);
@@ -934,6 +936,8 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
 	if (G_IS_TLS_CONNECTION (priv->conn))
 		return TRUE;
 
+	priv->ssl = TRUE;
+
 	if (!priv->is_server) {
 		GTlsClientConnection *conn;
 		GSocketConnectable *identity;
@@ -992,6 +996,7 @@ soup_socket_handshake_sync (SoupSocket    *sock,
 	SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
 	GError *error = NULL;
 
+	priv->ssl = TRUE;
 	if (g_tls_connection_handshake (G_TLS_CONNECTION (priv->conn),
 					cancellable, &error))
 		return SOUP_STATUS_OK;
@@ -1040,6 +1045,8 @@ soup_socket_handshake_async (SoupSocket         *sock,
 	SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
 	SoupSocketAsyncConnectData *data;
 
+	priv->ssl = TRUE;
+
 	data = g_slice_new (SoupSocketAsyncConnectData);
 	data->sock = g_object_ref (sock);
 	data->callback = callback;
@@ -1057,9 +1064,7 @@ soup_socket_handshake_async (SoupSocket         *sock,
  * soup_socket_is_ssl:
  * @sock: a #SoupSocket
  *
- * Tests if @sock is set up to do SSL. Note that this simply means
- * that the %SOUP_SOCKET_SSL_CREDENTIALS property has been set; it
- * does not mean that soup_socket_start_ssl() has been called.
+ * Tests if @sock is doing (or has attempted to do) SSL.
  *
  * Return value: %TRUE if @sock has SSL credentials set
  **/
@@ -1068,7 +1073,7 @@ soup_socket_is_ssl (SoupSocket *sock)
 {
 	SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
 
-	return priv->ssl_creds != NULL;
+	return priv->ssl;
 }
 
 /**
diff --git a/tests/get.c b/tests/get.c
index 79d6e80..1a6b4ff 100644
--- a/tests/get.c
+++ b/tests/get.c
@@ -61,6 +61,13 @@ get_url (const char *url)
 		while (soup_message_headers_iter_next (&iter, &hname, &value))
 			printf ("%s: %s\r\n", hname, value);
 		printf ("\n");
+	} else if (msg->status_code == SOUP_STATUS_SSL_FAILED) {
+		GTlsCertificateFlags flags;
+
+		if (soup_message_get_https_status (msg, NULL, &flags))
+			printf ("%s: %d %s (0x%x)\n", name, msg->status_code, msg->reason_phrase, flags);
+		else
+			printf ("%s: %d %s (no handshake status)\n", name, msg->status_code, msg->reason_phrase);
 	} else if (!quiet || SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
 		printf ("%s: %d %s\n", name, msg->status_code, msg->reason_phrase);
 



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