libsoup r1070 - in trunk: . libsoup tests



Author: danw
Date: Sun Feb  3 02:17:54 2008
New Revision: 1070
URL: http://svn.gnome.org/viewvc/libsoup?rev=1070&view=rev

Log:
	* libsoup/soup-headers.c (soup_headers_parse_request): if the
	request headers contain an unrecognized Expect: header, return
	SOUP_STATUS_EXPECTATION_FAILED. Also, process Connection headers
	in HTTP/1.0 messages as required by 2616 14.10.
	(soup_headers_parse_response): Likewise handle Connection headers
	in HTTP/1.0 messages

	* tests/header-parsing.c: test those things


Modified:
   trunk/ChangeLog
   trunk/libsoup/soup-headers.c
   trunk/tests/header-parsing.c

Modified: trunk/libsoup/soup-headers.c
==============================================================================
--- trunk/libsoup/soup-headers.c	(original)
+++ trunk/libsoup/soup-headers.c	Sun Feb  3 02:17:54 2008
@@ -105,6 +105,23 @@
 	return success;
 }
 
+/* RFC 2616 14.10 */
+static void
+soup_headers_clean_for_10 (SoupMessageHeaders *hdrs)
+{
+	const char *connection;
+	GSList *tokens, *t;
+
+	connection = soup_message_headers_get (hdrs, "Connection");
+	if (!connection)
+		return;
+
+	tokens = soup_header_parse_list (connection);
+	for (t = tokens; t; t = t->next)
+		soup_message_headers_remove (hdrs, t->data);
+	soup_header_free_list (tokens);
+}
+
 /**
  * soup_headers_parse_request:
  * @str: the header string (including the trailing blank line)
@@ -195,6 +212,12 @@
 	if (!soup_headers_parse (str, len, req_headers)) 
 		return SOUP_STATUS_BAD_REQUEST;
 
+	if (soup_message_headers_get_expectations (req_headers) &
+	    SOUP_EXPECTATION_UNRECOGNIZED)
+		return SOUP_STATUS_EXPECTATION_FAILED;
+	if (minor_version == 0)
+		soup_headers_clean_for_10 (req_headers);
+
 	if (req_method)
 		*req_method = g_strndup (method, method_end - method);
 	if (req_path)
@@ -300,6 +323,8 @@
 			     guint               *status_code,
 			     char               **reason_phrase)
 {
+	SoupHTTPVersion version;
+
 	if (!str || !*str)
 		return FALSE;
 
@@ -307,10 +332,15 @@
 		return FALSE;
 
 	if (!soup_headers_parse_status_line (str, 
-					     ver, 
+					     &version, 
 					     status_code, 
 					     reason_phrase))
 		return FALSE;
+	if (ver)
+		*ver = version;
+
+	if (version == SOUP_HTTP_1_0)
+		soup_headers_clean_for_10 (headers);
 
 	return TRUE;
 }

Modified: trunk/tests/header-parsing.c
==============================================================================
--- trunk/tests/header-parsing.c	(original)
+++ trunk/tests/header-parsing.c	Sun Feb  3 02:17:54 2008
@@ -168,6 +168,16 @@
 	  }
 	},
 
+	{ "Connection header on HTTP/1.0 message",
+	  "GET / HTTP/1.0\r\nFoo: bar\r\nConnection: Bar, Quux\r\nBar: baz\r\nQuux: foo\r\n", -1,
+	  SOUP_STATUS_OK,
+	  "GET", "/", SOUP_HTTP_1_0,
+	  { { "Foo", "bar" },
+	    { "Connection", "Bar, Quux" },
+	    { NULL }
+	  }
+	},
+
 	/****************************/
 	/*** RECOVERABLE REQUESTS ***/
 	/****************************/
@@ -328,6 +338,12 @@
 	  { { NULL } }
 	},
 
+	{ "Unrecognized expectation",
+	  "GET / HTTP/1.1\r\nHost: example.com\r\nExpect: the-impossible\r\n", -1,
+	  SOUP_STATUS_EXPECTATION_FAILED,
+	  NULL, NULL, -1,
+	  { { NULL } }
+	}
 };
 static const int num_reqtests = G_N_ELEMENTS (reqtests);
 
@@ -395,6 +411,15 @@
 	  }
 	},
 
+	{ "Connection header on HTTP/1.0 message",
+	  "HTTP/1.0 200 ok\r\nFoo: bar\r\nConnection: Bar\r\nBar: quux\r\n", -1,
+	  SOUP_HTTP_1_0, SOUP_STATUS_OK, "ok",
+	  { { "Foo", "bar" },
+	    { "Connection", "Bar" },
+	    { NULL }
+	  }
+	},
+
 	/*****************************/
 	/*** RECOVERABLE RESPONSES ***/
 	/*****************************/
@@ -552,24 +577,41 @@
 	debug_printf (1, "              '%s': '%s'\n", name, value);
 }
 
-typedef struct {
-	Header *headers;
-	int i;
-	gboolean ok;
-} HeaderForeachData;
+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)
 {
-	int i;
+	GSList *header_names, *h;
 	const char *value;
+	gboolean ok = TRUE;
+	int i;
 
-	for (i = 0; headers[i].name; i++) {
+	header_names = NULL;
+	soup_message_headers_foreach (hdrs, add_header_name, &header_names);
+
+	for (i = 0, h = header_names; headers[i].name && h; i++, h = h->next) {
+		if (strcmp (h->data, headers[i].name) != 0) {
+			ok = FALSE;
+			break;
+		}
 		value = soup_message_headers_get (hdrs, headers[i].name);
-		if (strcmp (value, headers[i].value) != 0)
-			return FALSE;
+		if (strcmp (value, headers[i].value) != 0) {
+			ok = FALSE;
+			break;
+		}
 	}
-	return TRUE;
+	if (headers[i].name || h)
+		ok = FALSE;
+	g_slist_free (header_names);
+	return ok;
 }
 
 static void



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