cpw.darkrain42.xmpp.bosh: 2fbd079d: BOSH: Support HTTPS connections to the c...

paul at darkrain42.org paul at darkrain42.org
Sun Mar 22 23:10:39 EDT 2009


-----------------------------------------------------------------
Revision: 2fbd079d0e8c53d5a6f240df5232b63c780212c0
Ancestor: 3f04f4a917efd4f6e3468064c845e9ffd6a252b1
Author: paul at darkrain42.org
Date: 2009-03-22T23:44:17
Branch: im.pidgin.cpw.darkrain42.xmpp.bosh
URL: http://d.pidgin.im/viewmtn/revision/info/2fbd079d0e8c53d5a6f240df5232b63c780212c0

Modified files:
        libpurple/protocols/jabber/bosh.c

ChangeLog: 

BOSH: Support HTTPS connections to the connection manager

-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/bosh.c	311d99c386654fe5df7384214cc28576875fbae3
+++ libpurple/protocols/jabber/bosh.c	968dccfed92fdf0f5e3f677ffee2f58616ef1b6d
@@ -50,6 +50,7 @@ struct _PurpleBOSHConnection {
 	PurpleHTTPConnection *connections[MAX_HTTP_CONNECTIONS];
 
 	gboolean ready;
+	gboolean ssl;
 
 	/* decoded URL */
 	char *host;
@@ -74,6 +75,7 @@ struct _PurpleHTTPConnection {
 
 struct _PurpleHTTPConnection {
 	PurpleBOSHConnection *bosh;
+	PurpleSslConnection *psc;
 	int fd;
 	int ie_handle;
 
@@ -139,6 +141,8 @@ jabber_bosh_http_connection_destroy(Purp
 
 	if (conn->ie_handle)
 		purple_input_remove(conn->ie_handle);
+	if (conn->psc)
+		purple_ssl_close(conn->psc);
 	if (conn->fd >= 0)
 		close(conn->fd);
 
@@ -181,6 +185,10 @@ jabber_bosh_connection_init(JabberStream
 	conn->pending = purple_circ_buffer_new(0 /* default grow size */);
 
 	conn->ready = FALSE;
+	if (purple_strcasestr(url, "https://") != NULL)
+		conn->ssl = TRUE;
+	else
+		conn->ssl = FALSE;
 
 	conn->connections[0] = jabber_bosh_http_connection_init(conn);
 
@@ -532,7 +540,8 @@ jabber_bosh_connection_send_native(Purpl
 	http_connection_send_request(chosen, packet);
 }
 
-static void http_connection_connected(PurpleHTTPConnection *conn)
+static void
+connection_common_established_cb(PurpleHTTPConnection *conn)
 {
 	/* Indicate we're ready and reset some variables */
 	conn->ready = TRUE;
@@ -645,20 +654,32 @@ jabber_bosh_http_connection_process(Purp
 	conn->handled_len = conn->body_len = 0;
 }
 
+/*
+ * Common code for reading, called from http_connection_read_cb_ssl and
+ * http_connection_read_cb.
+ */
 static void
-jabber_bosh_http_connection_read(gpointer data, gint fd,
-                                 PurpleInputCondition condition)
+http_connection_read(PurpleHTTPConnection *conn)
 {
-	PurpleHTTPConnection *conn = data;
 	char buffer[1025];
 	int cnt, count = 0;
 
 	if (!conn->buf)
 		conn->buf = g_string_new("");
 
-	while ((cnt = read(fd, buffer, sizeof(buffer))) > 0) {
+	/* Read once to prime cnt before the loop */
+	if (conn->psc)
+		cnt = purple_ssl_read(conn->psc, buffer, sizeof(buffer));
+	else
+		cnt = read(conn->fd, buffer, sizeof(buffer));
+	while (cnt > 0) {
 		count += cnt;
 		g_string_append_len(conn->buf, buffer, cnt);
+
+		if (conn->psc)
+			cnt = purple_ssl_read(conn->psc, buffer, sizeof(buffer));
+		else
+			cnt = read(conn->fd, buffer, sizeof(buffer));
 	}
 
 	if (cnt == 0 || (cnt < 0 && errno != EAGAIN)) {
@@ -679,9 +700,49 @@ jabber_bosh_http_connection_read(gpointe
 	jabber_bosh_http_connection_process(conn);
 }
 
-static void http_connection_cb(gpointer data, gint source, const gchar *error)
+static void
+http_connection_read_cb(gpointer data, gint fd, PurpleInputCondition condition)
 {
 	PurpleHTTPConnection *conn = data;
+
+	http_connection_read(conn);
+}
+
+static void
+http_connection_read_cb_ssl(gpointer data, PurpleSslConnection *psc,
+                            PurpleInputCondition cond)
+{
+	PurpleHTTPConnection *conn = data;
+
+	http_connection_read(conn);
+}
+
+static void
+ssl_connection_established_cb(gpointer data, PurpleSslConnection *psc,
+                              PurpleInputCondition cond)
+{
+	PurpleHTTPConnection *conn = data;
+
+	purple_ssl_input_add(psc, http_connection_read_cb_ssl, conn);
+	connection_common_established_cb(conn);
+}
+
+static void
+ssl_connection_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error,
+                        gpointer data)
+{
+	PurpleHTTPConnection *conn = data;
+
+	/* sslconn frees the connection on error */
+	conn->psc = NULL;
+
+	purple_connection_ssl_error(conn->bosh->js->gc, error);
+}
+
+static void
+connection_established_cb(gpointer data, gint source, const gchar *error)
+{
+	PurpleHTTPConnection *conn = data;
 	PurpleConnection *gc = conn->bosh->js->gc;
 
 	if (source < 0) {
@@ -694,11 +755,9 @@ static void http_connection_cb(gpointer 
 	}
 
 	conn->fd = source;
-
-	http_connection_connected(conn);
-
 	conn->ie_handle = purple_input_add(conn->fd, PURPLE_INPUT_READ,
-	        jabber_bosh_http_connection_read, conn);
+	        http_connection_read_cb, conn);
+	connection_common_established_cb(conn);
 }
 
 static void http_connection_connect(PurpleHTTPConnection *conn)
@@ -707,8 +766,24 @@ static void http_connection_connect(Purp
 	PurpleConnection *gc = bosh->js->gc;
 	PurpleAccount *account = purple_connection_get_account(gc);
 
-	if ((purple_proxy_connect(conn, account, bosh->host, bosh->port,
-	                          http_connection_cb, conn)) == NULL) {
+	if (bosh->ssl) {
+		if (purple_ssl_is_supported()) {
+			conn->psc = purple_ssl_connect(account, bosh->host, bosh->port,
+			                               ssl_connection_established_cb,
+			                               ssl_connection_error_cb,
+			                               conn);
+			if (!conn->psc) {
+				purple_connection_error_reason(gc,
+					PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
+					_("Unable to establish SSL connection"));
+			}
+		} else {
+			purple_connection_error_reason(gc,
+			    PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
+			    _("SSL support unavailable"));
+		}
+	} else if (purple_proxy_connect(conn, account, bosh->host, bosh->port,
+	                                 connection_established_cb, conn) == NULL) {
 		purple_connection_error_reason(gc,
 		    PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 		    _("Unable to create socket"));
@@ -732,7 +807,10 @@ http_connection_send_request(PurpleHTTPC
 
 	/* TODO: Better error handling, circbuffer or possible integration with
 	 * low-level code in jabber.c */
-	ret = write(conn->fd, packet, strlen(packet));
+	if (conn->psc)
+		ret = purple_ssl_write(conn->psc, packet, strlen(packet));
+	else
+		ret = write(conn->fd, packet, strlen(packet));
 
 	++conn->requests;
 	++conn->bosh->requests;


More information about the Commits mailing list