[libsoup/gnome-2-30] SoupSession: count redirections and cancel the message after too many



commit 7358449a55ccf19919fba62eb21b35628a2c5921
Author: José Millán Soto <jmillan igalia com>
Date:   Fri Jun 4 13:46:31 2010 +0200

    SoupSession: count redirections and cancel the message after too many
    
    and add a test to redirect-test
    
    https://bugzilla.gnome.org/show_bug.cgi?id=604383

 libsoup/soup-message-queue.h |    2 ++
 libsoup/soup-session.c       |   14 ++++++++++++++
 libsoup/soup-status.c        |    2 ++
 libsoup/soup-status.h        |    1 +
 tests/redirect-test.c        |   13 +++++++++++--
 5 files changed, 30 insertions(+), 2 deletions(-)
---
diff --git a/libsoup/soup-message-queue.h b/libsoup/soup-message-queue.h
index b7bc5d1..d4376a7 100644
--- a/libsoup/soup-message-queue.h
+++ b/libsoup/soup-message-queue.h
@@ -31,6 +31,8 @@ struct SoupMessageQueueItem {
 	SoupURI *proxy_uri;
 	SoupConnection *conn;
 
+	guint redirection_count;
+
 	guint resolving_proxy_addr : 1;
 	guint resolved_proxy_addr  : 1;
 
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 71d1d5f..18c3724 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -117,6 +117,8 @@ static void auth_manager_authenticate (SoupAuthManager *manager,
 #define SOUP_SESSION_MAX_CONNS_DEFAULT 10
 #define SOUP_SESSION_MAX_CONNS_PER_HOST_DEFAULT 2
 
+#define SOUP_SESSION_MAX_REDIRECTION_COUNT 20
+
 #define SOUP_SESSION_USER_AGENT_BASE "libsoup/" PACKAGE_VERSION
 
 G_DEFINE_TYPE (SoupSession, soup_session, G_TYPE_OBJECT)
@@ -1093,6 +1095,8 @@ static void
 redirect_handler (SoupMessage *msg, gpointer user_data)
 {
 	SoupSession *session = user_data;
+	SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
+	SoupMessageQueueItem *item;
 	const char *new_loc;
 	SoupURI *new_uri;
 
@@ -1100,6 +1104,16 @@ redirect_handler (SoupMessage *msg, gpointer user_data)
 						"Location");
 	g_return_if_fail (new_loc != NULL);
 
+	item = soup_message_queue_lookup (priv->queue, msg);
+	g_return_if_fail (item != NULL);
+	if (item->redirection_count >= SOUP_SESSION_MAX_REDIRECTION_COUNT) {
+		soup_session_cancel_message (session, msg, SOUP_STATUS_TOO_MANY_REDIRECTS);
+		soup_message_queue_item_unref (item);
+		return;
+	}
+	item->redirection_count++;
+	soup_message_queue_item_unref (item);
+
 	if (msg->status_code == SOUP_STATUS_SEE_OTHER ||
 	    (msg->status_code == SOUP_STATUS_FOUND &&
 	     !SOUP_METHOD_IS_SAFE (msg->method)) ||
diff --git a/libsoup/soup-status.c b/libsoup/soup-status.c
index 2fa309a..12473f6 100644
--- a/libsoup/soup-status.c
+++ b/libsoup/soup-status.c
@@ -78,6 +78,7 @@
  * closed the connection unexpectedly
  * @SOUP_STATUS_MALFORMED: Malformed data (usually a programmer error)
  * @SOUP_STATUS_TRY_AGAIN: Used internally
+ * @SOUP_STATUS_TOO_MANY_REDIRECTS: There were too many redirections
  * @SOUP_STATUS_CONTINUE: 100 Continue (HTTP)
  * @SOUP_STATUS_SWITCHING_PROTOCOLS: 101 Switching Protocols (HTTP)
  * @SOUP_STATUS_PROCESSING: 102 Processing (WebDAV)
@@ -185,6 +186,7 @@ static const struct {
 #endif
 	{ SOUP_STATUS_IO_ERROR,                   "Connection terminated unexpectedly" },
 	{ SOUP_STATUS_MALFORMED,                  "Message Corrupt" },
+	{ SOUP_STATUS_TOO_MANY_REDIRECTS,         "Too many redirects" },
 
 	/* Informational */
 	{ SOUP_STATUS_CONTINUE,                   "Continue" },
diff --git a/libsoup/soup-status.h b/libsoup/soup-status.h
index 66e9f1c..0d8b74f 100644
--- a/libsoup/soup-status.h
+++ b/libsoup/soup-status.h
@@ -32,6 +32,7 @@ typedef enum {
 	SOUP_STATUS_IO_ERROR,
 	SOUP_STATUS_MALFORMED,
 	SOUP_STATUS_TRY_AGAIN,
+	SOUP_STATUS_TOO_MANY_REDIRECTS,
 
 	/* HTTP Status Codes */
 	SOUP_STATUS_CONTINUE                        = 100,
diff --git a/tests/redirect-test.c b/tests/redirect-test.c
index cd6f1a5..24aefc4 100644
--- a/tests/redirect-test.c
+++ b/tests/redirect-test.c
@@ -18,6 +18,7 @@ typedef struct {
 	const char *method;
 	const char *path;
 	guint status_code;
+	gboolean repeat;
 } TestRequest;
 
 static struct {
@@ -107,7 +108,10 @@ static struct {
 
 	/* Test behavior with irrecoverably-bad Location header */
 	{ { { "GET", "/bad-no-host", 302 },
-	    { NULL } }, SOUP_STATUS_MALFORMED }
+	    { NULL } }, SOUP_STATUS_MALFORMED },
+
+	{ { { "GET", "/bad-recursive", 302, TRUE },
+	    { NULL } }, SOUP_STATUS_TOO_MANY_REDIRECTS }
 };
 static const int n_tests = G_N_ELEMENTS (tests);
 
@@ -142,7 +146,7 @@ restarted (SoupMessage *msg, gpointer user_data)
 
 	debug_printf (2, "    %s %s\n", msg->method, uri->path);
 
-	if ((*req)->method)
+	if ((*req)->method && !(*req)->repeat)
 		(*req)++;
 
 	if (!(*req)->method) {
@@ -234,6 +238,11 @@ server_callback (SoupServer *server, SoupMessage *msg,
 			soup_message_headers_replace (msg->response_headers,
 						      "Location",
 						      "/bad with spaces");
+		} else if (!strcmp (path, "/bad-recursive")) {
+			soup_message_set_status (msg, SOUP_STATUS_FOUND);
+			soup_message_headers_replace (msg->response_headers,
+						      "Location",
+						      "/bad-recursive");
 		} else if (!strcmp (path, "/bad-no-host")) {
 			soup_message_set_status (msg, SOUP_STATUS_FOUND);
 			soup_message_headers_replace (msg->response_headers,



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