libsoup r1079 - in trunk: . libsoup tests



Author: danw
Date: Sat Feb  9 00:46:12 2008
New Revision: 1079
URL: http://svn.gnome.org/viewvc/libsoup?rev=1079&view=rev

Log:
	* libsoup/soup-message-headers.c (SoupMessageHeadersIter)
	(soup_message_headers_iter_init, soup_message_headers_iter_next):
	Add an iterator type for SoupMessageHeaders.

	* libsoup/soup-message-client-io.c (get_request_headers):
	* libsoup/soup-message-server-io.c (get_response_headers): Use
	SoupMessageHeadersIter.

	* libsoup/soup-logger.c (print_request, print_response): Use
	SoupMessageHeadersIter. And take advantage of the simplification
	to fix the kludge where 'direction' was stored as a field in
	SoupLoggerPrivate rather than being an argument to
	soup_logger_print.

	* tests/get.c (get_url):
	* tests/header-parsing.c (check_headers):
	* tests/simple-httpd.c (server_callback): Use
	SoupMessageHeadersIter


Modified:
   trunk/ChangeLog
   trunk/libsoup/soup-logger.c
   trunk/libsoup/soup-message-client-io.c
   trunk/libsoup/soup-message-headers.c
   trunk/libsoup/soup-message-headers.h
   trunk/libsoup/soup-message-server-io.c
   trunk/tests/get.c
   trunk/tests/header-parsing.c
   trunk/tests/simple-httpd.c

Modified: trunk/libsoup/soup-logger.c
==============================================================================
--- trunk/libsoup/soup-logger.c	(original)
+++ trunk/libsoup/soup-logger.c	Sat Feb  9 00:46:12 2008
@@ -91,7 +91,6 @@
 	SoupLoggerPrinter   printer;
 	gpointer            printer_data;
 	GDestroyNotify      printer_dnotify;
-	char                direction;
 } SoupLoggerPrivate;
 #define SOUP_LOGGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_LOGGER, SoupLoggerPrivate))
 
@@ -373,7 +372,7 @@
 
 static void
 soup_logger_print (SoupLogger *logger, SoupLoggerLogLevel level,
-		   const char *format, ...)
+		   char direction, const char *format, ...)
 {
 	SoupLoggerPrivate *priv = SOUP_LOGGER_GET_PRIVATE (logger);
 	va_list args;
@@ -394,10 +393,10 @@
 		if (end)
 			*end = '\0';
 		if (priv->printer) {
-			priv->printer (logger, level, priv->direction,
+			priv->printer (logger, level, direction,
 				       line, priv->printer_data);
 		} else
-			printf ("%c %s\n", priv->direction, line);
+			printf ("%c %s\n", direction, line);
 
 		line = end + 1;
 	} while (end && *line);
@@ -406,28 +405,22 @@
 }
 
 static void
-print_header (const char *name, const char *value, gpointer logger)
+soup_logger_print_basic_auth (SoupLogger *logger, const char *value)
 {
-	if (!g_ascii_strcasecmp (name, "Authorization") &&
-	    !g_ascii_strncasecmp (value, "Basic ", 6)) {
-		char *decoded, *p;
-		gsize len;
-
-		decoded = (char *)g_base64_decode (value + 6, &len);
-		if (!decoded)
-			decoded = g_strdup (value);
-		p = strchr (decoded, ':');
-		if (p) {
-			while (++p < decoded + len)
-				*p = '*';
-		}
-		soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS,
-				   "%s: Basic [%.*s]", name, len, decoded);
-		g_free (decoded);
-	} else {
-		soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS,
-				   "%s: %s", name, value);
+	char *decoded, *p;
+	gsize len;
+
+	decoded = (char *)g_base64_decode (value + 6, &len);
+	if (!decoded)
+		decoded = g_strdup (value);
+	p = strchr (decoded, ':');
+	if (p) {
+		while (++p < decoded + len)
+			*p = '*';
 	}
+	soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>',
+			   "Authorization: Basic [%.*s]", len, decoded);
+	g_free (decoded);
 }
 
 static void
