[libsoup/pgriffis/redirection-signal: 2/2] Replace SOUP_MESSAGE_NO_REDIRECT with SoupMessage::redirection




commit 8fc0a9424b7b44c67f2b6a69e744001bd1d18c74
Author: Patrick Griffis <pgriffis igalia com>
Date:   Sun Dec 6 13:20:11 2020 -0600

    Replace SOUP_MESSAGE_NO_REDIRECT with SoupMessage::redirection
    
    This is more flexible and a replacement for users dealing with
    requeuing messages themselves.

 docs/reference/libsoup-3.0-sections.txt |   2 +
 libsoup/soup-message-private.h          |   3 +
 libsoup/soup-message.c                  |  73 +++++++++++++++++-
 libsoup/soup-message.h                  |  14 +++-
 libsoup/soup-session.c                  | 129 ++++++++++++++------------------
 tests/hsts-db-test.c                    |   1 -
 tests/hsts-test.c                       |   8 +-
 tests/misc-test.c                       |  42 +++++------
 tests/redirect-test.c                   |  37 +++++++++
 9 files changed, 209 insertions(+), 100 deletions(-)
---
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt
index 8c711f59..84900d87 100644
--- a/docs/reference/libsoup-3.0-sections.txt
+++ b/docs/reference/libsoup-3.0-sections.txt
@@ -27,6 +27,8 @@ soup_message_is_keepalive
 soup_message_get_tls_certificate
 soup_message_get_tls_certificate_errors
 <SUBSECTION>
+SoupMessageRedirectionFlags
+<SUBSECTION>
 soup_message_set_first_party
 soup_message_get_first_party
 <SUBSECTION>
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index ad1dfba0..dc5a284e 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -106,6 +106,9 @@ void soup_message_finished          (SoupMessage *msg);
 gboolean soup_message_authenticate  (SoupMessage *msg,
                                     SoupAuth    *auth,
                                     gboolean     retrying);
+SoupMessageRedirectionFlags soup_message_redirection (SoupMessage *msg,
+                                                      GUri        *location,
+                                                      guint        redirect_count);
 
 gboolean soup_message_disables_feature (SoupMessage *msg,
                                        gpointer     feature);
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 4ede71c1..198a5134 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -113,6 +113,7 @@ enum {
        AUTHENTICATE,
        NETWORK_EVENT,
        ACCEPT_CERTIFICATE,
+        REDIRECTION,
 
        LAST_SIGNAL
 };
@@ -141,6 +142,11 @@ enum {
        LAST_PROP
 };
 
+static gboolean redirection_accumulator (GSignalInvocationHint *ihint,
+                                         GValue                *return_accu,
+                                         const GValue          *handler_return,
+                                         gpointer               dummy);
+
 static void
 soup_message_init (SoupMessage *msg)
 {
@@ -586,6 +592,31 @@ soup_message_class_init (SoupMessageClass *message_class)
                              G_TYPE_TLS_CERTIFICATE,
                              G_TYPE_TLS_CERTIFICATE_FLAGS);
 
