changeset 12887:4229503f1cd9

[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 <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Sun, 15 Jan 2006 22:58:52 +0000
parents d8e8feac6cce
children 03f690fcb78e
files plugins/ChangeLog.API src/util.c src/util.h src/xmlnode.h
diffstat 4 files changed, 113 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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);
--- 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.
  *
--- 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);