@@ -437,6 +430,8 @@
 {
 	SoupLoggerPrivate *priv = SOUP_LOGGER_GET_PRIVATE (logger);
 	SoupLoggerLogLevel log_level;
+	SoupMessageHeadersIter iter;
+	const char *name, *value;
 	SoupURI *uri;
 
 	if (priv->request_filter) {
@@ -448,16 +443,14 @@
 	if (log_level == SOUP_LOGGER_LOG_NONE)
 		return;
 
-	priv->direction = '>';
-
 	uri = soup_message_get_uri (msg);
 	if (msg->method == SOUP_METHOD_CONNECT) {
-		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL,
+		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
 				   "CONNECT %s:%u HTTP/1.%d",
 				   uri->host, uri->port,
 				   soup_message_get_http_version (msg));
 	} else {
-		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL,
+		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
 				   "%s %s%s%s HTTP/1.%d",
 				   msg->method, uri->path,
 				   uri->query ? "?" : "",
@@ -465,10 +458,10 @@
 				   soup_message_get_http_version (msg));
 	}
 
-	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL,
+	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
 			   "Soup-Debug-Timestamp: %lu",
 			   (unsigned long)time (0));
-	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL,
+	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
 			   "Soup-Debug: %s %u (%p), %s %u (%p), %s %u (%p)%s",
 			   g_type_name_from_instance ((GTypeInstance *)session),
 			   soup_logger_get_id (logger, session), session,
@@ -481,9 +474,18 @@
 	if (log_level == SOUP_LOGGER_LOG_MINIMAL)
 		return;
 
-	print_header ("Host", uri->host, logger);
-	soup_message_headers_foreach (msg->request_headers,
-				      print_header, logger);
+	soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>',
+			   "Host: %s", uri->host);
+	soup_message_headers_iter_init (&iter, msg->request_headers);
+	while (soup_message_headers_iter_next (&iter, &name, &value)) {
+		if (!g_ascii_strcasecmp (name, "Authorization") &&
+		    !g_ascii_strncasecmp (value, "Basic ", 6))
+			soup_logger_print_basic_auth (logger, value);
+		else {
+			soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>',
+					   "%s: %s", name, value);
+		}
+	}
 	if (log_level == SOUP_LOGGER_LOG_HEADERS)
 		return;
 
@@ -494,7 +496,7 @@
 		soup_buffer_free (request);
 
 		if (soup_message_headers_get_expectations (msg->request_headers) != SOUP_EXPECTATION_CONTINUE) {
-			soup_logger_print (logger, SOUP_LOGGER_LOG_BODY,
+			soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '>',
 					   "\n%s", msg->request_body->data);
 		}
 	}
@@ -505,6 +507,8 @@
 {
 	SoupLoggerPrivate *priv = SOUP_LOGGER_GET_PRIVATE (logger);
 	SoupLoggerLogLevel log_level;
+	SoupMessageHeadersIter iter;
+	const char *name, *value;
 
 	if (priv->response_filter) {
 		log_level = priv->response_filter (logger, msg,
@@ -515,17 +519,15 @@
 	if (log_level == SOUP_LOGGER_LOG_NONE)
 		return;
 
-	priv->direction = '<';
-
-	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL,
+	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '<',
 			   "HTTP/1.%d %u %s\n",
 			   soup_message_get_http_version (msg),
 			   msg->status_code, msg->reason_phrase);
 
-	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL,
+	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '<',
 			   "Soup-Debug-Timestamp: %lu",
 			   (unsigned long)time (0));
-	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL,
+	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '<',
 			   "Soup-Debug: %s %u (%p)",
 			   g_type_name_from_instance ((GTypeInstance *)msg),
 			   soup_logger_get_id (logger, msg), msg);
@@ -533,13 +535,16 @@
 	if (log_level == SOUP_LOGGER_LOG_MINIMAL)
 		return;
 
-	soup_message_headers_foreach (msg->response_headers,
-				     print_header, logger);
+	soup_message_headers_iter_init (&iter, msg->response_headers);
+	while (soup_message_headers_iter_next (&iter, &name, &value)) {
+		soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '<',
+				   "%s: %s", name, value);
+	}
 	if (log_level == SOUP_LOGGER_LOG_HEADERS)
 		return;
 
 	if (msg->response_body->length) {
-		soup_logger_print (logger, SOUP_LOGGER_LOG_BODY,
+		soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '<',
 				   "\n%s", msg->response_body->data);
 	}
 }