+       /**
+        * SoupMessage::redirection:
+        * @msg: the message
+        * @location: the new redirected location
+         * @redirect_count: count of redirects for @msg
+        *
+         * Emitted after a redirect is returned for logging, blocking, or
+         * explicitly allowing the redirection to happen.
+         *
+         * You can call soup_message_get_uri() to access the pre-redirect
+         * URI.
+         *
+        * Returns: a #SoupMessageRedirectionFlags
+        */
+       signals[REDIRECTION] =
+               g_signal_new ("redirection",
+                             G_OBJECT_CLASS_TYPE (object_class),
+                             G_SIGNAL_RUN_LAST,
+                             0,
+                             redirection_accumulator, NULL,
+                             NULL,
+                             SOUP_TYPE_MESSAGE_REDIRECTION_FLAGS, 2,
+                             G_TYPE_URI,
+                              G_TYPE_UINT);
+
        /* properties */
        g_object_class_install_property (
                object_class, PROP_METHOD,
@@ -1355,8 +1386,6 @@ soup_message_cleanup_response (SoupMessage *msg)
 
 /**
  * SoupMessageFlags:
- * @SOUP_MESSAGE_NO_REDIRECT: The session should not follow redirect
- *   (3xx) responses received by this message.
  * @SOUP_MESSAGE_NEW_CONNECTION: Requests that the message should be
  *   sent on a newly-created connection, not reusing an existing
  *   persistent connection. Note that messages with non-idempotent
@@ -2190,3 +2219,43 @@ soup_message_is_options_ping (SoupMessage *msg)
 
         return priv->options_ping;
 }
+
+/**
+ * SoupMessageRedirectionFlags:
+ * @SOUP_MESSAGE_REDIRECTION_DEFAULT: The session will handled redirects
+ *   as normal. That is allowing them over safe methods.
+ * @SOUP_MESSAGE_REDIRECTION_BLOCK: Override the default behavior preventing
+ *   the redirect.
+ * @SOUP_MESSAGE_REDIRECTION_ALLOW_UNSAFE_METHOD: Override the default behavior
+ *   allowing redirects over unsafe methods such as DELETE.
+ * @SOUP_MESSAGE_REDIRECTION_ALLOW_REDIRECT_COUNT: Override the default behavior
+ *   ignoring the limit of number of redirects.
+ *
+ * Values returned by the #SoupMessage::redirection handler to alter the behavior
+ * of redirects.
+ **/
+
+SoupMessageRedirectionFlags
+soup_message_redirection (SoupMessage *msg, GUri *location, guint redirect_count)
+{
+        SoupMessageRedirectionFlags behavior = SOUP_MESSAGE_REDIRECTION_DEFAULT;
+
+       g_signal_emit (msg, signals[REDIRECTION], 0, location, redirect_count,
+                      &behavior);
+
+       return behavior;
+}
+
+static gboolean
+redirection_accumulator (GSignalInvocationHint *ihint,
+                         GValue                *return_accu,
+                         const GValue          *handler_return,
+                         gpointer               user_data)
+{
+        SoupMessageRedirectionFlags value;
+
+        value = g_value_get_flags (handler_return);
+        g_value_set_flags (return_accu, value);
+
+        return value == SOUP_MESSAGE_REDIRECTION_DEFAULT;
+}
\ No newline at end of file
diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h
index 2cd2603a..a4eb45d7 100644
--- a/libsoup/soup-message.h
+++ b/libsoup/soup-message.h
@@ -74,10 +74,9 @@ SOUP_AVAILABLE_IN_ALL
 gboolean         soup_message_get_is_top_level_navigation (SoupMessage      *msg);
 
 typedef enum {
-       SOUP_MESSAGE_NO_REDIRECT              = (1 << 1),
-       SOUP_MESSAGE_NEW_CONNECTION           = (1 << 2),
-       SOUP_MESSAGE_IDEMPOTENT               = (1 << 3),
-       SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE    = (1 << 4)
+       SOUP_MESSAGE_NEW_CONNECTION           = (1 << 1),
+       SOUP_MESSAGE_IDEMPOTENT               = (1 << 2),
+       SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE    = (1 << 3)
 } SoupMessageFlags;
 
 SOUP_AVAILABLE_IN_ALL
@@ -162,4 +161,11 @@ SoupMessageHeaders *soup_message_get_request_headers  (SoupMessage  *msg);
 SOUP_AVAILABLE_IN_ALL
 SoupMessageHeaders *soup_message_get_response_headers (SoupMessage  *msg);
 
+typedef enum {
+        SOUP_MESSAGE_REDIRECTION_DEFAULT = 0,
+        SOUP_MESSAGE_REDIRECTION_BLOCK = (1 << 1),
+        SOUP_MESSAGE_REDIRECTION_ALLOW_UNSAFE_METHOD = (1 << 2),
+        SOUP_MESSAGE_REDIRECTION_ALLOW_REDIRECT_COUNT = (1 << 3),
+} SoupMessageRedirectionFlags;
+
 G_END_DECLS
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 256bb63f..2ba7ab00 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -156,6 +156,9 @@ soup_session_process_queue_item (SoupSession          *session,
                                 gboolean             *should_cleanup,
                                 gboolean              loop);
 
+static void async_send_request_return_result (SoupMessageQueueItem *item,
+                                             gpointer stream, GError *error);
+
 #define SOUP_SESSION_MAX_CONNS_DEFAULT 10
 #define SOUP_SESSION_MAX_CONNS_PER_HOST_DEFAULT 2
 
@@ -813,11 +816,12 @@ redirection_uri (SoupSession *session,
 static gboolean
 soup_session_requeue_item (SoupSession          *session,
                           SoupMessageQueueItem *item,
+                           gboolean              ignore_count,
                           GError              **error)
 {
        gboolean retval;
 
-       if (item->resend_count >= SOUP_SESSION_MAX_RESEND_COUNT) {
+       if (!ignore_count && item->resend_count >= SOUP_SESSION_MAX_RESEND_COUNT) {
                if (SOUP_STATUS_IS_REDIRECTION (soup_message_get_status (item->msg))) {
                        g_set_error_literal (error,
                                             SOUP_SESSION_ERROR,
@@ -839,48 +843,36 @@ soup_session_requeue_item (SoupSession          *session,
        return retval;
 }
 
-/**
- * soup_session_redirect_message:
- * @session: the session
- * @msg: a #SoupMessage that has received a 3xx response
- * @error: return location for a #GError, or %NULL
- *
- * Updates @msg's URI according to its status code and "Location"
- * header, and requeues it on @session. Use this when you have set
- * %SOUP_MESSAGE_NO_REDIRECT on a message, but have decided to allow a
- * particular redirection to occur, or if you want to allow a
- * redirection that #SoupSession will not perform automatically (eg,
- * redirecting a non-safe method such as DELETE).
- *
- * If @msg's status code indicates that it should be retried as a GET
- * request, then @msg will be modified accordingly.
- *
- * If @msg has already been redirected too many times, this will
- * cause it to fail with %SOUP_STATUS_TOO_MANY_REDIRECTS.
- *
- * Return value: %TRUE if a redirection was applied, %FALSE if not
- * (eg, because there was no Location header, or it could not be
- * parsed).
- *
- * Since: 2.38
- */
-static gboolean
-soup_session_redirect_message (SoupSession *session,
-                              SoupMessage *msg,
-                              GError     **error)
+static void
+redirect_handler (SoupMessage *msg,
+                 gpointer     user_data)
 {
-       SoupSessionPrivate *priv;
-       GUri *new_uri;
-       SoupMessageQueueItem *item;
-       gboolean retval;
+       SoupMessageQueueItem *item = user_data;
+       SoupSession *session = item->session;
+        SoupMessageRedirectionFlags redirection_flags;
 
-       g_return_val_if_fail (SOUP_IS_SESSION (session), FALSE);
-       g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
-       g_return_val_if_fail (!error || *error == NULL, FALSE);
+        if (!SOUP_STATUS_IS_REDIRECTION (soup_message_get_status (msg)))
+                return;
 
-       new_uri = redirection_uri (session, msg, error);
+       GUri *new_uri = redirection_uri (session, msg, &item->error);
        if (!new_uri)
-               return FALSE;
+               return;
+
+        redirection_flags = soup_message_redirection (msg, new_uri, item->resend_count + 1);
+
+        if (redirection_flags & SOUP_MESSAGE_REDIRECTION_BLOCK) {
+                item->state = SOUP_MESSAGE_FINISHING;
+                soup_session_kick_queue (session);
+                g_uri_unref (new_uri);
+                return;
+        }
+
+        if (!(redirection_flags & SOUP_MESSAGE_REDIRECTION_ALLOW_UNSAFE_METHOD) &&
+            !SOUP_SESSION_WOULD_REDIRECT_AS_GET (session, msg) &&
+           !SOUP_SESSION_WOULD_REDIRECT_AS_SAFE (session, msg)) {
+                g_uri_unref (new_uri);
+               return;
+        }
 
        if (SOUP_SESSION_WOULD_REDIRECT_AS_GET (session, msg)) {
                if (soup_message_get_method (msg) != SOUP_METHOD_HEAD) {
@@ -896,26 +888,9 @@ soup_session_redirect_message (SoupSession *session,
        soup_message_set_uri (msg, new_uri);
        g_uri_unref (new_uri);
 
-       priv = soup_session_get_instance_private (session);
-       item = soup_message_queue_lookup (priv->queue, msg);
-       retval = soup_session_requeue_item (session, item, error);
-       soup_message_queue_item_unref (item);
-
-       return retval;
-}
-
-static void
-redirect_handler (SoupMessage *msg,
-                 gpointer     user_data)
-{
-       SoupMessageQueueItem *item = user_data;
-       SoupSession *session = item->session;
-
-       if (!SOUP_SESSION_WOULD_REDIRECT_AS_GET (session, msg) &&
-           !SOUP_SESSION_WOULD_REDIRECT_AS_SAFE (session, msg))
-               return;
-
-       soup_session_redirect_message (session, msg, &item->error);
+       soup_session_requeue_item (session, item,
+                                   redirection_flags & SOUP_MESSAGE_REDIRECTION_ALLOW_REDIRECT_COUNT,
+                                   &item->error);
 }
 
 static void
@@ -967,11 +942,10 @@ soup_session_append_queue_item (SoupSession        *session,
        host->num_messages++;
        g_mutex_unlock (&priv->conn_lock);
 
-       if (!soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT)) {
-               soup_message_add_header_handler (
-                       msg, "got_body", "Location",
-                       G_CALLBACK (redirect_handler), item);
-       }
+        soup_message_add_header_handler (
+                msg, "got_body", "Location",
+                G_CALLBACK (redirect_handler), item);
+
        g_signal_connect (msg, "restarted",
                          G_CALLBACK (message_restarted), item);
 
@@ -1308,7 +1282,6 @@ tunnel_connect (SoupMessageQueueItem *item)
 
        uri = soup_connection_get_remote_uri (item->conn);
        msg = soup_message_new_from_uri (SOUP_METHOD_CONNECT, uri);
-       soup_message_add_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
 
        tunnel_item = soup_session_append_queue_item (session, msg,
                                                      item->async,
@@ -1678,7 +1651,7 @@ soup_session_requeue_message (SoupSession *session,
        SoupMessageQueueItem *item;
 
        item = soup_message_queue_lookup (priv->queue, msg);
-       soup_session_requeue_item (session, item, &item->error);
+       soup_session_requeue_item (session, item, FALSE, &item->error);
        soup_message_queue_item_unref (item);
 }
 
@@ -2516,6 +2489,20 @@ soup_session_class_init (SoupSessionClass *session_class)
                                     G_PARAM_STATIC_STRINGS));
 }
 
+static gboolean
+is_tunnel_message (SoupSession *session, SoupMessage *msg)
+{
+       SoupSessionPrivate *priv = soup_session_get_instance_private (session);
+        SoupMessageQueueItem *item = soup_message_queue_lookup (priv->queue, msg);
+        gboolean ret;
+
+        g_assert (item);
+        ret = item->related != NULL;
+
+        soup_message_queue_item_unref (item);
+        return ret;
+}
+
 
 static gboolean
 expected_to_be_requeued (SoupSession *session, SoupMessage *msg)
@@ -2527,12 +2514,12 @@ expected_to_be_requeued (SoupSession *session, SoupMessage *msg)
                return !feature || !soup_message_disables_feature (msg, feature);
        }
 
-       if (!soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT)) {
-               return SOUP_SESSION_WOULD_REDIRECT_AS_GET (session, msg) ||
-                       SOUP_SESSION_WOULD_REDIRECT_AS_SAFE (session, msg);
-       }
+        /* Tunnel messages are never redirected */
+        if (is_tunnel_message (session, msg))
+                return FALSE;
 
-       return FALSE;
+        return SOUP_SESSION_WOULD_REDIRECT_AS_GET (session, msg) ||
+                SOUP_SESSION_WOULD_REDIRECT_AS_SAFE (session, msg);
 }
 
 /* send_request_async */
diff --git a/tests/hsts-db-test.c b/tests/hsts-db-test.c
index 54b3bcb8..1109a9ab 100644
--- a/tests/hsts-db-test.c
+++ b/tests/hsts-db-test.c
@@ -67,7 +67,6 @@ session_get_uri (SoupSession *session, const char *uri, SoupStatus expected_stat
         GError *error = NULL;
 
        msg = soup_message_new ("GET", uri);
-       soup_message_add_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
        body = soup_test_session_send (session, msg, NULL, &error);
        if (expected_status == SOUP_STATUS_NONE)
                g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
diff --git a/tests/hsts-test.c b/tests/hsts-test.c
index a0276c77..d7e766bc 100644
--- a/tests/hsts-test.c
+++ b/tests/hsts-test.c
@@ -105,6 +105,12 @@ server_callback  (SoupServer        *server,
        }
 }
 
+static SoupMessageRedirectionFlags
+redirection_callback (SoupMessage *msg, GUri *location, guint redirect_count, gpointer user_data)
+{
+        return SOUP_MESSAGE_REDIRECTION_BLOCK;
+}
+
 static void
 session_get_uri (SoupSession *session, const char *uri, SoupStatus expected_status)
 {
@@ -113,7 +119,7 @@ session_get_uri (SoupSession *session, const char *uri, SoupStatus expected_stat
        GError *error = NULL;
 
        msg = soup_message_new ("GET", uri);
-       soup_message_add_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
+        g_signal_connect (msg, "redirection", G_CALLBACK (redirection_callback), NULL);
        body = soup_test_session_send (session, msg, NULL, &error);
        if (expected_status == SOUP_STATUS_NONE)
                g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
diff --git a/tests/misc-test.c b/tests/misc-test.c
index 80ee111e..a5085f5a 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -654,50 +654,50 @@ do_msg_flags_test (void)
 
        /* Flags are initially empty */
        g_assert_cmpuint (soup_message_get_flags (msg), ==, 0);
-       g_assert_false (soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT));
+       g_assert_false (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION));
 
        /* Set a single flag */
-       soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
-       g_assert_cmpuint (soup_message_get_flags (msg), ==, SOUP_MESSAGE_NO_REDIRECT);
-       g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT));
-       g_assert_false (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION));
+       soup_message_set_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
+       g_assert_cmpuint (soup_message_get_flags (msg), ==, SOUP_MESSAGE_NEW_CONNECTION);
+       g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION));
+       g_assert_false (soup_message_query_flags (msg, SOUP_MESSAGE_IDEMPOTENT));
 
        /* Add another flag */
