# HG changeset patch # User Stu Tomlinson # Date 1107460072 0 # Node ID fed2a7c2471debd70c68b9ea0449fcd96099373d # Parent 54f7939df8e3b909941bbafc1f82e73a731bb0a0 [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 diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/httpconn.c --- 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); diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/msn.c --- 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); diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/nexus.c --- 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 diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/notification.c --- 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", diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/servconn.c --- 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; diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/session.c --- 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.")); diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/session.h --- 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; diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/switchboard.c --- 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); } diff -r 54f7939df8e3 -r fed2a7c2471d src/protocols/msn/userlist.c --- 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); }