SoupURI *proxy_uri;
SoupConnection *conn;
+ guint redirection_count;
+
guint resolving_proxy_addr : 1;
guint resolved_proxy_addr : 1;
#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)
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;
"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)) ||
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);
* 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)
#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" },
SOUP_STATUS_IO_ERROR,
SOUP_STATUS_MALFORMED,
SOUP_STATUS_TRY_AGAIN,
+ SOUP_STATUS_TOO_MANY_REDIRECTS,
/* HTTP Status Codes */
SOUP_STATUS_CONTINUE = 100,
const char *method;
const char *path;
guint status_code;
+ gboolean repeat;
} TestRequest;
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);
debug_printf (2, " %s %s\n", msg->method, uri->path);
- if ((*req)->method)
+ if ((*req)->method && !(*req)->repeat)
(*req)++;
if (!(*req)->method) {
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,