-       soup_message_add_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
-       g_assert_cmpuint (soup_message_get_flags (msg), ==, (SOUP_MESSAGE_NO_REDIRECT | 
SOUP_MESSAGE_NEW_CONNECTION));
-       g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT | 
SOUP_MESSAGE_NEW_CONNECTION));
+       soup_message_add_flags (msg, SOUP_MESSAGE_IDEMPOTENT);
+       g_assert_cmpuint (soup_message_get_flags (msg), ==, (SOUP_MESSAGE_IDEMPOTENT | 
SOUP_MESSAGE_NEW_CONNECTION));
+       g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_IDEMPOTENT | SOUP_MESSAGE_NEW_CONNECTION));
 
        /* Add an existing flag */
-       soup_message_add_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
-       g_assert_cmpuint (soup_message_get_flags (msg), ==, (SOUP_MESSAGE_NO_REDIRECT | 
SOUP_MESSAGE_NEW_CONNECTION));
-        g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT | 
SOUP_MESSAGE_NEW_CONNECTION));
+       soup_message_add_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
+       g_assert_cmpuint (soup_message_get_flags (msg), ==, (SOUP_MESSAGE_IDEMPOTENT | 
SOUP_MESSAGE_NEW_CONNECTION));
+        g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_IDEMPOTENT | 
SOUP_MESSAGE_NEW_CONNECTION));
 
        /* Remove a single flag */
        soup_message_remove_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
