Wed, 07 Aug 2013 15:54:44 +0530
Merged default branch
--- a/libpurple/protocols/yahoo/libymsg.c Wed Aug 07 03:36:33 2013 +0530 +++ b/libpurple/protocols/yahoo/libymsg.c Wed Aug 07 15:54:44 2013 +0530 @@ -3731,8 +3731,7 @@ yd->rxlen = 0; g_free(yd->picture_url); - if (yd->buddy_icon_connect_data) - purple_proxy_connect_cancel(yd->buddy_icon_connect_data); + purple_http_conn_cancel(yd->picture_upload_hc); if (yd->picture_upload_todo) yahoo_buddy_icon_upload_data_free(yd->picture_upload_todo); if (yd->ycht)
--- a/libpurple/protocols/yahoo/libymsg.h Wed Aug 07 03:36:33 2013 +0530 +++ b/libpurple/protocols/yahoo/libymsg.h Wed Aug 07 15:54:44 2013 +0530 @@ -150,11 +150,8 @@ struct yahoo_buddy_icon_upload_data { PurpleConnection *gc; - GString *str; char *filename; - int pos; - int fd; - guint watcher; + GString *picture_data; }; struct yahoo_p2p_data { @@ -236,7 +233,7 @@ /* ew. we have to check the icon before we connect, * but can't upload it til we're connected. */ struct yahoo_buddy_icon_upload_data *picture_upload_todo; - PurpleProxyConnectData *buddy_icon_connect_data; + PurpleHttpConnection *picture_upload_hc; struct _YchtConn *ycht;
--- a/libpurple/protocols/yahoo/yahoo_picture.c Wed Aug 07 03:36:33 2013 +0530 +++ b/libpurple/protocols/yahoo/yahoo_picture.c Wed Aug 07 15:54:44 2013 +0530 @@ -328,176 +328,100 @@ { purple_debug_misc("yahoo", "In yahoo_buddy_icon_upload_data_free()\n"); - if (d->str) - g_string_free(d->str, TRUE); + if (d->picture_data) + g_string_free(d->picture_data, TRUE); g_free(d->filename); - if (d->watcher) - purple_input_remove(d->watcher); - if (d->fd != -1) - close(d->fd); g_free(d); } -/* we couldn't care less about the server's response, but yahoo gets grumpy if we close before it sends it */ -static void yahoo_buddy_icon_upload_reading(gpointer data, gint source, PurpleInputCondition condition) +static void +yahoo_buddy_icon_upload_done(PurpleHttpConnection *http_conn, + PurpleHttpResponse *response, gpointer _d) { - struct yahoo_buddy_icon_upload_data *d = data; + struct yahoo_buddy_icon_upload_data *d = _d; PurpleConnection *gc = d->gc; - char buf[1024]; - int ret; - - if (!PURPLE_CONNECTION_IS_VALID(gc)) { - yahoo_buddy_icon_upload_data_free(d); - return; - } + YahooData *yd = purple_connection_get_protocol_data(gc); - ret = read(d->fd, buf, sizeof(buf)); + yd->picture_upload_hc = NULL; - if (ret < 0 && errno == EAGAIN) - return; - else if (ret <= 0) { - /* There are other problems if d->str->len overflows, so shut up the - * warning on 64-bit. */ - purple_debug_info("yahoo", "Buddy icon upload response (%" G_GSIZE_FORMAT ") bytes (> ~400 indicates failure):\n%.*s\n", - d->str->len, (guint)d->str->len, d->str->str); + if (!purple_http_response_is_successfull(response)) + purple_debug_info("yahoo", "Error uploading buddy icon.\n"); + else + purple_debug_misc("yahoo", "Finished uploading buddy icon.\n"); - yahoo_buddy_icon_upload_data_free(d); - return; - } - - g_string_append_len(d->str, buf, ret); + yahoo_buddy_icon_upload_data_free(d); } -static void yahoo_buddy_icon_upload_pending(gpointer data, gint source, PurpleInputCondition condition) +static void +yahoo_buddy_icon_build_packet(struct yahoo_buddy_icon_upload_data *d) { - struct yahoo_buddy_icon_upload_data *d = data; + struct yahoo_packet *pkt; PurpleConnection *gc = d->gc; - gssize wrote; - - if (!PURPLE_CONNECTION_IS_VALID(gc)) { - yahoo_buddy_icon_upload_data_free(d); - return; - } - - wrote = write(d->fd, d->str->str + d->pos, d->str->len - d->pos); - if (wrote < 0 && errno == EAGAIN) - return; - if (wrote <= 0) { - purple_debug_info("yahoo", "Error uploading buddy icon.\n"); - yahoo_buddy_icon_upload_data_free(d); - return; - } - d->pos += wrote; - if (d->pos >= d->str->len) { - purple_debug_misc("yahoo", "Finished uploading buddy icon.\n"); - purple_input_remove(d->watcher); - /* Clean out the sent buffer and reuse it to read the result */ - g_string_free(d->str, TRUE); - d->str = g_string_new(""); - d->watcher = purple_input_add(d->fd, PURPLE_INPUT_READ, yahoo_buddy_icon_upload_reading, d); - } -} + YahooData *yd = purple_connection_get_protocol_data(gc); + gchar *len_str; + guchar *pkt_buf; + gsize pkt_buf_len; -static void yahoo_buddy_icon_upload_connected(gpointer data, gint source, const gchar *error_message) -{ - struct yahoo_buddy_icon_upload_data *d = data; - struct yahoo_packet *pkt; - gchar *tmp, *header; - guchar *pkt_buf; - const char *host; - int port; - gsize pkt_buf_len; - PurpleConnection *gc = d->gc; - PurpleAccount *account; - YahooData *yd; - /* use whole URL if using HTTP Proxy */ - gboolean use_whole_url = yahoo_account_use_http_proxy(gc); + pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, + YAHOO_STATUS_AVAILABLE, yd->session_id); - account = purple_connection_get_account(gc); - yd = purple_connection_get_protocol_data(gc); - - /* Buddy icon connect is now complete; clear the PurpleProxyConnectData */ - yd->buddy_icon_connect_data = NULL; - - if (source < 0) { - purple_debug_error("yahoo", "Buddy icon upload failed: %s\n", error_message); - yahoo_buddy_icon_upload_data_free(d); - return; - } - - pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, YAHOO_STATUS_AVAILABLE, yd->session_id); - - tmp = g_strdup_printf("%" G_GSIZE_FORMAT, d->str->len); - /* 1 = me, 38 = expire time(?), 0 = me, 28 = size, 27 = filename, 14 = NULL, 29 = data */ + len_str = g_strdup_printf("%" G_GSIZE_FORMAT, d->picture_data->len); + /* 1 = me, 38 = expire time(?), 0 = me, 28 = size, 27 = filename, + * 14 = NULL, 29 = data + */ yahoo_packet_hash_str(pkt, 1, purple_connection_get_display_name(gc)); yahoo_packet_hash_str(pkt, 38, "604800"); /* time til expire */ - purple_account_set_int(account, YAHOO_PICEXPIRE_SETTING, time(NULL) + 604800); + purple_account_set_int(purple_connection_get_account(gc), + YAHOO_PICEXPIRE_SETTING, time(NULL) + 604800); yahoo_packet_hash_str(pkt, 0, purple_connection_get_display_name(gc)); - yahoo_packet_hash_str(pkt, 28, tmp); - g_free(tmp); + yahoo_packet_hash_str(pkt, 28, len_str); + g_free(len_str); yahoo_packet_hash_str(pkt, 27, d->filename); yahoo_packet_hash_str(pkt, 14, ""); /* 4 padding for the 29 key name */ pkt_buf_len = yahoo_packet_build(pkt, 4, FALSE, yd->jp, &pkt_buf); yahoo_packet_free(pkt); - /* header + packet + "29" + 0xc0 + 0x80) + pictureblob */ - - host = purple_account_get_string(account, "xfer_host", yd->jp? YAHOOJP_XFER_HOST : YAHOO_XFER_HOST); - port = purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT); - tmp = g_strdup_printf("%s:%d", host, port); - header = g_strdup_printf("POST %s%s/notifyft HTTP/1.1\r\n" - "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n" - "Cookie: T=%s; Y=%s\r\n" - "Host: %s\r\n" - "Content-Length: %" G_GSIZE_FORMAT "\r\n" - "Cache-Control: no-cache\r\n\r\n", - use_whole_url ? "http://" : "", use_whole_url ? tmp : "", - yd->cookie_t, yd->cookie_y, - tmp, - pkt_buf_len + 4 + d->str->len); - g_free(tmp); + /* There's no magic here, we just need to prepend in reverse order */ + g_string_prepend(d->picture_data, "29\xc0\x80"); - /* There's no magic here, we just need to prepend in reverse order */ - g_string_prepend(d->str, "29\xc0\x80"); - - g_string_prepend_len(d->str, (char *)pkt_buf, pkt_buf_len); + g_string_prepend_len(d->picture_data, (char *)pkt_buf, pkt_buf_len); g_free(pkt_buf); - - g_string_prepend(d->str, header); - g_free(header); - - /* There are other problems if we're uploading over 4GB of data */ - purple_debug_info("yahoo", "Buddy icon upload data:\n%.*s\n", (guint)d->str->len, d->str->str); - - d->fd = source; - d->watcher = purple_input_add(d->fd, PURPLE_INPUT_WRITE, yahoo_buddy_icon_upload_pending, d); - - yahoo_buddy_icon_upload_pending(d, d->fd, PURPLE_INPUT_WRITE); } -void yahoo_buddy_icon_upload(PurpleConnection *gc, struct yahoo_buddy_icon_upload_data *d) +void +yahoo_buddy_icon_upload(PurpleConnection *gc, + struct yahoo_buddy_icon_upload_data *d) { + PurpleHttpRequest *req; + PurpleHttpCookieJar *cjar; PurpleAccount *account = purple_connection_get_account(gc); YahooData *yd = purple_connection_get_protocol_data(gc); - if (yd->buddy_icon_connect_data != NULL) { - /* Cancel any in-progress buddy icon upload */ - purple_proxy_connect_cancel(yd->buddy_icon_connect_data); - yd->buddy_icon_connect_data = NULL; - } + /* Cancel any in-progress buddy icon upload */ + purple_http_conn_cancel(yd->picture_upload_hc); - yd->buddy_icon_connect_data = purple_proxy_connect(NULL, account, - purple_account_get_string(account, "xfer_host", - yd->jp? YAHOOJP_XFER_HOST : YAHOO_XFER_HOST), - purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_buddy_icon_upload_connected, d); + req = purple_http_request_new(NULL); + purple_http_request_set_url_printf(req, "http://%s:%d/notifyft", + purple_account_get_string(account, "xfer_host", yd->jp ? + YAHOOJP_XFER_HOST : YAHOO_XFER_HOST), + purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT)); + purple_http_request_set_method(req, "POST"); + cjar = purple_http_request_get_cookie_jar(req); + purple_http_cookie_jar_set(cjar, "T", yd->cookie_t); + purple_http_cookie_jar_set(cjar, "Y", yd->cookie_y); + purple_http_request_header_set(req, "Cache-Control", "no-cache"); + purple_http_request_header_set(req, "User-Agent", + YAHOO_CLIENT_USERAGENT); - if (yd->buddy_icon_connect_data == NULL) - { - purple_debug_error("yahoo", "Uploading our buddy icon failed to connect.\n"); - yahoo_buddy_icon_upload_data_free(d); - } + yahoo_buddy_icon_build_packet(d); + purple_http_request_set_contents(req, d->picture_data->str, + d->picture_data->len); + g_string_free(d->picture_data, TRUE); + d->picture_data = NULL; + + yd->picture_upload_hc = purple_http_request(gc, req, + yahoo_buddy_icon_upload_done, d); } static int yahoo_buddy_icon_calculate_checksum(const guchar *data, gsize len) @@ -564,8 +488,7 @@ /* We use this solely for sending a filename to the server */ d = g_new0(struct yahoo_buddy_icon_upload_data, 1); d->gc = gc; - d->str = s; - d->fd = -1; + d->picture_data = s; d->filename = g_strdup(purple_imgstore_get_filename(img)); if (!yd->logged_in) {
--- a/libpurple/protocols/yahoo/yahoochat.c Wed Aug 07 03:36:33 2013 +0530 +++ b/libpurple/protocols/yahoo/yahoochat.c Wed Aug 07 15:54:44 2013 +0530 @@ -1178,31 +1178,19 @@ } struct yahoo_roomlist { - int fd; - int inpa; - gchar *txbuf; - gsize tx_written; - guchar *rxqueue; - int rxlen; - gboolean started; - char *path; - char *host; + PurpleHttpConnection *hc; + gchar *url; + PurpleRoomlist *list; PurpleRoomlistRoom *cat; PurpleRoomlistRoom *ucat; - GMarkupParseContext *parse; }; static void yahoo_roomlist_destroy(struct yahoo_roomlist *yrl) { - if (yrl->inpa) - purple_input_remove(yrl->inpa); - g_free(yrl->txbuf); - g_free(yrl->rxqueue); - g_free(yrl->path); - g_free(yrl->host); - if (yrl->parse) - g_markup_parse_context_free(yrl->parse); + purple_http_conn_cancel(yrl->hc); + g_free(yrl->url); + g_free(yrl); } @@ -1383,121 +1371,63 @@ purple_roomlist_unref(list); } -static void yahoo_roomlist_pending(gpointer data, gint source, PurpleInputCondition cond) +static void +yahoo_roomlist_got(PurpleHttpConnection *http_conn, + PurpleHttpResponse *response, gpointer _yrl) { - struct yahoo_roomlist *yrl = data; - PurpleRoomlist *list = yrl->list; - char buf[1024]; - int len; - guchar *start; - struct yahoo_chatxml_state *s; + struct yahoo_roomlist *yrl = _yrl; + PurpleConnection *gc; + GMarkupParseContext *parse; - len = read(yrl->fd, buf, sizeof(buf)); + yrl->hc = NULL; - if (len < 0 && errno == EAGAIN) - return; + gc = purple_account_get_connection(purple_roomlist_get_account( + yrl->list)); - if (len <= 0) { - if (yrl->parse) - g_markup_parse_context_end_parse(yrl->parse, NULL); - yahoo_roomlist_cleanup(list, yrl); + if (!purple_http_response_is_successfull(response)) { + purple_notify_error(gc, NULL, _("Unable to connect"), + _("Fetching the room list failed.")); + yahoo_roomlist_cleanup(yrl->list, yrl); return; } - yrl->rxqueue = g_realloc(yrl->rxqueue, len + yrl->rxlen); - memcpy(yrl->rxqueue + yrl->rxlen, buf, len); - yrl->rxlen += len; + parse = g_markup_parse_context_new(&parser, 0, + yahoo_chatxml_state_new(yrl->list, yrl), + (GDestroyNotify)yahoo_chatxml_state_destroy); - if (!yrl->started) { - yrl->started = TRUE; - start = (guchar *)g_strstr_len((char *)yrl->rxqueue, yrl->rxlen, "\r\n\r\n"); - if (!start || (start - yrl->rxqueue + 4) >= yrl->rxlen) - return; - start += 4; - } else { - start = yrl->rxqueue; - } - - if (yrl->parse == NULL) { - s = yahoo_chatxml_state_new(list, yrl); - yrl->parse = g_markup_parse_context_new(&parser, 0, s, - (GDestroyNotify)yahoo_chatxml_state_destroy); - } - - if (!g_markup_parse_context_parse(yrl->parse, (char *)start, (yrl->rxlen - (start - yrl->rxqueue)), NULL)) { - - yahoo_roomlist_cleanup(list, yrl); + if (!g_markup_parse_context_parse(parse, + purple_http_response_get_data(response, NULL), + purple_http_response_get_data_len(response), NULL)) + { + purple_debug_error("yahoo", "Couldn't parse the room list\n"); + yahoo_roomlist_cleanup(yrl->list, yrl); return; } - yrl->rxlen = 0; + g_markup_parse_context_free(parse); } -static void yahoo_roomlist_send_cb(gpointer data, gint source, PurpleInputCondition cond) +static void +yahoo_roomlist_make_request(struct yahoo_roomlist *yrl) { - struct yahoo_roomlist *yrl; - PurpleRoomlist *list; - int written, remaining; - - yrl = data; - list = yrl->list; - - remaining = strlen(yrl->txbuf) - yrl->tx_written; - written = write(yrl->fd, yrl->txbuf + yrl->tx_written, remaining); - - if (written < 0 && errno == EAGAIN) - written = 0; - else if (written <= 0) { - purple_input_remove(yrl->inpa); - yrl->inpa = 0; - g_free(yrl->txbuf); - yrl->txbuf = NULL; - purple_notify_error(purple_account_get_connection(purple_roomlist_get_account(list)), NULL, _("Unable to connect"), _("Fetching the room list failed.")); - yahoo_roomlist_cleanup(list, yrl); - return; - } - - if (written < remaining) { - yrl->tx_written += written; - return; - } - - g_free(yrl->txbuf); - yrl->txbuf = NULL; - - purple_input_remove(yrl->inpa); - yrl->inpa = purple_input_add(yrl->fd, PURPLE_INPUT_READ, - yahoo_roomlist_pending, yrl); - -} - -static void yahoo_roomlist_got_connected(gpointer data, gint source, const gchar *error_message) -{ - struct yahoo_roomlist *yrl = data; PurpleRoomlist *list = yrl->list; PurpleAccount *account = purple_roomlist_get_account(list); PurpleConnection *pc = purple_account_get_connection(account); YahooData *yd = purple_connection_get_protocol_data(pc); + PurpleHttpRequest *req; + PurpleHttpCookieJar *cjar; + PurpleConnection *gc; - if (source < 0) { - purple_notify_error(pc, NULL, _("Unable to connect"), _("Fetching the room list failed.")); - yahoo_roomlist_cleanup(list, yrl); - return; - } - - yrl->fd = source; + gc = purple_account_get_connection(purple_roomlist_get_account( + yrl->list)); - yrl->txbuf = g_strdup_printf( - "GET http://%s/%s HTTP/1.0\r\n" - "Host: %s\r\n" - "Cookie: Y=%s; T=%s\r\n\r\n", - yrl->host, yrl->path, yrl->host, yd->cookie_y, - yd->cookie_t); + req = purple_http_request_new(yrl->url); + cjar = purple_http_request_get_cookie_jar(req); + purple_http_cookie_jar_set(cjar, "Y", yd->cookie_y); + purple_http_cookie_jar_set(cjar, "T", yd->cookie_t); - - yrl->inpa = purple_input_add(yrl->fd, PURPLE_INPUT_WRITE, - yahoo_roomlist_send_cb, yrl); - yahoo_roomlist_send_cb(yrl, yrl->fd, PURPLE_INPUT_WRITE); + yrl->hc = purple_http_request(gc, req, yahoo_roomlist_got, yrl); + purple_http_request_unref(req); } PurpleRoomlist *yahoo_roomlist_get_list(PurpleConnection *gc) @@ -1505,7 +1435,6 @@ PurpleAccount *account; PurpleRoomlist *rl; PurpleRoomlistField *f; - PurpleHttpURL *url_p; GList *fields = NULL; struct yahoo_roomlist *yrl; const char *rll, *rlurl; @@ -1530,15 +1459,7 @@ rl = purple_roomlist_new(account); yrl->list = rl; - url_p = purple_http_url_parse(url); - g_free(url); - if (!url_p) { - purple_debug_error("yahoo", "Couldn't parse URL\n"); - return NULL; - } - yrl->host = g_strdup(purple_http_url_get_host(url_p)); - yrl->path = g_strdup(purple_http_url_get_path(url_p)); - purple_http_url_free(url_p); + yrl->url = url; f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "room", TRUE); fields = g_list_append(fields, f); @@ -1560,19 +1481,13 @@ purple_roomlist_set_fields(rl, fields); - if (purple_proxy_connect(gc, account, yrl->host, 80, - yahoo_roomlist_got_connected, yrl) == NULL) - { - purple_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list.")); - yahoo_roomlist_cleanup(rl, yrl); - return NULL; - } - proto_data = purple_roomlist_get_proto_data(rl); proto_data = g_list_append(proto_data, yrl); purple_roomlist_set_proto_data(rl, proto_data); + yahoo_roomlist_make_request(yrl); purple_roomlist_set_in_progress(rl, TRUE); + return rl; } @@ -1595,7 +1510,6 @@ void yahoo_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category) { PurpleAccount *account; - PurpleHttpURL *url_p; struct yahoo_roomlist *yrl; char *url; char *id; @@ -1632,30 +1546,12 @@ proto_data = g_list_append(proto_data, yrl); purple_roomlist_set_proto_data(list, proto_data); - url_p = purple_http_url_parse(url); - g_free(url); - if (!url_p) { - purple_debug_error("yahoo", "Couldn't parse URL\n"); - return; - } - yrl->host = g_strdup(purple_http_url_get_host(url_p)); - yrl->path = g_strdup(purple_http_url_get_path(url_p)); - purple_http_url_free(url_p); + yrl->url = url; yrl->ucat = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat); purple_roomlist_room_add(list, yrl->ucat); - if (purple_proxy_connect(purple_account_get_connection(account), - account, yrl->host, 80, - yahoo_roomlist_got_connected, yrl) == NULL) - { - purple_notify_error(purple_account_get_connection(account), - NULL, _("Connection problem"), _("Unable to fetch room list.")); - purple_roomlist_ref(list); - yahoo_roomlist_cleanup(list, yrl); - return; - } - + yahoo_roomlist_make_request(yrl); purple_roomlist_set_in_progress(list, TRUE); purple_roomlist_ref(list); }