# HG changeset patch # User Daniel Atallah # Date 1137365932 0 # Node ID 4229503f1cd9009988b70e4c24e719c638ad6582 # Parent d8e8feac6cceb1ae421f7ed13d87bec18d4c9f25 [gaim-migrate @ 15240] Added gaim_url_fetch_request(), which is an enhancement to the gaim_url_fetch() functionality that allows you to specify the request that gets submitted to the server and whether or not the headers are also returned. I'm going to use this for the UPnP stuff (watch this space). Also fixed a tyop in the xmlnode docs. Remove the status documentation from the API Changelog. committer: Tailor Script diff -r d8e8feac6cce -r 4229503f1cd9 plugins/ChangeLog.API --- a/plugins/ChangeLog.API Sun Jan 15 18:13:03 2006 +0000 +++ b/plugins/ChangeLog.API Sun Jan 15 22:58:52 2006 +0000 @@ -232,35 +232,7 @@ * gaim_gtk_log_init() * gaim_gtk_log_get_handle() * gaim_gtk_log_uninit() - * gaim_accounts_restore_current_statuses() - * gaim_savedstatus_new() - * gaim_savedstatus_set_title() - * gaim_savedstatus_set_type() - * gaim_savedstatus_set_message() - * gaim_savedstatus_set_substatus() - * gaim_savedstatus_unset_substatus() - * gaim_savedstatus_delete() - * gaim_savedstatus_get_all() - * gaim_savedstatus_get_popular() - * gaim_savedstatus_get_current() - * gaim_savedstatus_get_startup() - * gaim_savedstatus_get_idleaway() - * gaim_savedstatus_find() - * gaim_savedstatus_find_by_creation_time() - * gaim_savedstatus_is_transient() - * gaim_savedstatus_get_title() - * gaim_savedstatus_get_type() - * gaim_savedstatus_get_message() - * gaim_savedstatus_get_creation_time() - * gaim_savedstatus_has_substatuses() - * gaim_savedstatus_get_substatus() - * gaim_savedstatus_substatus_get_type() - * gaim_savedstatus_substatus_get_message() - * gaim_savedstatus_activate() - * gaim_savedstatus_activate_for_account() - * gaim_savedstatuses_get_handle() - * gaim_savedstatuses_init() - * gaim_savedstatuses_uninit() + * gaim_url_fetch_request() Signals - Changed: (See the Doxygen docs for details on all signals.) * Signal propagation now stops after a handler returns a non-NULL value. diff -r d8e8feac6cce -r 4229503f1cd9 src/util.c --- a/src/util.c Sun Jan 15 18:13:03 2006 +0000 +++ b/src/util.c Sun Jan 15 22:58:52 2006 +0000 @@ -48,6 +48,8 @@ gboolean full; char *user_agent; gboolean http11; + char *request; + gboolean include_headers; int inpa; @@ -2860,13 +2862,14 @@ static void destroy_fetch_url_data(GaimFetchUrlData *gfud) { - if (gfud->webdata != NULL) g_free(gfud->webdata); - if (gfud->url != NULL) g_free(gfud->url); - if (gfud->user_agent != NULL) g_free(gfud->user_agent); - if (gfud->website.address != NULL) g_free(gfud->website.address); - if (gfud->website.page != NULL) g_free(gfud->website.page); - if (gfud->website.user != NULL) g_free(gfud->website.user); - if (gfud->website.passwd != NULL) g_free(gfud->website.passwd); + g_free(gfud->webdata); + g_free(gfud->url); + g_free(gfud->user_agent); + g_free(gfud->website.address); + g_free(gfud->website.page); + g_free(gfud->website.user); + g_free(gfud->website.passwd); + g_free(gfud->request); g_free(gfud); } @@ -2920,8 +2923,9 @@ gaim_debug_info("gaim_url_fetch", "Redirecting to %s\n", new_url); /* Try again, with this new location. */ - gaim_url_fetch(new_url, full, gfud->user_agent, gfud->http11, - gfud->callback, gfud->user_data); + gaim_url_fetch_request(new_url, full, gfud->user_agent, + gfud->http11, gfud->request, gfud->include_headers, + gfud->callback, gfud->user_data); /* Free up. */ g_free(new_url); @@ -2944,12 +2948,28 @@ * Note: data is _not_ nul-terminated. */ if (data_len > 16) { - p = strncmp(data, "Content-Length: ", 16) == 0? data: NULL; + p = strncmp(data, "Content-Length: ", 16) == 0 ? data : NULL; if (!p) { p = g_strstr_len(data, data_len, "\nContent-Length: "); if (p) p += 1; } + if (!p) + p = (strncmp(data, "CONTENT-LENGTH: ", 16) == 0) + ? data : NULL; + if (!p) { + p = g_strstr_len(data, data_len, "\nContent-Length: "); + if (p) + p++; + } + if (!p) { + p = g_strstr_len(data, data_len, "\nCONTENT-LENGTH: "); + if (p) + p++; + } + + if (p) + p += 16; } /* If we can find a Content-Length header at all, try to sscanf it. @@ -2957,7 +2977,7 @@ * if we make sure that there is indeed a \n in our header. */ if (p && g_strstr_len(p, data_len - (p - data), "\n")) { - sscanf(p, "Content-Length: %" G_GSIZE_FORMAT, &content_len); + sscanf(p, "%" G_GSIZE_FORMAT, &content_len); gaim_debug_misc("parse_content_len", "parsed %u\n", content_len); } @@ -2984,44 +3004,47 @@ if (!gfud->sentreq) { + char *send; char buf[1024]; - if (gfud->user_agent) - { - /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1 - * clients must know how to handle the "chunked" transfer encoding. - * Gaim doesn't know how to handle "chunked", so should always send - * the Host header regardless, to get around some observed problems - */ - g_snprintf(buf, sizeof(buf), - "GET %s%s HTTP/%s\r\n" - "Connection: close\r\n" - "User-Agent: %s\r\n" - "Host: %s\r\n\r\n", - (gfud->full ? "" : "/"), - (gfud->full ? gfud->url : gfud->website.page), - (gfud->http11 ? "1.1" : "1.0"), - gfud->user_agent, gfud->website.address); + if (gfud->request) { + send = gfud->request; + } else { + if (gfud->user_agent) { + /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1 + * clients must know how to handle the "chunked" transfer encoding. + * Gaim doesn't know how to handle "chunked", so should always send + * the Host header regardless, to get around some observed problems + */ + g_snprintf(buf, sizeof(buf), + "GET %s%s HTTP/%s\r\n" + "Connection: close\r\n" + "User-Agent: %s\r\n" + "Host: %s\r\n\r\n", + (gfud->full ? "" : "/"), + (gfud->full ? gfud->url : gfud->website.page), + (gfud->http11 ? "1.1" : "1.0"), + gfud->user_agent, gfud->website.address); + } else { + g_snprintf(buf, sizeof(buf), + "GET %s%s HTTP/%s\r\n" + "Connection: close\r\n" + "Host: %s\r\n\r\n", + (gfud->full ? "" : "/"), + (gfud->full ? gfud->url : gfud->website.page), + (gfud->http11 ? "1.1" : "1.0"), + gfud->website.address); + } + send = buf; } - else - { - g_snprintf(buf, sizeof(buf), - "GET %s%s HTTP/%s\r\n" - "Connection: close\r\n" - "Host: %s\r\n\r\n", - (gfud->full ? "" : "/"), - (gfud->full ? gfud->url : gfud->website.page), - (gfud->http11 ? "1.1" : "1.0"), - gfud->website.address); - } - - gaim_debug_misc("gaim_url_fetch", "Request: %s\n", buf); - - write(sock, buf, strlen(buf)); + + gaim_debug_misc("gaim_url_fetch", "Request: %s\n", send); + + write(sock, send, strlen(send)); fcntl(sock, F_SETFL, O_NONBLOCK); gfud->sentreq = TRUE; gfud->inpa = gaim_input_add(sock, GAIM_INPUT_READ, - url_fetched_cb, url_data); + url_fetched_cb, url_data); gfud->data_len = 4096; gfud->webdata = g_malloc(gfud->data_len); @@ -3078,10 +3101,17 @@ gfud->has_explicit_data_len = TRUE; } + content_len = MAX(content_len, body_len); + + /* If we're returning the headers too, we don't need to clean them out */ + if (gfud->include_headers) { + gfud->data_len = content_len + header_len; + return; + } + if (gfud->len > (header_len + 1)) body_len = (gfud->len - header_len); - content_len = MAX(content_len, body_len); new_data = g_try_malloc(content_len); if (new_data == NULL) { @@ -3151,10 +3181,10 @@ } void -gaim_url_fetch(const char *url, gboolean full, - const char *user_agent, gboolean http11, - void (*cb)(gpointer, const char *, size_t), - void *user_data) +gaim_url_fetch_request(const char *url, gboolean full, + const char *user_agent, gboolean http11, + const char *request, gboolean include_headers, + GaimURLFetchCallback cb, void *user_data) { GaimFetchUrlData *gfud; @@ -3167,12 +3197,14 @@ gfud = g_new0(GaimFetchUrlData, 1); - gfud->callback = cb; + gfud->callback = cb; gfud->user_data = user_data; - gfud->url = g_strdup(url); - gfud->user_agent = (user_agent != NULL ? g_strdup(user_agent) : NULL); - gfud->http11 = http11; - gfud->full = full; + gfud->url = g_strdup(url); + gfud->user_agent = user_agent ? g_strdup(user_agent) : NULL; + gfud->http11 = http11; + gfud->full = full; + gfud->request = request ? g_strdup(request) : NULL; + gfud->include_headers = include_headers; gaim_url_parse(url, &gfud->website.address, &gfud->website.port, &gfud->website.page, &gfud->website.user, &gfud->website.passwd); diff -r d8e8feac6cce -r 4229503f1cd9 src/util.h --- a/src/util.h Sun Jan 15 18:13:03 2006 +0000 +++ b/src/util.h Sun Jan 15 22:58:52 2006 +0000 @@ -747,6 +747,8 @@ gboolean gaim_url_parse(const char *url, char **ret_host, int *ret_port, char **ret_path, char **ret_user, char **ret_passwd); +typedef void (*GaimURLFetchCallback) (gpointer data, const char *buf, gsize len); + /** * Fetches the data from a URL, and passes it to a callback function. * @@ -758,10 +760,30 @@ * @param cb The callback function. * @param data The user data to pass to the callback function. */ -void gaim_url_fetch(const char *url, gboolean full, - const char *user_agent, gboolean http11, - void (*cb)(void *, const char *, size_t), - void *data); +#define gaim_url_fetch(url, full, user_agent, http11, cb, data) \ + gaim_url_fetch_request(url, full, user_agent, http11, NULL, \ + FALSE, cb, data); + +/** + * Fetches the data from a URL, and passes it to a callback function. + * + * @param url The URL. + * @param full TRUE if this is the full URL, or FALSE if it's a + * partial URL. + * @param user_agent The user agent field to use, or NULL. + * @param http11 TRUE if HTTP/1.1 should be used to download the file. + * @param request A HTTP request to send to the server instead of the + * standard GET + * @param include_headers if TRUE, include the HTTP headers in the + * response + * @param cb The callback function. + * @param data The user data to pass to the callback function. + */ +void gaim_url_fetch_request(const char *url, gboolean full, + const char *user_agent, gboolean http11, + const char *request, gboolean include_headers, + GaimURLFetchCallback cb, void *data); + /** * Decodes a URL into a plain string. * diff -r d8e8feac6cce -r 4229503f1cd9 src/xmlnode.h --- a/src/xmlnode.h Sun Jan 15 18:13:03 2006 +0000 +++ b/src/xmlnode.h Sun Jan 15 22:58:52 2006 +0000 @@ -159,7 +159,7 @@ * @param node The starting node to output. * @param len Address for the size of the string. * - * @return The node repersented as a string. You must + * @return The node represented as a string. You must * g_free this string when finished using it. */ char *xmlnode_to_str(xmlnode *node, int *len);