-       g_assert_cmpuint (soup_message_get_flags (msg), ==, SOUP_MESSAGE_NO_REDIRECT);
-        g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT));
+       g_assert_cmpuint (soup_message_get_flags (msg), ==, SOUP_MESSAGE_IDEMPOTENT);
+        g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_IDEMPOTENT));
         g_assert_false (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION));
 
        /* Remove a non-existing flag */
        soup_message_remove_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
-       g_assert_cmpuint (soup_message_get_flags (msg), ==, SOUP_MESSAGE_NO_REDIRECT);
-        g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT));
+       g_assert_cmpuint (soup_message_get_flags (msg), ==, SOUP_MESSAGE_IDEMPOTENT);
+        g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_IDEMPOTENT));
         g_assert_false (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION));
 
        /* Add a set of flags */
        soup_message_add_flags (msg, SOUP_MESSAGE_NEW_CONNECTION | SOUP_MESSAGE_IDEMPOTENT | 
SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
-       g_assert_cmpuint (soup_message_get_flags (msg), ==, (SOUP_MESSAGE_NO_REDIRECT | 
SOUP_MESSAGE_NEW_CONNECTION | SOUP_MESSAGE_IDEMPOTENT | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE));
-       g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT | SOUP_MESSAGE_NEW_CONNECTION 
| SOUP_MESSAGE_IDEMPOTENT | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE));
+       g_assert_cmpuint (soup_message_get_flags (msg), ==, (SOUP_MESSAGE_NEW_CONNECTION | 
SOUP_MESSAGE_IDEMPOTENT | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE));
+       g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION | SOUP_MESSAGE_IDEMPOTENT | 
SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE));
 
        /* Remove a set of flags */
