/pidgin/main: 8d0979967d05: HTTP: removing extra yahoo HTTP impl...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Fri Aug 9 06:57:37 EDT 2013
Changeset: 8d0979967d05b0f05b12c44eafd3b105fe1731cb
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2013-08-09 12:57 +0200
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/8d0979967d05
Description:
HTTP: removing extra yahoo HTTP implementations - file transfer (and small improvements to libpurple http and ft code)
diffstat:
libpurple/ft.c | 113 +-
libpurple/ft.h | 13 +
libpurple/http.c | 51 +-
libpurple/protocols/jabber/oob.c | 1 +
libpurple/protocols/yahoo/libyahoo.c | 3 -
libpurple/protocols/yahoo/libyahoojp.c | 3 -
libpurple/protocols/yahoo/libymsg.c | 4 +-
libpurple/protocols/yahoo/libymsg.h | 1 -
libpurple/protocols/yahoo/yahoo_filexfer.c | 1448 +++++----------------------
libpurple/protocols/yahoo/yahoo_filexfer.h | 5 -
libpurple/protocols/yahoo/yahoo_picture.c | 5 +-
11 files changed, 419 insertions(+), 1228 deletions(-)
diffs (truncated from 2128 to 300 lines):
diff --git a/libpurple/ft.c b/libpurple/ft.c
--- a/libpurple/ft.c
+++ b/libpurple/ft.c
@@ -1159,14 +1159,22 @@ purple_xfer_write_file(PurpleXfer *xfer,
if (fs_known && size > purple_xfer_get_bytes_remaining(xfer)) {
purple_debug_warning("filetransfer",
- "Got too much data (truncating).\n");
+ "Got too much data (truncating at %" G_GOFFSET_FORMAT
+ ").\n", purple_xfer_get_size(xfer));
size = purple_xfer_get_bytes_remaining(xfer);
}
if (ui_ops && ui_ops->ui_write)
wc = ui_ops->ui_write(xfer, buffer, size);
- else
+ else {
+ if (xfer->dest_fp == NULL) {
+ purple_debug_error("filetransfer",
+ "File is not opened for writing\n");
+ purple_xfer_cancel_local(xfer);
+ return FALSE;
+ }
wc = fwrite(buffer, 1, size, xfer->dest_fp);
+ }
if (wc != size) {
purple_debug_error("filetransfer",
@@ -1181,6 +1189,57 @@ purple_xfer_write_file(PurpleXfer *xfer,
return TRUE;
}
+gssize
+purple_xfer_read_file(PurpleXfer *xfer, guchar *buffer, gsize size)
+{
+ PurpleXferUiOps *ui_ops;
+ gssize got_len;
+
+ g_return_val_if_fail(xfer != NULL, FALSE);
+ g_return_val_if_fail(buffer != NULL, FALSE);
+
+ ui_ops = purple_xfer_get_ui_ops(xfer);
+
+ if (ui_ops && ui_ops->ui_read) {
+ guchar *buffer_got = NULL;
+
+ got_len = ui_ops->ui_read(xfer, &buffer_got, size);
+
+ if (got_len > size) {
+ g_free(buffer_got);
+ purple_debug_error("filetransfer",
+ "Got too much data from UI.\n");
+ purple_xfer_cancel_local(xfer);
+ return -1;
+ }
+
+ if (got_len > 0)
+ memcpy(buffer, buffer_got, got_len);
+ g_free(buffer_got);
+ } else {
+ if (xfer->dest_fp == NULL) {
+ purple_debug_error("filetransfer",
+ "File is not opened for reading\n");
+ purple_xfer_cancel_local(xfer);
+ return -1;
+ }
+ got_len = fread(buffer, 1, size, xfer->dest_fp);
+ if (got_len != size && ferror(xfer->dest_fp)) {
+ purple_debug_error("filetransfer",
+ "Unable to read file.\n");
+ purple_xfer_cancel_local(xfer);
+ return -1;
+ }
+ }
+
+ if (got_len > 0) {
+ purple_xfer_set_bytes_sent(xfer,
+ purple_xfer_get_bytes_sent(xfer) + got_len);
+ }
+
+ return got_len;
+}
+
static void
do_transfer(PurpleXfer *xfer)
{
@@ -1207,7 +1266,7 @@ do_transfer(PurpleXfer *xfer)
return;
}
} else if (xfer->type == PURPLE_XFER_SEND) {
- size_t result = 0;
+ gssize result = 0;
size_t s = MIN(purple_xfer_get_bytes_remaining(xfer), xfer->current_buffer_size);
PurpleXferPrivData *priv = g_hash_table_lookup(xfers_data, xfer);
gboolean read = TRUE;
@@ -1232,40 +1291,26 @@ do_transfer(PurpleXfer *xfer)
}
if (read) {
- if (ui_ops && ui_ops->ui_read) {
- gssize tmp = ui_ops->ui_read(xfer, &buffer, s);
- if (tmp == 0) {
- /*
- * The UI claimed it was ready, but didn't have any data for
- * us... It will call purple_xfer_ui_ready when ready, which
- * sets back up this watcher.
- */
- if (xfer->watcher != 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- }
-
- /* Need to indicate the prpl is still ready... */
- priv->ready |= PURPLE_XFER_READY_PRPL;
-
- g_return_if_reached();
- } else if (tmp < 0) {
- purple_debug_error("filetransfer", "Unable to read whole buffer.\n");
- purple_xfer_cancel_local(xfer);
- return;
+ buffer = g_new(guchar, s);
+ result = purple_xfer_read_file(xfer, buffer, s);
+ if (result == 0) {
+ /*
+ * The UI claimed it was ready, but didn't have any data for
+ * us... It will call purple_xfer_ui_ready when ready, which
+ * sets back up this watcher.
+ */
+ if (xfer->watcher != 0) {
+ purple_input_remove(xfer->watcher);
+ xfer->watcher = 0;
}
- result = tmp;
- } else {
- buffer = g_malloc(s);
- result = fread(buffer, 1, s, xfer->dest_fp);
- if (result != s) {
- purple_debug_error("filetransfer", "Unable to read whole buffer.\n");
- purple_xfer_cancel_local(xfer);
- g_free(buffer);
- return;
- }
+ /* Need to indicate the prpl is still ready... */
+ priv->ready |= PURPLE_XFER_READY_PRPL;
+
+ g_return_if_reached();
}
+ if (result < 0)
+ return;
}
if (priv->buffer) {
diff --git a/libpurple/ft.h b/libpurple/ft.h
--- a/libpurple/ft.h
+++ b/libpurple/ft.h
@@ -641,6 +641,19 @@ gboolean
purple_xfer_write_file(PurpleXfer *xfer, const guchar *buffer, gsize size);
/**
+ * Writes chunk of file being sent.
+ *
+ * @param xfer The file transfer.
+ * @param buffer The buffer to write the data to.
+ * @param size The size of buffer.
+ *
+ * @return Number of bytes written (0 means, the device is busy), or -1 on
+ * failure.
+ */
+gssize
+purple_xfer_read_file(PurpleXfer *xfer, guchar *buffer, gsize size);
+
+/**
* Starts a file transfer.
*
* Either @a fd must be specified <i>or</i> @a ip and @a port on a
diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -868,18 +868,18 @@ static gboolean _purple_http_recv_header
hdrline[hdrline_len] = '\0';
if (hdrline[0] == '\0') {
- if (!hc->main_header_got && hc->is_keepalive) {
- if (purple_debug_is_verbose()) {
+ if (!hc->main_header_got) {
+ if (purple_debug_is_verbose() &&
+ hc->is_keepalive)
+ {
purple_debug_misc("http", "Got keep-"
"alive terminator from previous"
" request\n");
+ } else {
+ purple_debug_warning("http", "Got empty"
+ " line at the beginning - this "
+ "may be a HTTP server quirk\n");
}
- } else if (!hc->main_header_got) {
- hc->response->code = 0;
- purple_debug_warning("http",
- "Main header not present\n");
- _purple_http_error(hc, _("Error parsing HTTP"));
- return FALSE;
} else /* hc->main_header_got */ {
hc->headers_got = TRUE;
if (purple_debug_is_verbose()) {
@@ -939,6 +939,8 @@ static gboolean _purple_http_recv_body_d
}
if (hc->request->max_length >= 0) {
if (hc->length_got + len > hc->request->max_length) {
+ purple_debug_warning("http",
+ "Maximum length exceeded, truncating\n");
len = hc->request->max_length - hc->length_got;
hc->length_expected = hc->request->max_length;
}
@@ -1086,6 +1088,12 @@ static gboolean _purple_http_recv_loopbo
/* EOF */
if (len == 0) {
+ if (hc->request->max_length == 0) {
+ /* It's definitely YHttpServer quirk. */
+ purple_debug_warning("http", "Got EOF, but no data was "
+ "expected (this may be a server quirk)\n");
+ hc->length_expected = hc->length_got;
+ }
if (hc->length_expected >= 0 &&
hc->length_got < hc->length_expected) {
purple_debug_warning("http", "No more data while reading"
@@ -1101,10 +1109,21 @@ static gboolean _purple_http_recv_loopbo
purple_http_conn_retry(hc);
return FALSE;
} else {
- purple_debug_warning("http", "No more data while "
- "parsing headers\n");
- _purple_http_error(hc, _("Error parsing HTTP"));
- return FALSE;
+ if (g_ascii_strcasecmp(purple_http_headers_get(
+ hc->response->headers, "Server"),
+ "YHttpServer") == 0)
+ {
+ purple_debug_warning("http", "No more data "
+ "while parsing headers (YHttpServer "
+ "quirk)\n");
+ hc->headers_got = TRUE;
+ hc->length_expected = hc->length_got = 0;
+ } else {
+ purple_debug_warning("http", "No more data "
+ "while parsing headers\n");
+ _purple_http_error(hc, _("Error parsing HTTP"));
+ return FALSE;
+ }
}
}
@@ -2252,13 +2271,17 @@ purple_http_keepalive_pool_release(Purpl
hs->is_busy = FALSE;
host = hs->host;
+ if (host == NULL) {
+ purple_http_socket_close_free(hs);
+ return;
+ }
+
if (invalidate) {
host->sockets = g_slist_remove(host->sockets, hs);
purple_http_socket_close_free(hs);
}
- if (host != NULL)
- purple_http_keepalive_host_process_queue(host);
+ purple_http_keepalive_host_process_queue(host);
}
void
diff --git a/libpurple/protocols/jabber/oob.c b/libpurple/protocols/jabber/oob.c
--- a/libpurple/protocols/jabber/oob.c
+++ b/libpurple/protocols/jabber/oob.c
@@ -122,6 +122,7 @@ static void jabber_oob_xfer_start(Purple
JabberOOBXfer *jox = purple_xfer_get_protocol_data(xfer);
req = purple_http_request_new(jox->url);
+ purple_http_request_set_timeout(req, -1);
purple_http_request_set_max_len(req, -1);
purple_http_request_set_response_writer(req, jabber_oob_xfer_writer,
xfer);
diff --git a/libpurple/protocols/yahoo/libyahoo.c b/libpurple/protocols/yahoo/libyahoo.c
--- a/libpurple/protocols/yahoo/libyahoo.c
+++ b/libpurple/protocols/yahoo/libyahoo.c
@@ -312,9 +312,6 @@ init_plugin(PurplePlugin *plugin)
option = purple_account_option_string_new(_("File transfer server"), "xfer_host", YAHOO_XFER_HOST);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_int_new(_("File transfer port"), "xfer_port", YAHOO_XFER_PORT);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
option = purple_account_option_string_new(_("Chat room locale"), "room_list_locale", YAHOO_ROOMLIST_LOCALE);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
diff --git a/libpurple/protocols/yahoo/libyahoojp.c b/libpurple/protocols/yahoo/libyahoojp.c
--- a/libpurple/protocols/yahoo/libyahoojp.c
More information about the Commits
mailing list