/pidgin/main: 3b8ce83bac96: HTTP: get rid of one (of two) msn's ...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Mon Jul 22 12:37:41 EDT 2013
Changeset: 3b8ce83bac9646c8a8756656b62cbf4d0acc74c1
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2013-07-22 18:37 +0200
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/3b8ce83bac96
Description:
HTTP: get rid of one (of two) msn's own http implementations
diffstat:
libpurple/http.c | 34 +-
libpurple/protocols/msn/httpconn.c | 947 +++++++++++-------------------------
libpurple/protocols/msn/httpconn.h | 87 +--
libpurple/protocols/msn/servconn.c | 5 +-
libpurple/protocols/msn/servconn.h | 2 +
libpurple/sslconn.c | 11 +
libpurple/sslconn.h | 10 +
7 files changed, 391 insertions(+), 705 deletions(-)
diffs (truncated from 1349 to 300 lines):
diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -216,6 +216,12 @@ static GList *purple_http_hc_list;
static GHashTable *purple_http_hc_by_gc;
/**
+ * Keys: pointers to PurpleConnection.
+ * Values: gboolean TRUE.
+ */
+static GHashTable *purple_http_cancelling_gc;
+
+/**
* Keys: pointers to PurpleHttpConnection.
* Values: pointers to links in purple_http_hc_list.
*/
@@ -448,6 +454,8 @@ purple_http_socket_dontwatch(PurpleHttpS
if (hs->inpa > 0)
purple_input_remove(hs->inpa);
hs->inpa = 0;
+ if (hs->ssl_connection)
+ purple_ssl_input_remove(hs->ssl_connection);
}
static void
@@ -1451,6 +1459,13 @@ PurpleHttpConnection * purple_http_reque
return NULL;
}
+ if (g_hash_table_lookup(purple_http_cancelling_gc, gc)) {
+ purple_debug_warning("http", "Cannot perform another HTTP "
+ "request while cancelling all related with this "
+ "PurpleConnection\n");
+ return NULL;
+ }
+
hc = purple_http_connection_new(request, gc);
hc->callback = callback;
hc->user_data = user_data;
@@ -1589,15 +1604,19 @@ void purple_http_conn_cancel_all(PurpleC
{
GList *gc_list = g_hash_table_lookup(purple_http_hc_by_gc, gc);
+ g_hash_table_insert(purple_http_cancelling_gc, gc, GINT_TO_POINTER(TRUE));
+
while (gc_list) {
PurpleHttpConnection *hc = gc_list->data;
gc_list = g_list_next(gc_list);
purple_http_conn_cancel(hc);
}
+ g_hash_table_remove(purple_http_cancelling_gc, gc);
+
if (NULL != g_hash_table_lookup(purple_http_hc_by_gc, gc))
- purple_debug_error("http", "Couldn't cancel all connections "
- "related to gc=%p\n", gc);
+ purple_debug_fatal("http", "Couldn't cancel all connections "
+ "related to gc=%p (it shouldn't happen)\n", gc);
}
gboolean purple_http_conn_is_running(PurpleHttpConnection *http_conn)
@@ -2011,6 +2030,9 @@ purple_http_keepalive_pool_request(Purpl
g_free(hash);
+ if (purple_debug_is_verbose())
+ purple_debug_misc("http", "locking a socket: %p\n", hs);
+
return hs;
}
@@ -2025,6 +2047,9 @@ purple_http_keepalive_pool_release(Purpl
return;
}
+ if (purple_debug_is_verbose())
+ purple_debug_misc("http", "releasing a socket: %p\n", hs);
+
purple_http_socket_dontwatch(hs);
hs->is_busy = FALSE;
@@ -2386,6 +2411,8 @@ gboolean purple_http_response_is_success
if (code <= 0)
return FALSE;
+ /* TODO: HTTP/1.1 100 Continue */
+
if (code / 100 == 2)
return TRUE;
@@ -2797,6 +2824,7 @@ void purple_http_init(void)
purple_http_hc_by_ptr = g_hash_table_new(g_direct_hash, g_direct_equal);
purple_http_hc_by_gc = g_hash_table_new_full(g_direct_hash,
g_direct_equal, NULL, (GDestroyNotify)g_list_free);
+ purple_http_cancelling_gc = g_hash_table_new(g_direct_hash, g_direct_equal);
}
static void purple_http_foreach_conn_cancel(gpointer _hc, gpointer user_data)
@@ -2829,4 +2857,6 @@ void purple_http_uninit(void)
purple_http_hc_by_gc = NULL;
g_hash_table_destroy(purple_http_hc_by_ptr);
purple_http_hc_by_ptr = NULL;
+ g_hash_table_destroy(purple_http_cancelling_gc);
+ purple_http_cancelling_gc = NULL;
}
diff --git a/libpurple/protocols/msn/httpconn.c b/libpurple/protocols/msn/httpconn.c
--- a/libpurple/protocols/msn/httpconn.c
+++ b/libpurple/protocols/msn/httpconn.c
@@ -1,5 +1,5 @@
/**
- * @file httpconn.c HTTP connection method
+ * @file httpconn.h HTTP-tunnelled connections
*
* purple
*
@@ -19,581 +19,88 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
-#include "msn.h"
-#include "debug.h"
+
#include "httpconn.h"
-typedef struct
+#include "debug.h"
+#include "http.h"
+
+#include "msn.h"
+
+typedef struct _MsnHttpConnWriteQueueElement MsnHttpConnWriteQueueElement;
+
+struct _MsnHttpConn
{
- MsnHttpConn *httpconn;
- char *body;
- size_t body_len;
-} MsnHttpQueueData;
+ MsnServConn *servconn;
-static void
-msn_httpconn_process_queue(MsnHttpConn *httpconn)
+ gboolean connected;
+ gboolean is_disconnecting;
+ gboolean is_externally_disconnected;
+
+ gchar *host_dest;
+ gchar *host_gw;
+ int port;
+
+ gchar *session_id; /* changes after every request */
+
+ PurpleHttpConnection *current_request;
+ int polling_timer;
+ int finish_timer;
+ PurpleHttpKeepalivePool *keepalive_pool;
+ GSList *write_queue;
+};
+
+struct _MsnHttpConnWriteQueueElement
{
- httpconn->waiting_response = FALSE;
+ gchar *data;
+ size_t len;
+};
- if (httpconn->queue != NULL)
- {
- MsnHttpQueueData *queue_data;
+static MsnHttpConnWriteQueueElement *
+msn_httpconn_writequeueelement_new(const gchar *data, size_t len)
+{
+ MsnHttpConnWriteQueueElement *wqe;
- queue_data = (MsnHttpQueueData *)httpconn->queue->data;
+ g_return_val_if_fail(!(len > 0 && data == NULL), NULL);
- httpconn->queue = g_list_remove(httpconn->queue, queue_data);
+ wqe = g_new(MsnHttpConnWriteQueueElement, 1);
+ wqe->data = g_memdup(data, len);
+ wqe->len = len;
- msn_httpconn_write(queue_data->httpconn,
- queue_data->body,
- queue_data->body_len);
-
- g_free(queue_data->body);
- g_free(queue_data);
- }
-}
-
-static gboolean
-msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf,
- size_t size, char **ret_buf, size_t *ret_size,
- gboolean *error)
-{
- const char *s, *c;
- char *header, *body;
- const char *body_start;
- char *tmp;
- size_t body_len = 0;
-
- g_return_val_if_fail(httpconn != NULL, FALSE);
- g_return_val_if_fail(buf != NULL, FALSE);
- g_return_val_if_fail(size > 0, FALSE);
- g_return_val_if_fail(ret_buf != NULL, FALSE);
- g_return_val_if_fail(ret_size != NULL, FALSE);
- g_return_val_if_fail(error != NULL, FALSE);
-
-#if 0
- purple_debug_info("msn", "HTTP: parsing data {%s}\n", buf);
-#endif
-
- /* Healthy defaults. */
- body = NULL;
-
- *ret_buf = NULL;
- *ret_size = 0;
- *error = FALSE;
-
- /* First, some tests to see if we have a full block of stuff. */
- if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) &&
- (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) &&
- ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) &&
- (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0)))
- {
- *error = TRUE;
-
- return FALSE;
- }
-
- if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0)
- {
- if ((s = strstr(buf, "\r\n\r\n")) == NULL)
- return FALSE;
-
- s += 4;
-
- if (*s == '\0')
- {
- *ret_buf = g_strdup("");
- *ret_size = 0;
-
- msn_httpconn_process_queue(httpconn);
-
- return TRUE;
- }
-
- size -= (s - buf);
- buf = s;
- }
-
- if ((s = strstr(buf, "\r\n\r\n")) == NULL)
- /* Need to wait for the full HTTP header to arrive */
- return FALSE;
-
- s += 4; /* Skip \r\n\r\n */
- header = g_strndup(buf, s - buf);
- body_start = s;
- body_len = size - (body_start - buf);
-
- if ((s = purple_strcasestr(header, "Content-Length: ")) != NULL)
- {
- int tmp_len;
-
- s += strlen("Content-Length: ");
-
- if ((c = strchr(s, '\r')) == NULL)
- {
- g_free(header);
-
- return FALSE;
- }
-
- tmp = g_strndup(s, c - s);
- tmp_len = atoi(tmp);
- g_free(tmp);
-
- if (body_len != tmp_len)
- {
- /* Need to wait for the full packet to arrive */
-
- g_free(header);
-
-#if 0
- purple_debug_warning("msn",
- "body length (%d) != content length (%d)\n",
- body_len, tmp_len);
-#endif
-
- return FALSE;
- }
- }
-
- body = g_malloc(body_len + 1);
- memcpy(body, body_start, body_len);
- body[body_len] = '\0';
More information about the Commits
mailing list