pidgin: a2f4d295: Re-combine large (multi-part) messages o...
qulogic at pidgin.im
qulogic at pidgin.im
Tue Jan 27 00:25:44 EST 2009
-----------------------------------------------------------------
Revision: a2f4d295f1d985858eacada121adb414f6cc924b
Ancestor: 33bcab783c3ff4bedbd9ffdfdb29f232a0d6e8b9
Author: qulogic at pidgin.im
Date: 2009-01-27T05:22:10
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/a2f4d295f1d985858eacada121adb414f6cc924b
Modified files:
ChangeLog libpurple/protocols/msn/cmdproc.c
libpurple/protocols/msn/cmdproc.h
libpurple/protocols/msn/msg.h
ChangeLog:
Re-combine large (multi-part) messages on MSN since we seem to say that we
do support receiving chunked messages.
References #393, though not the same as the patch in the ticket.
-------------- next part --------------
============================================================
--- ChangeLog 9061088e68eb10d8d6d7243f0598ba91b0e3aa49
+++ ChangeLog 256e2933978e764565acd28e12b5947db99bc811
@@ -5,6 +5,7 @@ version 2.5.5 (??/??/????):
* Fix transfer of buddy icons, custom smileys and files from the
latest WLM 9 official client. (Thomas Gibson-Robinson)
* Fix a crash when removing an account with an unknown protocol id.
+ * Large (multi-part) messages on MSN are now correctly re-combined.
Finch:
* Allow rebinding keys to change the focused widget (details in the
============================================================
--- libpurple/protocols/msn/cmdproc.c af0cf762cdce653bb98d968b8159bc8ff0f3ead8
+++ libpurple/protocols/msn/cmdproc.c 26f32ef7f803692995d9028c0655440151d22168
@@ -35,6 +35,9 @@ msn_cmdproc_new(MsnSession *session)
cmdproc->txqueue = g_queue_new();
cmdproc->history = msn_history_new();
+ cmdproc->multiparts = g_hash_table_new_full(g_str_hash, g_str_equal,
+ NULL, (GDestroyNotify)msn_message_unref);
+
return cmdproc;
}
@@ -53,6 +56,8 @@ msn_cmdproc_destroy(MsnCmdProc *cmdproc)
if (cmdproc->last_cmd != NULL)
msn_command_destroy(cmdproc->last_cmd);
+ g_hash_table_destroy(cmdproc->multiparts);
+
g_free(cmdproc);
}
@@ -235,7 +240,62 @@ msn_cmdproc_process_msg(MsnCmdProc *cmdp
msn_cmdproc_process_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
MsnMsgTypeCb cb;
+ const char *messageId = NULL;
+ /* Multi-part messages */
+ if ((messageId = msn_message_get_attr(msg, "Message-ID")) != NULL) {
+ const char *chunk_text = msn_message_get_attr(msg, "Chunks");
+ guint chunk;
+ if (chunk_text != NULL) {
+ chunk = strtol(chunk_text, NULL, 10);
+ /* 1024 chunks of ~1300 bytes is ~1MB, which seems OK to prevent
+ some random client causing pidgin to hog a ton of memory.
+ Probably should figure out the maximum that the official client
+ actually supports, though. */
+ if (chunk > 0 && chunk < 1024) {
+ msg->total_chunks = chunk;
+ msg->received_chunks = 1;
+ g_hash_table_insert(cmdproc->multiparts, (gpointer)messageId, msn_message_ref(msg));
+ purple_debug_info("msn", "Received chunked message, messageId: '%s', total chunks: %d\n",
+ messageId, chunk);
+ } else {
+ purple_debug_error("msn", "MessageId '%s' has too many chunks: %d\n", messageId, chunk);
+ }
+ return;
+ } else {
+ chunk_text = msn_message_get_attr(msg, "Chunk");
+ if (chunk_text != NULL) {
+ MsnMessage *first = g_hash_table_lookup(cmdproc->multiparts, messageId);
+ chunk = strtol(chunk_text, NULL, 10);
+ if (first == NULL) {
+ purple_debug_error("msn",
+ "Unable to find first chunk of messageId '%s' to correspond with chunk %d.\n",
+ messageId, chunk+1);
+ } else if (first->received_chunks == chunk) {
+ /* Chunk is from 1 to total-1 (doesn't count first one) */
+ purple_debug_info("msn", "Received chunk %d of %d, messageId: '%s'\n",
+ chunk+1, first->total_chunks, messageId);
+ first->body = g_realloc(first->body, first->body_len + msg->body_len);
+ memcpy(first->body + first->body_len, msg->body, msg->body_len);
+ first->body_len += msg->body_len;
+ first->received_chunks++;
+ if (first->received_chunks != first->total_chunks)
+ return;
+ else
+ /* We're done! Send it along... The caller takes care of
+ freeing the old one. */
+ msg = first;
+ } else {
+ /* TODO: Can you legitimately receive chunks out of order? */
+ g_hash_table_remove(cmdproc->multiparts, messageId);
+ return;
+ }
+ } else {
+ purple_debug_error("msn", "Received MessageId '%s' with no chunk number!\n", messageId);
+ }
+ }
+ }
+
if (msn_message_get_content_type(msg) == NULL)
{
purple_debug_misc("msn", "failed to find message content\n");
@@ -245,15 +305,14 @@ msn_cmdproc_process_msg(MsnCmdProc *cmdp
cb = g_hash_table_lookup(cmdproc->cbs_table->msgs,
msn_message_get_content_type(msg));
- if (cb == NULL)
- {
+ if (cb != NULL)
+ cb(cmdproc, msg);
+ else
purple_debug_warning("msn", "Unhandled content-type '%s'\n",
msn_message_get_content_type(msg));
- return;
- }
-
- cb(cmdproc, msg);
+ if (messageId != NULL)
+ g_hash_table_remove(cmdproc->multiparts, messageId);
}
void
============================================================
--- libpurple/protocols/msn/cmdproc.h 14484cdc00317352590dcc0dd06a0cbb9999caf2
+++ libpurple/protocols/msn/cmdproc.h 44bca181258d427bd44cf3a430fac597a58bef58
@@ -46,6 +46,8 @@ struct _MsnCmdProc
MsnHistory *history;
+ GHashTable *multiparts; /**< Multi-part message ID's */
+
void *data; /**< Extra data, like the switchboard. */
};
============================================================
--- libpurple/protocols/msn/msg.h 80aaa015f0a2fc7191b4f67b7232841ea326be6a
+++ libpurple/protocols/msn/msg.h 532196ca4e57132ff397d5b529b6b7299eba3c1f
@@ -109,6 +109,8 @@ struct _MsnMessage
char *charset;
char *body;
gsize body_len;
+ guint total_chunks; /**< How many chunks in this multi-part message */
+ guint received_chunks; /**< How many chunks we've received so far */
MsnSlpHeader msnslp_header;
MsnSlpFooter msnslp_footer;
More information about the Commits
mailing list