summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Millán Soto <jmillan@igalia.com>2010-06-04 13:46:31 +0200
committerDan Winship <danw@gnome.org>2010-06-08 11:19:46 -0400
commit34ae2a292b69321078c5e7d922a39f75e8538d3a (patch)
tree074516d8ed1de48a9768a2f48b1a1a14ad0aceef
parentb5b76659341f08cffa9a592bb703fb81fa793dd2 (diff)
downloadlibsoup-34ae2a292b69321078c5e7d922a39f75e8538d3a.tar.gz
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
-rw-r--r--libsoup/soup-message-queue.h2
-rw-r--r--libsoup/soup-session.c13
-rw-r--r--libsoup/soup-status.c2
-rw-r--r--libsoup/soup-status.h1
-rw-r--r--tests/redirect-test.c13
5 files changed, 27 insertions, 4 deletions
diff --git a/libsoup/soup-message-queue.h b/libsoup/soup-message-queue.h
index b7bc5d12..d4376a7e 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 5143a487..1d5e6f5d 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_ABSTRACT_TYPE (SoupSession, soup_session, G_TYPE_OBJECT)
@@ -1092,7 +1094,8 @@ auth_manager_authenticate (SoupAuthManager *manager, SoupMessage *msg,
static void
redirect_handler (SoupMessage *msg, gpointer user_data)
{
- SoupSession *session = user_data;
+ SoupMessageQueueItem *item = user_data;
+ SoupSession *session = item->session;
const char *new_loc;
SoupURI *new_uri;
@@ -1100,6 +1103,12 @@ redirect_handler (SoupMessage *msg, gpointer user_data)
"Location");
g_return_if_fail (new_loc != NULL);
+ if (item->redirection_count >= SOUP_SESSION_MAX_REDIRECTION_COUNT) {
+ soup_session_cancel_message (session, msg, SOUP_STATUS_TOO_MANY_REDIRECTS);
+ return;
+ }
+ item->redirection_count++;
+
if (msg->status_code == SOUP_STATUS_SEE_OTHER ||
(msg->status_code == SOUP_STATUS_FOUND &&
!SOUP_METHOD_IS_SAFE (msg->method)) ||
@@ -1555,7 +1564,7 @@ queue_message (SoupSession *session, SoupMessage *msg,
if (!(soup_message_get_flags (msg) & SOUP_MESSAGE_NO_REDIRECT)) {
soup_message_add_header_handler (
msg, "got_body", "Location",
- G_CALLBACK (redirect_handler), session);
+ G_CALLBACK (redirect_handler), item);
}
g_signal_emit (session, signals[REQUEST_QUEUED], 0, msg);
diff --git a/libsoup/soup-status.c b/libsoup/soup-status.c
index 2fa309af..12473f61 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 66e9f1c7..0d8b74fb 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 cd6f1a5d..24aefc4c 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,