@@ -553,14 +558,12 @@
 	g_mutex_lock (priv->lock);
 
 	print_response (logger, msg);
-	priv->direction = ' ';
-	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, "");
+	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, ' ', "");
 
 	if (msg->status_code == SOUP_STATUS_CONTINUE && msg->request_body->data) {
 		SoupLoggerLogLevel log_level;
 
-		priv->direction = '>';
-		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL,
+		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
 				   "[Now sending request body...]");
 
 		if (priv->request_filter) {
@@ -570,12 +573,11 @@
 			log_level = priv->level;
 
 		if (log_level == SOUP_LOGGER_LOG_BODY) {
-			soup_logger_print (logger, SOUP_LOGGER_LOG_BODY,
+			soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '>',
 					   "%s", msg->request_body->data);
 		}
 
-		priv->direction = ' ';
-		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, "");
+		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, ' ', "");
 	}
 
 	g_mutex_unlock (priv->lock);
@@ -590,8 +592,7 @@
 	g_mutex_lock (priv->lock);
 
 	print_response (logger, msg);
-	priv->direction = ' ';
-	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, "");
+	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, ' ', "");
 
 	g_mutex_unlock (priv->lock);
 }
@@ -613,7 +614,6 @@
 		 SoupSocket *socket, gpointer user_data)
 {
 	SoupLogger *logger = user_data;
-	SoupLoggerPrivate *priv = SOUP_LOGGER_GET_PRIVATE (logger);
 	gboolean restarted;
 	guint msg_id;
 
@@ -639,6 +639,5 @@
 		soup_logger_set_id (logger, socket);
 
 	print_request (logger, msg, session, socket, restarted);
-	priv->direction = ' ';
-	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, "");
+	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, ' ', "");
 }

Modified: trunk/libsoup/soup-message-client-io.c
==============================================================================
--- trunk/libsoup/soup-message-client-io.c	(original)
+++ trunk/libsoup/soup-message-client-io.c	Sat Feb  9 00:46:12 2008
@@ -59,13 +59,6 @@
 	return SOUP_STATUS_OK;
 }
 
-static void 
-add_header (const char *name, const char *value, gpointer data)
-{
-	GString *headers = data;
-	g_string_append_printf (headers, "%s: %s\r\n", name, value);
-}
-
 static void
 get_request_headers (SoupMessage *req, GString *header,
 		     SoupEncoding *encoding, gpointer user_data)
@@ -74,6 +67,8 @@
 	gboolean proxy = GPOINTER_TO_UINT (user_data);
 	SoupURI *uri = soup_message_get_uri (req);
 	char *uri_string;
+	SoupMessageHeadersIter iter;
+	const char *name, *value;
 
 	if (req->method == SOUP_METHOD_CONNECT) {
 		/* CONNECT URI is hostname:port for tunnel destination */
@@ -108,7 +103,9 @@
 							 req->request_body->length);
 	}
 
-	soup_message_headers_foreach (req->request_headers, add_header, header);
+	soup_message_headers_iter_init (&iter, req->request_headers);
+	while (soup_message_headers_iter_next (&iter, &name, &value))
+		g_string_append_printf (header, "%s: %s\r\n", name, value);
 	g_string_append (header, "\r\n");
 }
 

