changeset 10568:fed2a7c2471d

[gaim-migrate @ 11954] Some MSN bits: - Fix HTTP Method works when using an HTTP proxy that require authentication (Bastien Durel) - Better error reporting when the MSN servers are temporarily unavailable - Prevent zombie failed switchboard connections swallowing up messages - Fix win32 crashes receiving messages from aMSN with no formatting info - Fix a crash when the connection to the nexus server fails - maybe some other stuff, I forgot how much had piled up committer: Tailor Script <tailor@pidgin.im>
author Stu Tomlinson <stu@nosnilmot.com>
date Thu, 03 Feb 2005 19:47:52 +0000
parents 54f7939df8e3
children 12349012610b
files src/protocols/msn/httpconn.c src/protocols/msn/msn.c src/protocols/msn/nexus.c src/protocols/msn/notification.c src/protocols/msn/servconn.c src/protocols/msn/session.c src/protocols/msn/session.h src/protocols/msn/switchboard.c src/protocols/msn/userlist.c
diffstat 9 files changed, 125 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/msn/httpconn.c	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/httpconn.c	Thu Feb 03 19:47:52 2005 +0000
@@ -80,6 +80,40 @@
 	g_free(httpconn);
 }
 
+static char *
+msn_httpconn_proxy_auth(MsnHttpConn *httpconn)
+{
+	GaimAccount *account;
+	GaimProxyInfo *gpi;
+	const char *username, *password;
+	char *auth = NULL;
+
+	account = httpconn->session->account;
+
+	if (gaim_account_get_proxy_info(account) == NULL)
+		gpi = gaim_global_proxy_get_info();
+	else
+		gpi = gaim_account_get_proxy_info(account);
+
+	if (gpi == NULL || !(gaim_proxy_info_get_type(gpi) == GAIM_PROXY_HTTP ||
+						 gaim_proxy_info_get_type(gpi) == GAIM_PROXY_USE_ENVVAR))
+		return NULL;
+
+	username = gaim_proxy_info_get_username(gpi);
+	password = gaim_proxy_info_get_password(gpi);
+
+	if (username != NULL) {
+		char *tmp;
+		auth = g_strdup_printf("%s:%s", username, password ? password : "");
+		tmp = gaim_base64_encode(auth, strlen(auth));
+		g_free(auth);
+		auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp);
+		g_free(tmp);
+	}
+
+	return auth;
+}
+
 static ssize_t
 write_raw(MsnHttpConn *httpconn, const char *header,
 		  const char *body, size_t body_len)
@@ -129,6 +163,7 @@
 msn_httpconn_poll(MsnHttpConn *httpconn)
 {
 	char *header;
+	char *auth;
 	int r;
 
 	g_return_if_fail(httpconn != NULL);
@@ -139,6 +174,8 @@
 		return;
 	}
 
+	auth = msn_httpconn_proxy_auth(httpconn);
+
 	header = g_strdup_printf(
 		"POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n"
 		"Accept: */*\r\n"
@@ -146,13 +183,18 @@
 		"User-Agent: MSMSGS\r\n"
 		"Host: %s\r\n"
 		"Proxy-Connection: Keep-Alive\r\n"
+		"%s" /* Proxy auth */
 		"Connection: Keep-Alive\r\n"
 		"Pragma: no-cache\r\n"
 		"Content-Type: application/x-msn-messenger\r\n"
 		"Content-Length: 0\r\n",
 		httpconn->host,
 		httpconn->full_session_id,
-		httpconn->host);
+		httpconn->host,
+		auth ? auth : "");
+
+	if (auth != NULL)
+		g_free(auth);
 
 	r = write_raw(httpconn, header, NULL, -1);
 
@@ -172,10 +214,18 @@
 
 	httpconn = data;
 
+	g_return_val_if_fail(httpconn != NULL, TRUE);
+
 #if 0
 	gaim_debug_info("msn", "polling from %s\n", httpconn->session_id);
 #endif
 
+	if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL))
+	{
+		gaim_debug_warning("msn", "Attempted HTTP poll before session is established\n");
+		return TRUE;
+	}
+
 	if (httpconn->dirty)
 		msn_httpconn_poll(httpconn);
 
@@ -296,7 +346,9 @@
 	if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len,
 								 &result_msg, &result_len, &error))
 	{
-		/* We must wait for more input */
+		/* We must wait for more input, or something went wrong */
+		if (error)
+			msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ);
 
 		return;
 	}