-       soup_message_remove_flags (msg, (SOUP_MESSAGE_NO_REDIRECT | SOUP_MESSAGE_IDEMPOTENT));
-       g_assert_cmpuint (soup_message_get_flags (msg), ==, (SOUP_MESSAGE_NEW_CONNECTION | 
SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE));
-       g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION | 
SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE));
+       soup_message_remove_flags (msg, (SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE | SOUP_MESSAGE_IDEMPOTENT));
+       g_assert_cmpuint (soup_message_get_flags (msg), ==, SOUP_MESSAGE_NEW_CONNECTION);
+       g_assert_true (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION));
 
        /* Remove all flags */
        soup_message_set_flags (msg, 0);
        g_assert_cmpuint (soup_message_get_flags (msg), ==, 0);
-        g_assert_false (soup_message_query_flags (msg, SOUP_MESSAGE_NO_REDIRECT | 
SOUP_MESSAGE_NEW_CONNECTION | SOUP_MESSAGE_IDEMPOTENT | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE));
+        g_assert_false (soup_message_query_flags (msg, SOUP_MESSAGE_NEW_CONNECTION | SOUP_MESSAGE_IDEMPOTENT 
| SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE));
 
        g_object_unref (msg);
 }
diff --git a/tests/redirect-test.c b/tests/redirect-test.c
index a7e15cd9..90649d31 100644
--- a/tests/redirect-test.c
+++ b/tests/redirect-test.c
@@ -323,6 +323,41 @@ server2_callback (SoupServer        *server,
        soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
 }
 
