diff -ru pidgin-facebookchat/fb_blist.c ../pidgin-facebookchat-read-only/fb_blist.c --- pidgin-facebookchat/fb_blist.c 2010-11-26 11:07:32.000000000 +0100 +++ ../pidgin-facebookchat-read-only/fb_blist.c 2011-04-15 10:53:37.145218926 +0200 @@ -292,6 +292,7 @@ gsize uid_length; FacebookBuddy *fbuddy; PurpleBuddy *buddy; + GHashTable *processed_buddies; purple_debug_info("facebook", "parsing status message stream\n"); @@ -321,6 +322,8 @@ objnode, "html")); //purple_debug_misc("facebook", "html data\n%s\n", html); + processed_buddies = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + messages = g_strsplit(html, "/h6>", -1); for(i = 0; messages[i]; i++) { @@ -348,7 +351,7 @@ if (!message_string) { g_free(uid_string); - continue; + continue; } message_string = strchr(message_string, '>'); if (!message_string) @@ -359,6 +362,15 @@ message_string += 1; message_string = g_strndup(message_string, g_strrstr(message_string, "<")-message_string); purple_debug_info("facebook", "message: %s\n", message_string); + + if (g_hash_table_lookup(processed_buddies, uid_string)) + { + // Already processed a status message for this buddy + g_free(uid_string); + g_free(message_string); + continue; + } + g_hash_table_insert(processed_buddies, uid_string, uid_string); buddy = purple_find_buddy(fba->account, uid_string); if (buddy && buddy->proto_data) @@ -371,15 +383,14 @@ fbuddy->status = purple_markup_strip_html(message_string); purple_prpl_got_user_status(fba->account, buddy->name, - purple_primitive_get_id_from_type( - purple_presence_is_idle(purple_buddy_get_presence(buddy)) ? PURPLE_STATUS_AWAY : - PURPLE_STATUS_AVAILABLE), "message", fbuddy->status, NULL); + purple_status_get_id(purple_presence_get_active_status( + purple_buddy_get_presence(buddy))), "message", fbuddy->status, NULL); } - g_free(uid_string); g_free(message_string); } g_strfreev(messages); + g_hash_table_destroy(processed_buddies); new_latest = json_node_get_int(json_object_get_member( objnode, "newestStoryTime")); diff -ru pidgin-facebookchat/fb_connection.c ../pidgin-facebookchat-read-only/fb_connection.c --- pidgin-facebookchat/fb_connection.c 2010-10-20 22:52:01.000000000 +0200 +++ ../pidgin-facebookchat-read-only/fb_connection.c 2011-04-15 10:53:37.142218963 +0200 @@ -477,6 +477,12 @@ if (host == NULL) host = "www.facebook.com"; + if (fba && fba->account) + { + if (purple_account_get_bool(fba->account, "use-https", FALSE)) + method |= FB_METHOD_SSL; + } + if (fba && fba->account && !(method & FB_METHOD_SSL)) { proxy_info = purple_proxy_get_setup(fba->account); @@ -556,43 +562,6 @@ g_free(cookies); - /* - * Do a separate DNS lookup for the given host name and cache it - * for next time. - * - * TODO: It would be better if we did this before we call - * purple_proxy_connect(), so we could re-use the result. - * Or even better: Use persistent HTTP connections for servers - * that we access continually. - * - * TODO: This cache of the hostname<-->IP address does not respect - * the TTL returned by the DNS server. We should expire things - * from the cache after some amount of time. - */ - if (!is_proxy && !(method & FB_METHOD_SSL) && !g_hostname_is_ip_address(host)) - { - /* Don't do this for proxy connections, since proxies do the DNS lookup */ - gchar *host_ip; - - host_ip = g_hash_table_lookup(fba->hostname_ip_cache, host); - if (host_ip != NULL) { - host = host_ip; - } else if (fba->account && !fba->account->disconnecting) { - GSList *host_lookup_list = NULL; - PurpleDnsQueryData *query; - - host_lookup_list = g_slist_prepend( - host_lookup_list, g_strdup(host)); - host_lookup_list = g_slist_prepend( - host_lookup_list, fba); - - query = purple_dnsquery_a(host, 80, - fb_host_lookup_cb, host_lookup_list); - fba->dns_queries = g_slist_prepend(fba->dns_queries, query); - host_lookup_list = g_slist_append(host_lookup_list, query); - } - } - fbconn = g_new0(FacebookConnection, 1); fbconn->fba = fba; fbconn->url = real_url; @@ -627,7 +596,20 @@ static void fb_attempt_connection(FacebookConnection *fbconn) { + gboolean is_proxy = FALSE; FacebookAccount *fba = fbconn->fba; + PurpleProxyInfo *proxy_info = NULL; + + if (fba && fba->account && !(fbconn->method & FB_METHOD_SSL)) + { + proxy_info = purple_proxy_get_setup(fba->account); + if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) + proxy_info = purple_global_proxy_get_info(); + if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP) + { + is_proxy = TRUE; + } + } #if 0 /* Connection to attempt retries. This code doesn't work perfectly, but @@ -651,6 +633,44 @@ fba->conns = g_slist_prepend(fba->conns, fbconn); + /* + * Do a separate DNS lookup for the given host name and cache it + * for next time. + * + * TODO: It would be better if we did this before we call + * purple_proxy_connect(), so we could re-use the result. + * Or even better: Use persistent HTTP connections for servers + * that we access continually. + * + * TODO: This cache of the hostname<-->IP address does not respect + * the TTL returned by the DNS server. We should expire things + * from the cache after some amount of time. + */ + if (!is_proxy && !(fbconn->method & FB_METHOD_SSL) && !g_hostname_is_ip_address(fbconn->hostname)) + { + /* Don't do this for proxy connections, since proxies do the DNS lookup */ + gchar *host_ip; + + host_ip = g_hash_table_lookup(fba->hostname_ip_cache, fbconn->hostname); + if (host_ip != NULL) { + g_free(fbconn->hostname); + fbconn->hostname = g_strdup(host_ip); + } else if (fba->account && !fba->account->disconnecting) { + GSList *host_lookup_list = NULL; + PurpleDnsQueryData *query; + + host_lookup_list = g_slist_prepend( + host_lookup_list, g_strdup(fbconn->hostname)); + host_lookup_list = g_slist_prepend( + host_lookup_list, fba); + + query = purple_dnsquery_a(fbconn->hostname, 80, + fb_host_lookup_cb, host_lookup_list); + fba->dns_queries = g_slist_prepend(fba->dns_queries, query); + host_lookup_list = g_slist_append(host_lookup_list, query); + } + } + if (fbconn->method & FB_METHOD_SSL) { fbconn->ssl_conn = purple_ssl_connect(fba->account, fbconn->hostname, 443, fb_post_or_get_ssl_connect_cb, diff -ru pidgin-facebookchat/fb_messages.c ../pidgin-facebookchat-read-only/fb_messages.c --- pidgin-facebookchat/fb_messages.c 2010-10-09 12:33:13.000000000 +0200 +++ ../pidgin-facebookchat-read-only/fb_messages.c 2011-04-15 10:53:37.143218950 +0200 @@ -332,7 +332,7 @@ purple_debug_info("facebook", "getting new messages\n"); - fetch_server = g_strdup_printf("%d.%s.facebook.com", 0, channel_number); + fetch_server = g_strdup_printf("%d-%s.facebook.com", 0, channel_number); /* use the current time in the url to get past any transparent proxy caches */ fetch_url = g_strdup_printf("/x/%lu/%s/p_%" G_GINT64_FORMAT "=%d", (gulong)time(NULL), (fba->is_idle?"false":"true"), fba->uid, fba->message_fetch_sequence); @@ -398,9 +398,10 @@ jstime = g_strdup_printf("%ld%ld", msg->time.tv_sec, (msg->time.tv_usec/1000)); encoded_message = g_strdup(purple_url_encode(msg->message)); - postdata = g_strdup_printf("msg_text=%s&msg_id=%d&to=%s&client_time=%s&post_form_id=%s", + postdata = g_strdup_printf("msg_text=%s&msg_id=%d&to=%s&client_time=%s&post_form_id=%s&fb_dtsg=%s", encoded_message, msg->msg_id, msg->who, jstime, - msg->fba->post_form_id ? msg->fba->post_form_id : "0"); + msg->fba->post_form_id ? msg->fba->post_form_id : "0", + msg->fba->dtsg ? msg->fba->dtsg : "(null)"); g_free(encoded_message); g_free(jstime); diff -ru pidgin-facebookchat/libfacebook.c ../pidgin-facebookchat-read-only/libfacebook.c --- pidgin-facebookchat/libfacebook.c 2010-11-27 11:55:56.000000000 +0100 +++ ../pidgin-facebookchat-read-only/libfacebook.c 2011-04-15 10:53:37.153218826 +0200 @@ -812,6 +812,12 @@ "facebook_manage_friends", FALSE); prpl_info->protocol_options = g_list_append( prpl_info->protocol_options, option); + + option = purple_account_option_bool_new( + _("Always use HTTPS"), + "use-https", FALSE); + prpl_info->protocol_options = g_list_append( + prpl_info->protocol_options, option); } static PurplePluginProtocolInfo prpl_info = {