@@ -421,6 +473,7 @@
 {
 	char *params;
 	char *header;
+	char *auth;
 	gboolean first;
 	const char *server_types[] = { "NS", "SB" };
 	const char *server_type;
@@ -469,10 +522,18 @@
 		/* The rest of the times servconn->host is the gateway host. */
 		host = httpconn->host;
 
+		if (host == NULL || httpconn->full_session_id == NULL)
+		{
+			gaim_debug_warning("msn", "Attempted HTTP write before session is established\n");
+			return -1;
+		}
+
 		params = g_strdup_printf("SessionID=%s",
 								 httpconn->full_session_id);
 	}
 
+	auth = msn_httpconn_proxy_auth(httpconn);
+
 	header = g_strdup_printf(
 		"POST http://%s/gateway/gateway.dll?%s HTTP/1.1\r\n"
 		"Accept: */*\r\n"
@@ -480,6 +541,7 @@
 		"User-Agent: MSMSGS\r\n"
 		"Host: %s\r\n"
 		"Proxy-Connection: Keep-Alive\r\n"
+		"%s" /* Proxy auth */
 		"Connection: Keep-Alive\r\n"
 		"Pragma: no-cache\r\n"
 		"Content-Type: application/x-msn-messenger\r\n"
@@ -487,10 +549,14 @@
 		host,
 		params,
 		host,
+		auth ? auth : "",
 		(int)size);
 
 	g_free(params);
 
+	if (auth != NULL)
+		g_free(auth);
+
 	r = write_raw(httpconn, header, data, size);
 
 	g_free(header);
--- a/src/protocols/msn/msn.c	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/msn.c	Thu Feb 03 19:47:52 2005 +0000
@@ -687,7 +687,8 @@
 	if (strcmp(username, gaim_account_get_username(account)))
 		gaim_account_set_username(account, username);
 
-	msn_session_connect(session, host, port, http_method);
+	if (!msn_session_connect(session, host, port, http_method))
+		gaim_connection_error(gc, _("Failed to connect to server."));
 }
 
 static void
@@ -755,7 +756,8 @@
 
 		format = msn_message_get_attr(msg, "X-MMS-IM-Format");
 		msn_parse_format(format, &pre, &post);
-		body_str = g_strdup_printf("%s%s%s", pre, body_enc, post);
+		body_str = g_strdup_printf("%s%s%s", pre ? pre :  "",
+								   body_enc ? body_enc : "", post ? post : "");
 		g_free(body_enc);
 		g_free(pre);
 		g_free(post);
--- a/src/protocols/msn/nexus.c	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/nexus.c	Thu Feb 03 19:47:52 2005 +0000
@@ -93,8 +93,6 @@
 {
 	MsnNexus *nexus;
 	MsnSession *session;
-	GaimAccount *account;
-	GaimConnection *gc;
 
 	nexus = data;
 	g_return_if_fail(nexus != NULL);
@@ -102,16 +100,9 @@
 	session = nexus->session;
 	g_return_if_fail(session != NULL);
 
-	account = session->account;
-	g_return_if_fail(account != NULL);
-
-	gc = gaim_account_get_connection(account);
-	g_return_if_fail(gc != NULL);
-
 	msn_session_set_error(session, MSN_ERROR_AUTH, _("Unable to connect"));
-
-	msn_nexus_destroy(nexus);
-	session->nexus = NULL;
+	/* the above line will result in nexus being destroyed, so we don't want
+	 * to destroy it here, or we'd crash */
 }
 
 static void
--- a/src/protocols/msn/notification.c	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/notification.c	Thu Feb 03 19:47:52 2005 +0000
@@ -269,6 +269,30 @@
 }
 
 static void
+usr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
+{
+	MsnErrorType msnerr = 0;
+
+	switch (error)
+	{
+		case 500:
+		case 601:
+		case 910:
+		case 921:
+			msnerr = MSN_ERROR_SERV_UNAVAILABLE;
+			break;
+		case 911:
+			msnerr = MSN_ERROR_AUTH;
+			break;
+		default:
+			return;
+			break;
+	}
+
+	msn_session_set_error(cmdproc->session, msnerr, NULL);
+}
+
+static void
 ver_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	MsnSession *session;
@@ -322,6 +346,9 @@
 {
 	g_return_if_fail(notification != NULL);
 
+	if (!notification->in_use)
+		return;
+
 	msn_cmdproc_send_quick(notification->cmdproc, "OUT", NULL, NULL);
 
 	msn_notification_disconnect(notification);
@@ -976,7 +1003,8 @@
 	swboard->im_user = g_strdup(cmd->params[4]);
 	/* msn_switchboard_add_user(swboard, cmd->params[4]); */
 
-	msn_switchboard_connect(swboard, host, port);
+	if (!msn_switchboard_connect(swboard, host, port))
+		msn_switchboard_destroy(swboard);
 
 	g_free(host);
 }
@@ -1320,15 +1348,7 @@
 	msn_table_add_error(cbs_table, "REG", reg_error);
 	msn_table_add_error(cbs_table, "RMG", rmg_error);
 	/* msn_table_add_error(cbs_table, "REA", rea_error); */