Modified: trunk/libsoup/soup-message-headers.c
==============================================================================
--- trunk/libsoup/soup-message-headers.c	(original)
+++ trunk/libsoup/soup-message-headers.c	Sat Feb  9 00:46:12 2008
@@ -257,6 +257,71 @@
 }
 
 /**
+ * SoupMessageHeadersIter:
+ *
+ * An opaque type used to iterate over a %SoupMessageHeaders
+ * structure.
+ *
+ * After intializing the iterator with
+ * soup_message_headers_iter_init(), call
+ * soup_message_headers_iter_next() to fetch data from it.
+ *
+ * You may not modify the headers while iterating over them.
+ **/
+
+typedef struct {
+	SoupMessageHeaders *hdrs;
+	int index;
+} SoupMessageHeadersIterReal;
+
+/**
+ * soup_message_headers_iter_init:
+ * @iter: a pointer to a %SoupMessageHeadersIter structure
+ * @hdrs: a %SoupMessageHeaders
+ *
+ * Initializes @iter for iterating @hdrs.
+ **/
+void
+soup_message_headers_iter_init (SoupMessageHeadersIter *iter,
+				SoupMessageHeaders *hdrs)
+{
+	SoupMessageHeadersIterReal *real = (SoupMessageHeadersIterReal *)iter;
+
+	real->hdrs = hdrs;
+	real->index = 0;
+}
+
+/**
+ * soup_message_headers_iter_next:
+ * @iter: a %SoupMessageHeadersIter
+ * @name: pointer to a variable to return the header name in
+ * @value: pointer to a variable to return the header value in
+ *
+ * Yields the next name/value pair in the %SoupMessageHeaders being
+ * iterated by @iter. If @iter has already yielded the last header,
+ * then soup_message_headers_iter_next() will return %FALSE and @name
+ * and @value will be unchanged.
+ *
+ * Return value: %TRUE if another name and value were returned, %FALSE
+ * if the end of the headers has been reached.
+ **/
+gboolean
+soup_message_headers_iter_next (SoupMessageHeadersIter *iter,
+				const char **name, const char **value)
+{
+	SoupMessageHeadersIterReal *real = (SoupMessageHeadersIterReal *)iter;
+	SoupHeader *hdr_array = (SoupHeader *)real->hdrs->array->data;
+
+	if (real->index >= real->hdrs->array->len)
+		return FALSE;
+
+	*name = hdr_array[real->index].name;
+	*value = hdr_array[real->index].value;
+	real->index++;
+	return TRUE;
+}
+
+/**
  * SoupMessageHeadersForeachFunc:
  * @name: the header name
  * @value: the header value
@@ -281,6 +346,8 @@
  * then the I/O code will output multiple copies of the header when
  * sending the message to the remote implementation, which may be
  * required for interoperability in some cases.)
+ *
+ * You may not modify the headers from @func.
  **/
 void
 soup_message_headers_foreach (SoupMessageHeaders *hdrs,

Modified: trunk/libsoup/soup-message-headers.h
==============================================================================
--- trunk/libsoup/soup-message-headers.h	(original)
+++ trunk/libsoup/soup-message-headers.h	Sat Feb  9 00:46:12 2008
@@ -43,6 +43,16 @@
 						   SoupMessageHeadersForeachFunc func,
 						   gpointer            user_data);
 
+typedef struct {
+	gpointer dummy[3];
+} SoupMessageHeadersIter;
+
+void                soup_message_headers_iter_init (SoupMessageHeadersIter  *iter,
+						    SoupMessageHeaders      *hdrs);
+gboolean            soup_message_headers_iter_next (SoupMessageHeadersIter  *iter,
+						    const char             **name,
+						    const char             **value);
+
 /* Specific headers */
 
 typedef enum {

Modified: trunk/libsoup/soup-message-server-io.c
==============================================================================
--- trunk/libsoup/soup-message-server-io.c	(original)
+++ trunk/libsoup/soup-message-server-io.c	Sat Feb  9 00:46:12 2008
@@ -93,16 +93,12 @@
 }
 
 static void
-write_header (const char *name, const char *value, gpointer headers)
-{
-	g_string_append_printf (headers, "%s: %s\r\n", name, value);
-}
-
-static void
 get_response_headers (SoupMessage *msg, GString *headers,
 		      SoupEncoding *encoding, gpointer user_data)
 {
 	SoupEncoding claimed_encoding;
+	SoupMessageHeadersIter iter;
+	const char *name, *value;
 
 	g_string_append_printf (headers, "HTTP/1.1 %d %s\r\n",
 				msg->status_code, msg->reason_phrase);
@@ -124,8 +120,9 @@
 							 msg->response_body->length);
 	}
 
