diff options
author | José Millán Soto <jmillan@igalia.com> | 2010-06-04 13:46:31 +0200 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2010-06-08 11:19:46 -0400 |
commit | 34ae2a292b69321078c5e7d922a39f75e8538d3a (patch) | |
tree | 074516d8ed1de48a9768a2f48b1a1a14ad0aceef | |
parent | b5b76659341f08cffa9a592bb703fb81fa793dd2 (diff) | |
download | libsoup-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.h | 2 | ||||
-rw-r--r-- | libsoup/soup-session.c | 13 | ||||
-rw-r--r-- | libsoup/soup-status.c | 2 | ||||
-rw-r--r-- | libsoup/soup-status.h | 1 | ||||
-rw-r--r-- | tests/redirect-test.c | 13 |
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, |