-
-	/* I received a '500' error from the notification server just now.
-	 * I think this means 'Service temporarily unavailable' or similar,
-	 * in response to a USR command. We should report this instead of
-	 * 'Error reading from notification server'.
-	 * I'm not going to implement this right now, because we're string
-	 * frozen (and I'd probably break something anyway), so I'll put this
-	 * here as a reminder, or something. Stu. */
-	/* msn_table_add_error(cbs_table, "USR", usr_error); */
+	msn_table_add_error(cbs_table, "USR", usr_error);
 
 	msn_table_add_msg_type(cbs_table,
 						   "text/x-msmsgsprofile",
--- a/src/protocols/msn/servconn.c	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/servconn.c	Thu Feb 03 19:47:52 2005 +0000
@@ -212,7 +212,8 @@
 		/* HTTP Connection. */
 
 		if (!servconn->httpconn->connected)
-			msn_httpconn_connect(servconn->httpconn, host, port);
+			if (!msn_httpconn_connect(servconn->httpconn, host, port))
+				return FALSE;;
 
 		servconn->connected = TRUE;
 		servconn->httpconn->virgin = TRUE;
--- a/src/protocols/msn/session.c	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/session.c	Thu Feb 03 19:47:52 2005 +0000
@@ -282,7 +282,7 @@
 	GaimConnection *gc;
 	char *msg;
 
-	gc = session->account->gc;
+	gc = gaim_account_get_connection(session->account);
 
 	switch (error)
 	{
@@ -300,6 +300,11 @@
 			gc->wants_to_die = TRUE;
 			msg = g_strdup(_("You have signed on from another location."));
 			break;
+		case MSN_ERROR_SERV_UNAVAILABLE:
+			msg = g_strdup(_("The MSN servers are temporarily "
+							 "unavailable. Please wait and try "
+							 "again."));
+			break;
 		case MSN_ERROR_SERV_DOWN:
 			msg = g_strdup(_("The MSN servers are going down "
 							 "temporarily."));
--- a/src/protocols/msn/session.h	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/session.h	Thu Feb 03 19:47:52 2005 +0000
@@ -51,7 +51,8 @@
 	MSN_ERROR_AUTH,
 	MSN_ERROR_BAD_BLIST,
 	MSN_ERROR_SIGN_OTHER,
-	MSN_ERROR_SERV_DOWN
+	MSN_ERROR_SERV_DOWN,
+	MSN_ERROR_SERV_UNAVAILABLE
 
 } MsnErrorType;
 
--- a/src/protocols/msn/switchboard.c	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/switchboard.c	Thu Feb 03 19:47:52 2005 +0000
@@ -412,7 +412,8 @@
 
 		format = msn_message_get_attr(msg, "X-MMS-IM-Format");
 		msn_parse_format(format, &pre, &post);
-		body_str = g_strdup_printf("%s%s%s", pre, body_enc, post);
+		body_str = g_strdup_printf("%s%s%s", pre ? pre : "",
+								   body_enc ? body_enc : "", post ? post : "");
 		g_free(body_enc);
 		g_free(pre);
 		g_free(post);
@@ -830,14 +831,15 @@
 
 	if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL)
 	{
-		char *pre_format, *post_format;
+		char *pre, *post;
 
-		msn_parse_format(value, &pre_format, &post_format);
+		msn_parse_format(value, &pre, &post);
 
-		body_final = g_strdup_printf("%s%s%s", pre_format, body_enc, post_format);
+		body_final = g_strdup_printf("%s%s%s", pre ? pre : "",
+									 body_enc ? body_enc : "", post ? post : "");
 
-		g_free(pre_format);
-		g_free(post_format);
+		g_free(pre);
+		g_free(post);
 		g_free(body_enc);
 	}
 	else
@@ -1055,7 +1057,8 @@
 
 	msn_parse_socket(cmd->params[2], &host, &port);
 
-	msn_switchboard_connect(swboard, host, port);
+	if (!msn_switchboard_connect(swboard, host, port))
+		msn_switchboard_destroy(swboard);
 
 	g_free(host);
 }
--- a/src/protocols/msn/userlist.c	Thu Feb 03 15:37:13 2005 +0000
+++ b/src/protocols/msn/userlist.c	Thu Feb 03 19:47:52 2005 +0000
@@ -668,6 +668,6 @@
 		return;
 	}
 
+	msn_userlist_add_buddy(userlist, who, MSN_LIST_FL, new_group_name);
 	msn_userlist_rem_buddy(userlist, who, MSN_LIST_FL, old_group_name);
-	msn_userlist_add_buddy(userlist, who, MSN_LIST_FL, new_group_name);
 }