+static SoupMessageRedirectionFlags
+redirection_callback (SoupMessage *msg, GUri *location, guint redirect_count, gpointer user_data)
+{
+        GUri *old_uri = soup_message_get_uri (msg);
+        gboolean *handled = user_data;
+
+        g_assert_cmpuint (redirect_count, ==, 1);
+        g_assert_false (soup_uri_equal (old_uri, location));
+
+        *handled = TRUE;
+        return SOUP_MESSAGE_REDIRECTION_BLOCK;
+}
+
+static void
+do_msg_redirection_signal_test (void)
+{
+               GUri *uri = g_uri_parse_relative (base_uri, "301", SOUP_HTTP_URI_FLAGS, NULL);
+        SoupMessage *msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
+        gboolean handled = FALSE;
+        GError *error = NULL;
+
+        g_signal_connect (msg, "redirection", G_CALLBACK (redirection_callback), &handled);
+
+       GBytes *body = soup_test_session_async_send (async_session, msg, NULL, &error);
+
+        g_assert_no_error (error);
+        g_assert_true (handled);
+        soup_test_assert_message_status (msg, 301);
+        g_assert_true (soup_uri_equal (uri, soup_message_get_uri (msg)));
+
+        g_uri_unref (uri);
+        g_bytes_unref (body);
+        g_object_unref (msg);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -360,6 +395,8 @@ main (int argc, char **argv)
                g_free (path);
        }
 
+        g_test_add_func ("/redirect/msg/redirection-signal", do_msg_redirection_signal_test);
+
        ret = g_test_run ();
 
        g_main_loop_unref (loop);


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