-	soup_message_headers_foreach (msg->response_headers,
-				      write_header, headers);
+	soup_message_headers_iter_init (&iter, msg->response_headers);
+	while (soup_message_headers_iter_next (&iter, &name, &value))
+		g_string_append_printf (headers, "%s: %s\r\n", name, value);
 	g_string_append (headers, "\r\n");
 }
 

Modified: trunk/tests/get.c
==============================================================================
--- trunk/tests/get.c	(original)
+++ trunk/tests/get.c	Sat Feb  9 00:46:12 2008
@@ -100,12 +100,6 @@
 }
 
 static void
-print_header (const char *name, const char *value, gpointer data)
-{
-	printf ("%s: %s\n", name, value);
-}
-
-static void
 get_url (const char *url)
 {
 	char *url_to_get, *slash, *name;
@@ -158,13 +152,19 @@
 	}
 
 	if (debug) {
+		SoupMessageHeadersIter iter;
+		const char *name, *value;
 		char *path = soup_uri_to_string (soup_message_get_uri (msg), TRUE);
+
 		printf ("%s %s HTTP/1.%d\n\n", method, path,
 			soup_message_get_http_version (msg));
 		printf ("HTTP/1.%d %d %s\n",
 			soup_message_get_http_version (msg),
 			msg->status_code, msg->reason_phrase);
-		soup_message_headers_foreach (msg->response_headers, print_header, NULL);
+
+		soup_message_headers_iter_init (&iter, msg->response_headers);
+		while (soup_message_headers_iter_next (&iter, &name, &value))
+			printf ("%s: %s\r\n", name, value);
 		printf ("\n");
 	} else
 		printf ("%s: %d %s\n", name, msg->status_code, msg->reason_phrase);

Modified: trunk/tests/header-parsing.c
==============================================================================
--- trunk/tests/header-parsing.c	(original)
+++ trunk/tests/header-parsing.c	Sat Feb  9 00:46:12 2008
@@ -577,25 +577,22 @@
 	debug_printf (1, "              '%s': '%s'\n", name, value);
 }
 
-static void
-add_header_name (const char *name, const char *value, gpointer data)
-{
-	GSList **names = data;
-
-	if (!g_slist_find_custom (*names, name, (GCompareFunc)strcmp))
-		*names = g_slist_append (*names, (char *)name);
-}
-
 static gboolean
 check_headers (Header *headers, SoupMessageHeaders *hdrs)
 {
 	GSList *header_names, *h;
-	const char *value;
+	SoupMessageHeadersIter iter;
+	const char *name, *value;
 	gboolean ok = TRUE;
 	int i;
 
 	header_names = NULL;
-	soup_message_headers_foreach (hdrs, add_header_name, &header_names);
+	soup_message_headers_iter_init (&iter, hdrs);
+	while (soup_message_headers_iter_next (&iter, &name, &value)) {
+		if (!g_slist_find_custom (header_names, name,
+					  (GCompareFunc)strcmp))
+			header_names = g_slist_append (header_names, (char *)name);
+	}
 
 	for (i = 0, h = header_names; headers[i].name && h; i++, h = h->next) {
 		if (strcmp (h->data, headers[i].name) != 0) {

Modified: trunk/tests/simple-httpd.c
==============================================================================
--- trunk/tests/simple-httpd.c	(original)
+++ trunk/tests/simple-httpd.c	Sat Feb  9 00:46:12 2008
@@ -155,21 +155,19 @@
 }
 
 static void
-print_header (const char *name, const char *value, gpointer data)
-{
-	printf ("%s: %s\n", name, value);
-}
-
-static void
 server_callback (SoupServer *server, SoupMessage *msg,
 		 const char *path, GHashTable *query,
 		 SoupClientContext *context, gpointer data)
 {
 	char *file_path;
+	SoupMessageHeadersIter iter;
+	const char *name, *value;
 
 	printf ("%s %s HTTP/1.%d\n", msg->method, path,
 		soup_message_get_http_version (msg));
-	soup_message_headers_foreach (msg->request_headers, print_header, NULL);
+	soup_message_headers_iter_init (&iter, msg->request_headers);
+	while (soup_message_headers_iter_next (&iter, &name, &value))
+		printf ("%s: %s\n", name, value);
 	if (msg->request_body->length)
 		printf ("%s\n", msg->request_body->data);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]