diff options
| author | Patrick Griffis <pgriffis@igalia.com> | 2020-12-06 13:20:11 -0600 |
|---|---|---|
| committer | Patrick Griffis <pgriffis@igalia.com> | 2020-12-06 13:37:23 -0600 |
| commit | 8fc0a9424b7b44c67f2b6a69e744001bd1d18c74 (patch) | |
| tree | 2e0f271e170f3b8a96a144819ea51fa36fbfd9f7 | |
| parent | 8eea041cc8298a1336df968568267bac3feb2b23 (diff) | |
| download | libsoup-8fc0a9424b7b44c67f2b6a69e744001bd1d18c74.tar.gz | |
Replace SOUP_MESSAGE_NO_REDIRECT with SoupMessage::redirection
This is more flexible and a replacement for users dealing with
requeuing messages themselves.
| -rw-r--r-- | docs/reference/libsoup-3.0-sections.txt | 2 | ||||
| -rw-r--r-- | libsoup/soup-message-private.h | 3 | ||||
| -rw-r--r-- | libsoup/soup-message.c | 73 | ||||
| -rw-r--r-- | libsoup/soup-message.h | 14 | ||||
| -rw-r--r-- | libsoup/soup-session.c | 129 | ||||
| -rw-r--r-- | tests/hsts-db-test.c | 1 | ||||
| -rw-r--r-- | tests/hsts-test.c | 8 | ||||
| -rw-r--r-- | tests/misc-test.c | 42 | ||||
| -rw-r--r-- | 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); |
