diff options
| author | Carlos Garcia Campos <cgarcia@igalia.com> | 2020-11-12 15:34:02 +0100 |
|---|---|---|
| committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2020-11-15 15:06:01 +0100 |
| commit | b4b865d8d62f4207059c187c345dca4d0349a77e (patch) | |
| tree | d8c2202a347f54418ab55513e2d9763cd1f5ccfc | |
| parent | 365056ee1e2cb7c3a17b44f91156e4808a477a6e (diff) | |
| download | libsoup-b4b865d8d62f4207059c187c345dca4d0349a77e.tar.gz | |
Remove non-HTTP SoupStatus values
Stop using the message status for internal or transport errors and
always use GError for those.
30 files changed, 364 insertions, 514 deletions
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt index f66f50fc..5c8f1d6a 100644 --- a/docs/reference/libsoup-3.0-sections.txt +++ b/docs/reference/libsoup-3.0-sections.txt @@ -201,7 +201,6 @@ soup_message_body_get_type <SECTION> <FILE>soup-status</FILE> <TITLE>SoupStatus</TITLE> -SOUP_STATUS_IS_TRANSPORT_ERROR SOUP_STATUS_IS_INFORMATIONAL SOUP_STATUS_IS_SUCCESSFUL SOUP_STATUS_IS_REDIRECTION @@ -209,11 +208,6 @@ SOUP_STATUS_IS_CLIENT_ERROR SOUP_STATUS_IS_SERVER_ERROR SoupStatus soup_status_get_phrase -soup_status_proxify -<SUBSECTION> -SOUP_HTTP_ERROR -<SUBSECTION Private> -soup_http_error_quark </SECTION> <SECTION> diff --git a/libsoup/auth/soup-auth-negotiate.c b/libsoup/auth/soup-auth-negotiate.c index 41215690..7b05f9bb 100644 --- a/libsoup/auth/soup-auth-negotiate.c +++ b/libsoup/auth/soup-auth-negotiate.c @@ -95,12 +95,12 @@ G_DEFINE_TYPE_WITH_PRIVATE (SoupAuthNegotiate, soup_auth_negotiate, SOUP_TYPE_CO static gboolean check_auth_trusted_uri (SoupConnectionAuth *auth, SoupMessage *msg); static gboolean soup_gss_build_response (SoupNegotiateConnectionState *conn, - SoupAuth *auth, GError **err); + SoupAuth *auth, char **error_message); static void soup_gss_client_cleanup (SoupNegotiateConnectionState *conn); static gboolean soup_gss_client_init (SoupNegotiateConnectionState *conn, - const char *authority, GError **err); + const char *authority, char **error_message); static int soup_gss_client_step (SoupNegotiateConnectionState *conn, - const char *host, GError **err); + const char *host, char **error_message); static GSList *trusted_uris; static GSList *blacklisted_uris; @@ -194,23 +194,23 @@ soup_auth_negotiate_get_connection_authorization (SoupConnectionAuth *auth, char *header = NULL; if (conn->state == SOUP_NEGOTIATE_NEW) { - GError *err = NULL; + char *error_message = NULL; if (!check_auth_trusted_uri (auth, msg)) { conn->state = SOUP_NEGOTIATE_FAILED; return NULL; } - if (!soup_gss_build_response (conn, SOUP_AUTH (auth), &err)) { - g_assert (err); /* Silence scan-build */ + if (!soup_gss_build_response (conn, SOUP_AUTH (auth), &error_message)) { + g_assert (error_message); /* Silence scan-build */ /* FIXME: report further upward via * soup_message_get_error_message */ if (conn->initialized) - g_warning ("gssapi step failed: %s", err->message); + g_warning ("gssapi step failed: %s", error_message); else - g_warning ("gssapi init failed: %s", err->message); + g_warning ("gssapi init failed: %s", error_message); conn->state = SOUP_NEGOTIATE_FAILED; - g_clear_error (&err); + g_clear_pointer (&error_message, g_free); return NULL; } @@ -243,7 +243,7 @@ soup_auth_negotiate_update_connection (SoupConnectionAuth *auth, SoupMessage *ms #ifdef LIBSOUP_HAVE_GSSAPI gboolean success = TRUE; SoupNegotiateConnectionState *conn = state; - GError *err = NULL; + char *error_message = NULL; if (!check_auth_trusted_uri (auth, msg)) { conn->state = SOUP_NEGOTIATE_FAILED; @@ -260,7 +260,7 @@ soup_auth_negotiate_update_connection (SoupConnectionAuth *auth, SoupMessage *ms } conn->state = SOUP_NEGOTIATE_RECEIVED_CHALLENGE; - if (soup_gss_build_response (conn, SOUP_AUTH (auth), &err)) { + if (soup_gss_build_response (conn, SOUP_AUTH (auth), &error_message)) { /* Connect the signal only once per message */ if (!g_object_get_data (G_OBJECT (msg), "negotiate-got-headers-connected")) { /* Wait for the 2xx response to verify server response */ @@ -277,17 +277,17 @@ soup_auth_negotiate_update_connection (SoupConnectionAuth *auth, SoupMessage *ms } goto out; } else { - g_assert (err); /* Silence scan-build */ + g_assert (error_message); /* Silence scan-build */ /* FIXME: report further upward via * soup_message_get_error_message */ if (conn->initialized) - g_warning ("gssapi step failed: %s", err->message); + g_warning ("gssapi step failed: %s", error_message); else - g_warning ("gssapi init failed: %s", err->message); + g_warning ("gssapi init failed: %s", error_message); success = FALSE; } } else if (!strncmp (header, "Negotiate ", 10)) { - if (soup_gss_client_step (conn, header + 10, &err) == AUTH_GSS_CONTINUE) { + if (soup_gss_client_step (conn, header + 10, &error_message) == AUTH_GSS_CONTINUE) { conn->state = SOUP_NEGOTIATE_RECEIVED_CHALLENGE; goto out; } @@ -295,7 +295,7 @@ soup_auth_negotiate_update_connection (SoupConnectionAuth *auth, SoupMessage *ms conn->state = SOUP_NEGOTIATE_FAILED; out: - g_clear_error (&err); + g_clear_pointer (&error_message, g_free); return success; #else return FALSE; @@ -343,7 +343,7 @@ check_server_response (SoupMessage *msg, gpointer auth) { gint ret; const char *auth_headers; - GError *err = NULL; + char *error_message = NULL; SoupAuthNegotiate *negotiate = auth; SoupAuthNegotiatePrivate *priv = soup_auth_negotiate_get_instance_private (negotiate); SoupNegotiateConnectionState *conn; @@ -367,7 +367,7 @@ check_server_response (SoupMessage *msg, gpointer auth) goto out; } - ret = soup_gss_client_step (conn, auth_headers + 10, &err); + ret = soup_gss_client_step (conn, auth_headers + 10, &error_message); switch (ret) { case AUTH_GSS_COMPLETE: @@ -377,8 +377,9 @@ check_server_response (SoupMessage *msg, gpointer auth) conn->state = SOUP_NEGOTIATE_RECEIVED_CHALLENGE; break; case AUTH_GSS_ERROR: - if (err) - g_warning ("%s", err->message); + if (error_message) + g_warning ("%s", error_message); + /* Unfortunately, so many programs (curl, Firefox, ..) ignore * the return token that is included in the response, so it is * possible that there are servers that send back broken stuff. @@ -394,7 +395,7 @@ check_server_response (SoupMessage *msg, gpointer auth) conn->state = SOUP_NEGOTIATE_FAILED; } out: - g_clear_error (&err); + g_clear_pointer (&error_message, g_free); } /* Check if scheme://host:port from message matches the given URI. */ @@ -471,20 +472,20 @@ check_auth_trusted_uri (SoupConnectionAuth *auth, SoupMessage *msg) } static gboolean -soup_gss_build_response (SoupNegotiateConnectionState *conn, SoupAuth *auth, GError **err) +soup_gss_build_response (SoupNegotiateConnectionState *conn, SoupAuth *auth, char **error_message) { if (!conn->initialized) - if (!soup_gss_client_init (conn, soup_auth_get_authority (auth), err)) + if (!soup_gss_client_init (conn, soup_auth_get_authority (auth), error_message)) return FALSE; - if (soup_gss_client_step (conn, "", err) != AUTH_GSS_CONTINUE) + if (soup_gss_client_step (conn, "", error_message) != AUTH_GSS_CONTINUE) return FALSE; return TRUE; } static void -soup_gss_error (OM_uint32 err_maj, OM_uint32 err_min, GError **err) +soup_gss_error (OM_uint32 err_maj, OM_uint32 err_min, char **error_message) { OM_uint32 maj_stat, min_stat, msg_ctx = 0; gss_buffer_desc status; @@ -514,14 +515,11 @@ soup_gss_error (OM_uint32 err_maj, OM_uint32 err_min, GError **err) gss_release_buffer (&min_stat, &status); } - if (err && *err == NULL) { - g_set_error (err, - SOUP_HTTP_ERROR, - SOUP_STATUS_UNAUTHORIZED, - "%s: %s", - buf_maj, - buf_min ? buf_min : ""); + if (error_message && *error_message == NULL) { + *error_message = g_strdup_printf ("%s: %s", buf_maj, + buf_min ? buf_min : ""); } + g_free (buf_maj); g_free (buf_min); buf_min = buf_maj = NULL; @@ -529,7 +527,7 @@ soup_gss_error (OM_uint32 err_maj, OM_uint32 err_min, GError **err) } static gboolean -soup_gss_client_init (SoupNegotiateConnectionState *conn, const gchar *authority, GError **err) +soup_gss_client_init (SoupNegotiateConnectionState *conn, const gchar *authority, char **error_message) { OM_uint32 maj_stat, min_stat; gchar *service = NULL; @@ -553,7 +551,7 @@ soup_gss_client_init (SoupNegotiateConnectionState *conn, const gchar *authority &conn->server_name); if (GSS_ERROR (maj_stat)) { - soup_gss_error (maj_stat, min_stat, err); + soup_gss_error (maj_stat, min_stat, error_message); ret = FALSE; goto out; } @@ -567,7 +565,7 @@ out: } static gint -soup_gss_client_step (SoupNegotiateConnectionState *conn, const gchar *challenge, GError **err) +soup_gss_client_step (SoupNegotiateConnectionState *conn, const gchar *challenge, char **error_message) { OM_uint32 maj_stat, min_stat; gss_buffer_desc in = GSS_C_EMPTY_BUFFER; @@ -597,7 +595,7 @@ soup_gss_client_step (SoupNegotiateConnectionState *conn, const gchar *challenge NULL); if ((maj_stat != GSS_S_COMPLETE) && (maj_stat != GSS_S_CONTINUE_NEEDED)) { - soup_gss_error (maj_stat, min_stat, err); + soup_gss_error (maj_stat, min_stat, error_message); ret = AUTH_GSS_ERROR; goto out; } diff --git a/libsoup/cache/soup-cache.c b/libsoup/cache/soup-cache.c index cd0ab5de..68ba5f26 100644 --- a/libsoup/cache/soup-cache.c +++ b/libsoup/cache/soup-cache.c @@ -1425,7 +1425,7 @@ soup_cache_cancel_conditional_request (SoupCache *cache, if (entry) entry->being_validated = FALSE; - soup_session_cancel_message (priv->session, msg, SOUP_STATUS_CANCELLED); + soup_session_cancel_message (priv->session, msg, SOUP_STATUS_NONE); } void diff --git a/libsoup/hsts/soup-hsts-enforcer.c b/libsoup/hsts/soup-hsts-enforcer.c index 8925f5ac..1889e98e 100644 --- a/libsoup/hsts/soup-hsts-enforcer.c +++ b/libsoup/hsts/soup-hsts-enforcer.c @@ -534,7 +534,7 @@ on_sts_known_host_message_starting (SoupMessage *msg, SoupHSTSEnforcer *hsts_enf errors = soup_message_get_tls_certificate_errors (msg); if (errors) - soup_session_cancel_message (priv->session, msg, SOUP_STATUS_CANCELLED); + soup_session_cancel_message (priv->session, msg, SOUP_STATUS_NONE); } static void diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c index ed467e9f..aaf7829f 100644 --- a/libsoup/server/soup-server-io.c +++ b/libsoup/server/soup-server-io.c @@ -659,7 +659,7 @@ io_read (SoupServerMessage *msg, case SOUP_MESSAGE_IO_STATE_HEADERS: if (!soup_message_io_data_read_headers (io, FALSE, NULL, error)) { if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT)) - soup_server_message_set_status (msg, SOUP_STATUS_MALFORMED, NULL); + soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL); return FALSE; } @@ -851,9 +851,7 @@ io_run (SoupServerMessage *msg) NULL); g_source_attach (io->io_source, io->async_context); } else if (soup_server_message_get_io_data (msg) == server_io) { - if (!SOUP_STATUS_IS_TRANSPORT_ERROR (soup_server_message_get_status (msg, NULL))) - soup_server_message_set_status (msg, SOUP_STATUS_IO_ERROR, error ? error->message : NULL); - + soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, error ? error->message : NULL); soup_server_message_io_finished (msg); } g_object_unref (msg); diff --git a/libsoup/server/soup-server.c b/libsoup/server/soup-server.c index c49127e1..58bbd9c9 100644 --- a/libsoup/server/soup-server.c +++ b/libsoup/server/soup-server.c @@ -966,10 +966,8 @@ client_disconnected (SoupServer *server, priv->clients = g_slist_remove (priv->clients, msg); - if (soup_server_message_get_status (msg, NULL) != 0) { - soup_server_message_set_status (msg, SOUP_STATUS_IO_ERROR, NULL); + if (soup_server_message_get_status (msg, NULL) != 0) soup_server_message_io_finished (msg); - } } static void @@ -1006,7 +1004,7 @@ request_finished (SoupServerMessage *msg, soup_server_message_finished (msg); failed = (completion == SOUP_MESSAGE_IO_INTERRUPTED || - soup_server_message_get_status (msg, NULL) == SOUP_STATUS_IO_ERROR); + soup_server_message_get_status (msg, NULL) == SOUP_STATUS_INTERNAL_SERVER_ERROR); g_signal_emit (server, failed ? signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED], 0, msg); diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c index 5bee9dc1..c247a9b6 100644 --- a/libsoup/soup-message-io.c +++ b/libsoup/soup-message-io.c @@ -460,7 +460,7 @@ io_write (SoupMessage *msg, gboolean blocking, return TRUE; } -static guint +static gboolean parse_headers (SoupMessage *msg, char *headers, guint headers_len, @@ -481,7 +481,7 @@ parse_headers (SoupMessage *msg, g_set_error_literal (error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_PARSING, _("Could not parse HTTP response")); - return SOUP_STATUS_MALFORMED; + return FALSE; } soup_message_set_status_full (msg, status, reason_phrase); @@ -504,10 +504,10 @@ parse_headers (SoupMessage *msg, g_set_error_literal (error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_ENCODING, _("Unrecognized HTTP response encoding")); - return SOUP_STATUS_MALFORMED; + return FALSE; } - return SOUP_STATUS_OK; + return TRUE; } /* Attempts to push forward the reading side of @msg's I/O. Returns @@ -522,24 +522,21 @@ io_read (SoupMessage *msg, gboolean blocking, { SoupClientMessageIOData *client_io = soup_message_get_io_data (msg); SoupMessageIOData *io = &client_io->base; - guint status; + gboolean succeeded; switch (io->read_state) { case SOUP_MESSAGE_IO_STATE_HEADERS: - if (!soup_message_io_data_read_headers (io, blocking, cancellable, error)) { - if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT)) - soup_message_set_status (msg, SOUP_STATUS_MALFORMED); + if (!soup_message_io_data_read_headers (io, blocking, cancellable, error)) return FALSE; - } - status = parse_headers (msg, - (char *)io->read_header_buf->data, - io->read_header_buf->len, - &io->read_encoding, - error); + succeeded = parse_headers (msg, + (char *)io->read_header_buf->data, + io->read_header_buf->len, + &io->read_encoding, + error); g_byte_array_set_size (io->read_header_buf, 0); - if (status != SOUP_STATUS_OK) { + if (!succeeded) { /* Either we couldn't parse the headers, or they * indicated something that would mean we wouldn't * be able to parse the body. (Eg, unknown @@ -547,7 +544,6 @@ io_read (SoupMessage *msg, gboolean blocking, * reading, and make sure the connection gets * closed when we're done. */ - soup_message_set_status (msg, status); soup_message_headers_append (soup_message_get_request_headers (msg), "Connection", "close"); io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING; @@ -684,6 +680,7 @@ request_is_restartable (SoupMessage *msg, GError *error) soup_connection_get_ever_used (client_io->item->conn) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) && + !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && error->domain != G_TLS_ERROR && SOUP_METHOD_IS_IDEMPOTENT (soup_message_get_method (msg))); } @@ -721,15 +718,6 @@ io_run_until (SoupMessage *msg, gboolean blocking, } if (my_error) { - if (request_is_restartable (msg, my_error)) { - /* Connection got closed, but we can safely try again */ - g_error_free (my_error); - g_set_error_literal (error, SOUP_HTTP_ERROR, - SOUP_STATUS_TRY_AGAIN, ""); - g_object_unref (msg); - return FALSE; - } - g_propagate_error (error, my_error); g_object_unref (msg); return FALSE; @@ -788,20 +776,14 @@ io_run_until (SoupMessage *msg, gboolean blocking, } static void -soup_message_io_update_status (SoupMessage *msg, - GError *error) +soup_message_io_finish (SoupMessage *msg, + GError *error) { - if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN)) { + if (request_is_restartable (msg, error)) { SoupClientMessageIOData *io = soup_message_get_io_data (msg); + /* Connection got closed, but we can safely try again. */ io->item->state = SOUP_MESSAGE_RESTARTING; - } else if (error->domain == G_TLS_ERROR) { - soup_message_set_status_full (msg, - SOUP_STATUS_SSL_FAILED, - error->message); - } else if (!SOUP_STATUS_IS_TRANSPORT_ERROR (soup_message_get_status (msg)) && - !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - soup_message_set_status (msg, SOUP_STATUS_IO_ERROR); } soup_message_io_finished (msg); @@ -847,7 +829,7 @@ soup_message_io_run (SoupMessage *msg, g_source_attach (io->io_source, io->async_context); } else { if (soup_message_get_io_data (msg) == client_io) - soup_message_io_update_status (msg, error); + soup_message_io_finish (msg, error); g_error_free (error); } @@ -870,7 +852,7 @@ soup_message_io_run_until_read (SoupMessage *msg, return TRUE; if (soup_message_get_io_data (msg) == io) - soup_message_io_update_status (msg, *error); + soup_message_io_finish (msg, *error); return FALSE; } @@ -923,7 +905,7 @@ io_run_until_read_async (SoupMessage *msg, } if (soup_message_get_io_data (msg) == client_io) - soup_message_io_update_status (msg, error); + soup_message_io_finish (msg, error); g_task_return_error (task, error); g_object_unref (task); @@ -993,12 +975,6 @@ soup_message_io_get_response_istream (SoupMessage *msg, SoupClientMessageIOData *io = soup_message_get_io_data (msg); GInputStream *client_stream; - if (SOUP_STATUS_IS_TRANSPORT_ERROR (soup_message_get_status (msg))) { - g_set_error_literal (error, SOUP_HTTP_ERROR, - soup_message_get_status (msg), soup_message_get_reason_phrase (msg)); - return NULL; - } - client_stream = soup_client_input_stream_new (io->base.body_istream, msg); g_signal_connect (client_stream, "eof", G_CALLBACK (client_stream_eof), msg); diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 604251fa..fa0ce46b 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -208,6 +208,14 @@ enum { * be parsed * @SOUP_SESSION_ERROR_ENCODING: the server's response was in an * unsupported format + * @SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS: the message has been redirected + * too many times + * @SOUP_SESSION_ERROR_TOO_MANY_RESTARTS: the message has been restarted + * too many times + * @SOUP_SESSION_ERROR_REDIRECT_NO_LOCATION: failed to redirect message because + * Location header was missing or empty in response + * @SOUP_SESSION_ERROR_REDIRECT_BAD_URI: failed to redirect message because + * Location header contains an invalid URI * * A #SoupSession error. */ @@ -777,23 +785,39 @@ free_host (SoupSessionHost *host) soup_message_get_status (msg) == SOUP_STATUS_FOUND) && \ SOUP_METHOD_IS_SAFE (soup_message_get_method (msg))) -static inline GUri * -redirection_uri (SoupMessage *msg) +static GUri * +redirection_uri (SoupSession *session, + SoupMessage *msg, + GError **error) { + SoupSessionPrivate *priv; const char *new_loc; GUri *new_uri; new_loc = soup_message_headers_get_one (soup_message_get_response_headers (msg), "Location"); - if (!new_loc) + if (!new_loc || !*new_loc) { + g_set_error_literal (error, + SOUP_SESSION_ERROR, + SOUP_SESSION_ERROR_REDIRECT_NO_LOCATION, + _("Location header is missing or empty in response headers")); return NULL; + } new_uri = g_uri_parse_relative (soup_message_get_uri (msg), new_loc, SOUP_HTTP_URI_FLAGS, NULL); if (!new_uri) return NULL; - - if (!g_uri_get_host (new_uri)) { + + priv = soup_session_get_instance_private (session); + if (!g_uri_get_host (new_uri) || !*g_uri_get_host (new_uri) || + (!soup_uri_is_http (new_uri, priv->http_aliases) && + !soup_uri_is_https (new_uri, priv->https_aliases))) { g_uri_unref (new_uri); + g_set_error (error, + SOUP_SESSION_ERROR, + SOUP_SESSION_ERROR_REDIRECT_BAD_URI, + _("Invalid URI “%s” in Location response header"), + new_loc); return NULL; } @@ -816,35 +840,58 @@ redirection_uri (SoupMessage *msg) gboolean soup_session_would_redirect (SoupSession *session, SoupMessage *msg) { - SoupSessionPrivate *priv = soup_session_get_instance_private (session); GUri *new_uri; + g_return_val_if_fail (SOUP_IS_SESSION (session), FALSE); + g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE); + /* It must have an appropriate status code and method */ if (!SOUP_SESSION_WOULD_REDIRECT_AS_GET (session, msg) && !SOUP_SESSION_WOULD_REDIRECT_AS_SAFE (session, msg)) return FALSE; - /* and a Location header that parses to an http URI */ - if (!soup_message_headers_get_one (soup_message_get_response_headers (msg), "Location")) - return FALSE; - new_uri = redirection_uri (msg); + new_uri = redirection_uri (session, msg, NULL); if (!new_uri) return FALSE; - if (!g_uri_get_host (new_uri) || !*g_uri_get_host (new_uri) || - (!soup_uri_is_http (new_uri, priv->http_aliases) && - !soup_uri_is_https (new_uri, priv->https_aliases))) { - g_uri_unref (new_uri); - return FALSE; - } g_uri_unref (new_uri); return TRUE; } +static gboolean +soup_session_requeue_item (SoupSession *session, + SoupMessageQueueItem *item, + GError **error) +{ + gboolean retval; + + if (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, + SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS, + _("Too many redirects")); + } else { + g_set_error_literal (error, + SOUP_SESSION_ERROR, + SOUP_SESSION_ERROR_TOO_MANY_RESTARTS, + _("Message was restarted too many times")); + } + retval = FALSE; + } else { + item->resend_count++; + item->state = SOUP_MESSAGE_RESTARTING; + retval = TRUE; + } + + 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 @@ -866,11 +913,20 @@ soup_session_would_redirect (SoupSession *session, SoupMessage *msg) * Since: 2.38 */ gboolean -soup_session_redirect_message (SoupSession *session, SoupMessage *msg) +soup_session_redirect_message (SoupSession *session, + SoupMessage *msg, + GError **error) { + SoupSessionPrivate *priv; GUri *new_uri; + SoupMessageQueueItem *item; + gboolean retval; - new_uri = redirection_uri (msg); + 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); + + new_uri = redirection_uri (session, msg, error); if (!new_uri) return FALSE; @@ -888,8 +944,12 @@ soup_session_redirect_message (SoupSession *session, SoupMessage *msg) soup_message_set_uri (msg, new_uri); g_uri_unref (new_uri); - soup_session_requeue_message (session, msg); - return TRUE; + 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 @@ -899,8 +959,11 @@ redirect_handler (SoupMessage *msg, SoupMessageQueueItem *item = user_data; SoupSession *session = item->session; - if (soup_session_would_redirect (session, msg)) - soup_session_redirect_message (session, msg); + 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); } static void @@ -1184,51 +1247,6 @@ soup_session_unqueue_item (SoupSession *session, } static void -soup_session_set_item_status (SoupSession *session, - SoupMessageQueueItem *item, - guint status_code, - GError *error) -{ - GUri *uri = NULL; - - switch (status_code) { - case SOUP_STATUS_CANT_RESOLVE: - case SOUP_STATUS_CANT_CONNECT: - uri = soup_message_get_uri (item->msg); - break; - - case SOUP_STATUS_CANT_RESOLVE_PROXY: - case SOUP_STATUS_CANT_CONNECT_PROXY: - if (item->conn) - uri = soup_connection_get_proxy_uri (item->conn); - break; - - case SOUP_STATUS_SSL_FAILED: - if (!g_tls_backend_supports_tls (g_tls_backend_get_default ())) { - soup_message_set_status_full (item->msg, status_code, - "TLS/SSL support not available; install glib-networking"); - return; - } - break; - - default: - break; - } - - if (error) - soup_message_set_status_full (item->msg, status_code, error->message); - else if (uri && g_uri_get_host (uri)) { - char *msg = g_strdup_printf ("%s (%s)", - soup_status_get_phrase (status_code), - g_uri_get_host (uri)); - soup_message_set_status_full (item->msg, status_code, msg); - g_free (msg); - } else - soup_message_set_status (item->msg, status_code); -} - - -static void message_completed (SoupMessage *msg, SoupMessageIOCompletion completion, gpointer user_data) { SoupMessageQueueItem *item = user_data; @@ -1250,41 +1268,6 @@ message_completed (SoupMessage *msg, SoupMessageIOCompletion completion, gpointe } } -static guint -status_from_connect_error (SoupMessageQueueItem *item, GError *error) -{ - guint status; - - if (!error) - return SOUP_STATUS_OK; - - if (error->domain == G_TLS_ERROR) - status = SOUP_STATUS_SSL_FAILED; - else if (error->domain == G_RESOLVER_ERROR) - status = SOUP_STATUS_CANT_RESOLVE; - else if (error->domain == G_IO_ERROR) { - if (error->code == G_IO_ERROR_CANCELLED) - status = SOUP_STATUS_CANCELLED; - else if (error->code == G_IO_ERROR_HOST_UNREACHABLE || - error->code == G_IO_ERROR_NETWORK_UNREACHABLE || - error->code == G_IO_ERROR_CONNECTION_REFUSED) - status = SOUP_STATUS_CANT_CONNECT; - else if (error->code == G_IO_ERROR_PROXY_FAILED || - error->code == G_IO_ERROR_PROXY_AUTH_FAILED || - error->code == G_IO_ERROR_PROXY_NEED_AUTH || - error->code == G_IO_ERROR_PROXY_NOT_ALLOWED) - status = SOUP_STATUS_CANT_CONNECT_PROXY; - else - status = SOUP_STATUS_IO_ERROR; - } else - status = SOUP_STATUS_IO_ERROR; - - if (item->conn && soup_connection_is_via_proxy (item->conn)) - return soup_status_proxify (status); - else - return status; -} - static void tunnel_complete (SoupMessageQueueItem *tunnel_item, guint status, GError *error) @@ -1297,18 +1280,17 @@ tunnel_complete (SoupMessageQueueItem *tunnel_item, if (soup_message_get_status (item->msg)) item->state = SOUP_MESSAGE_FINISHING; + else if (item->state == SOUP_MESSAGE_TUNNELING) + item->state = SOUP_MESSAGE_READY; item->error = error; - if (!status) - status = status_from_connect_error (item, error); - if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { + if (!SOUP_STATUS_IS_SUCCESSFUL (status) || item->error) { soup_connection_disconnect (item->conn); soup_session_set_item_connection (session, item, NULL); - if (soup_message_get_status (item->msg) == 0) - soup_session_set_item_status (session, item, status, error); + if (!error && soup_message_get_status (item->msg) == SOUP_STATUS_NONE) + soup_message_set_status (item->msg, status); } - item->state = SOUP_MESSAGE_READY; if (item->async) soup_session_kick_queue (session); soup_message_queue_item_unref (item); @@ -1322,7 +1304,7 @@ tunnel_handshake_complete (SoupConnection *conn, GError *error = NULL; soup_connection_tunnel_handshake_finish (conn, result, &error); - tunnel_complete (tunnel_item, 0, error); + tunnel_complete (tunnel_item, SOUP_STATUS_OK, error); } static void @@ -1344,14 +1326,14 @@ tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion, return; } - soup_message_set_status (msg, SOUP_STATUS_TRY_AGAIN); + item->state = SOUP_MESSAGE_RESTARTING; } tunnel_item->state = SOUP_MESSAGE_FINISHED; soup_session_unqueue_item (session, tunnel_item); status = soup_message_get_status (tunnel_item->msg); - if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { + if (!SOUP_STATUS_IS_SUCCESSFUL (status) || item->state == SOUP_MESSAGE_RESTARTING) { tunnel_complete (tunnel_item, status, NULL); return; } @@ -1366,7 +1348,7 @@ tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion, GError *error = NULL; soup_connection_tunnel_handshake (item->conn, item->cancellable, &error); - tunnel_complete (tunnel_item, 0, error); + tunnel_complete (tunnel_item, SOUP_STATUS_OK, error); } } @@ -1403,7 +1385,6 @@ static void connect_complete (SoupMessageQueueItem *item, SoupConnection *conn, GError *error) { SoupSession *session = item->session; - guint status; if (!error) { item->state = SOUP_MESSAGE_CONNECTED; @@ -1411,11 +1392,8 @@ connect_complete (SoupMessageQueueItem *item, SoupConnection *conn, GError *erro } item->error = error; - status = status_from_connect_error (item, error); soup_connection_disconnect (conn); if (item->state == SOUP_MESSAGE_CONNECTING) { - if (soup_message_get_status (item->msg) == 0) - soup_session_set_item_status (session, item, status, error); soup_session_set_item_connection (session, item, NULL); item->state = SOUP_MESSAGE_READY; } @@ -1621,12 +1599,8 @@ soup_session_process_queue_item (SoupSession *session, break; } - if (soup_message_get_status (item->msg)) { - if (soup_message_get_status (item->msg) == SOUP_STATUS_TRY_AGAIN) { - soup_message_cleanup_response (item->msg); - item->state = SOUP_MESSAGE_STARTING; - } else - item->state = SOUP_MESSAGE_FINISHING; + if (item->error || soup_message_get_status (item->msg)) { + item->state = SOUP_MESSAGE_FINISHING; break; } @@ -1752,27 +1726,14 @@ idle_run_queue_dnotify (gpointer user_data) * again. **/ void -soup_session_requeue_message (SoupSession *session, SoupMessage *msg) +soup_session_requeue_message (SoupSession *session, + SoupMessage *msg) { SoupSessionPrivate *priv = soup_session_get_instance_private (session); SoupMessageQueueItem *item; - g_return_if_fail (SOUP_IS_SESSION (session)); - g_return_if_fail (SOUP_IS_MESSAGE (msg)); - item = soup_message_queue_lookup (priv->queue, msg); - g_return_if_fail (item != NULL); - - if (item->resend_count >= SOUP_SESSION_MAX_RESEND_COUNT) { - if (SOUP_STATUS_IS_REDIRECTION (soup_message_get_status (msg))) - soup_message_set_status (msg, SOUP_STATUS_TOO_MANY_REDIRECTS); - else - g_warning ("SoupMessage %p stuck in infinite loop?", msg); - } else { - item->resend_count++; - item->state = SOUP_MESSAGE_RESTARTING; - } - + soup_session_requeue_item (session, item, &item->error); soup_message_queue_item_unref (item); } @@ -1887,8 +1848,7 @@ soup_session_unpause_message (SoupSession *session, * soup_session_cancel_message: * @session: a #SoupSession * @msg: the message to cancel - * @status_code: status code to set on @msg (generally - * %SOUP_STATUS_CANCELLED) + * @status_code: status code to set on @msg * * Causes @session to immediately finish processing @msg (regardless * of its current state) with a final status_code of @status_code. You @@ -1935,7 +1895,6 @@ soup_session_cancel_message (SoupSession *session, SoupMessage *msg, guint statu soup_message_io_unpause (msg); } - soup_message_set_status (msg, status_code); g_cancellable_cancel (item->cancellable); soup_session_kick_queue (item->session); @@ -1968,8 +1927,7 @@ soup_session_abort (SoupSession *session) for (item = soup_message_queue_first (priv->queue); item; item = soup_message_queue_next (priv->queue, item)) { - soup_session_cancel_message (session, item->msg, - SOUP_STATUS_CANCELLED); + soup_session_cancel_message (session, item->msg, SOUP_STATUS_NONE); } /* Close all idle connections */ @@ -2668,8 +2626,10 @@ 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 (session, msg); + 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); + } return FALSE; } @@ -2696,13 +2656,6 @@ async_send_request_return_result (SoupMessageQueueItem *item, if (stream) g_object_unref (stream); g_task_return_error (task, g_error_copy (item->error)); - } else if (SOUP_STATUS_IS_TRANSPORT_ERROR (soup_message_get_status (item->msg))) { - if (stream) - g_object_unref (stream); - g_task_return_new_error (task, SOUP_HTTP_ERROR, - soup_message_get_status (item->msg), - "%s", - soup_message_get_reason_phrase (item->msg)); } else g_task_return_pointer (task, stream, g_object_unref); g_object_unref (task); @@ -2831,8 +2784,11 @@ run_until_read_done (SoupMessage *msg, GError *error = NULL; soup_message_io_run_until_read_finish (msg, result, &error); - if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN)) + if (error && !item->io_started) { + /* Message was restarted, we'll try again. */ + g_error_free (error); return; + } if (!error) stream = soup_message_io_get_response_istream (msg, &error); @@ -2920,7 +2876,6 @@ cancel_cache_response (SoupMessageQueueItem *item) { item->paused = FALSE; item->state = SOUP_MESSAGE_FINISHING; - soup_message_set_status (item->msg, SOUP_STATUS_CANCELLED); soup_session_kick_queue (item->session); } @@ -3096,15 +3051,6 @@ soup_session_send_async (SoupSession *session, item->task = g_task_new (session, item->cancellable, callback, user_data); g_task_set_priority (item->task, io_priority); g_task_set_task_data (item->task, item, (GDestroyNotify) soup_message_queue_item_unref); - - /* Do not check for cancellations as we do not want to - * overwrite custom error messages set during cancellations - * (for example SOUP_HTTP_ERROR is set for cancelled messages - * in async_send_request_return_result() (status_code==1 - * means CANCEL and is considered a TRANSPORT_ERROR)). - */ - g_task_set_check_cancellable (item->task, FALSE); - if (async_respond_from_cache (session, item)) item->state = SOUP_MESSAGE_CACHED; else @@ -3215,7 +3161,8 @@ soup_session_send (SoupSession *session, /* Send request, read headers */ if (!soup_message_io_run_until_read (msg, item->cancellable, &my_error)) { - if (g_error_matches (my_error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN)) { + if (item->state == SOUP_MESSAGE_RESTARTING) { + /* Message was restarted, we'll try again. */ g_clear_error (&my_error); continue; } @@ -3267,10 +3214,6 @@ soup_session_send (SoupSession *session, g_clear_object (&stream); if (error) *error = g_error_copy (item->error); - } else if (SOUP_STATUS_IS_TRANSPORT_ERROR (soup_message_get_status (msg))) { - g_clear_object (&stream); - g_set_error_literal (error, SOUP_HTTP_ERROR, soup_message_get_status (msg), - soup_message_get_reason_phrase (msg)); } else if (!stream) stream = g_memory_input_stream_new (); diff --git a/libsoup/soup-session.h b/libsoup/soup-session.h index 8b4e37f7..4da94903 100644 --- a/libsoup/soup-session.h +++ b/libsoup/soup-session.h @@ -23,7 +23,11 @@ typedef enum { SOUP_SESSION_ERROR_BAD_URI, SOUP_SESSION_ERROR_UNSUPPORTED_URI_SCHEME, SOUP_SESSION_ERROR_PARSING, - SOUP_SESSION_ERROR_ENCODING + SOUP_SESSION_ERROR_ENCODING, + SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS, + SOUP_SESSION_ERROR_TOO_MANY_RESTARTS, + SOUP_SESSION_ERROR_REDIRECT_NO_LOCATION, + SOUP_SESSION_ERROR_REDIRECT_BAD_URI } SoupSessionError; SOUP_AVAILABLE_IN_2_42 @@ -62,7 +66,8 @@ gboolean soup_session_would_redirect (SoupSession *session, SoupMessage *msg); SOUP_AVAILABLE_IN_2_38 gboolean soup_session_redirect_message (SoupSession *session, - SoupMessage *msg); + SoupMessage *msg, + GError **error); SOUP_AVAILABLE_IN_2_24 void soup_session_add_feature (SoupSession *session, diff --git a/libsoup/soup-status.c b/libsoup/soup-status.c index 87c6514e..58c5c4a4 100644 --- a/libsoup/soup-status.c +++ b/libsoup/soup-status.c @@ -21,14 +21,6 @@ **/ /** - * SOUP_STATUS_IS_TRANSPORT_ERROR: - * @status: a status code - * - * Tests if @status is a libsoup transport error. - * - * Return value: %TRUE or %FALSE - **/ -/** * SOUP_STATUS_IS_INFORMATIONAL: * @status: an HTTP status code * @@ -73,18 +65,6 @@ * SoupStatus: * @SOUP_STATUS_NONE: No status available. (Eg, the message has not * been sent yet) - * @SOUP_STATUS_CANCELLED: Message was cancelled locally - * @SOUP_STATUS_CANT_RESOLVE: Unable to resolve destination host name - * @SOUP_STATUS_CANT_RESOLVE_PROXY: Unable to resolve proxy host name - * @SOUP_STATUS_CANT_CONNECT: Unable to connect to remote host - * @SOUP_STATUS_CANT_CONNECT_PROXY: Unable to connect to proxy - * @SOUP_STATUS_SSL_FAILED: SSL/TLS negotiation failed - * @SOUP_STATUS_IO_ERROR: A network error occurred, or the other end - * 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_TLS_FAILED: Used internally * @SOUP_STATUS_CONTINUE: 100 Continue (HTTP) * @SOUP_STATUS_SWITCHING_PROTOCOLS: 101 Switching Protocols (HTTP) * @SOUP_STATUS_PROCESSING: 102 Processing (WebDAV) @@ -175,17 +155,6 @@ static const struct { guint code; const char *phrase; } reason_phrases [] = { - /* Transport errors */ - { SOUP_STATUS_CANCELLED, "Cancelled" }, - { SOUP_STATUS_CANT_RESOLVE, "Cannot resolve hostname" }, - { SOUP_STATUS_CANT_RESOLVE_PROXY, "Cannot resolve proxy hostname" }, - { SOUP_STATUS_CANT_CONNECT, "Cannot connect to destination" }, - { SOUP_STATUS_CANT_CONNECT_PROXY, "Cannot connect to proxy" }, - { SOUP_STATUS_SSL_FAILED, "SSL handshake failed" }, - { 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_SWITCHING_PROTOCOLS, "Switching Protocols" }, @@ -281,32 +250,6 @@ soup_status_get_phrase (guint status_code) } /** - * soup_status_proxify: - * @status_code: a status code - * - * Turns %SOUP_STATUS_CANT_RESOLVE into - * %SOUP_STATUS_CANT_RESOLVE_PROXY and %SOUP_STATUS_CANT_CONNECT into - * %SOUP_STATUS_CANT_CONNECT_PROXY. Other status codes are passed - * through unchanged. - * - * Return value: the "proxified" equivalent of @status_code. - * - * Since: 2.26 - **/ -guint -soup_status_proxify (guint status_code) -{ - if (status_code == SOUP_STATUS_CANT_RESOLVE) - return SOUP_STATUS_CANT_RESOLVE_PROXY; - else if (status_code == SOUP_STATUS_CANT_CONNECT) - return SOUP_STATUS_CANT_CONNECT_PROXY; - else - return status_code; -} - -G_DEFINE_QUARK (soup-http-error-quark, soup_http_error) - -/** * SoupHTTPVersion: * @SOUP_HTTP_1_0: HTTP 1.0 (RFC 1945) * @SOUP_HTTP_1_1: HTTP 1.1 (RFC 2616) diff --git a/libsoup/soup-status.h b/libsoup/soup-status.h index cc7512f9..df4ea4ba 100644 --- a/libsoup/soup-status.h +++ b/libsoup/soup-status.h @@ -11,7 +11,6 @@ G_BEGIN_DECLS -#define SOUP_STATUS_IS_TRANSPORT_ERROR(status) ((status) > 0 && (status) < 100) #define SOUP_STATUS_IS_INFORMATIONAL(status) ((status) >= 100 && (status) < 200) #define SOUP_STATUS_IS_SUCCESSFUL(status) ((status) >= 200 && (status) < 300) #define SOUP_STATUS_IS_REDIRECTION(status) ((status) >= 300 && (status) < 400) @@ -21,20 +20,6 @@ G_BEGIN_DECLS typedef enum { SOUP_STATUS_NONE, - /* Transport Errors */ - SOUP_STATUS_CANCELLED = 1, - SOUP_STATUS_CANT_RESOLVE, - SOUP_STATUS_CANT_RESOLVE_PROXY, - SOUP_STATUS_CANT_CONNECT, - SOUP_STATUS_CANT_CONNECT_PROXY, - SOUP_STATUS_SSL_FAILED, - SOUP_STATUS_IO_ERROR, - SOUP_STATUS_MALFORMED, - SOUP_STATUS_TRY_AGAIN, - SOUP_STATUS_TOO_MANY_REDIRECTS, - SOUP_STATUS_TLS_FAILED, - - /* HTTP Status Codes */ SOUP_STATUS_CONTINUE = 100, SOUP_STATUS_SWITCHING_PROTOCOLS = 101, SOUP_STATUS_PROCESSING = 102, /* WebDAV */ @@ -100,17 +85,5 @@ typedef enum { SOUP_AVAILABLE_IN_2_4 const char *soup_status_get_phrase (guint status_code); -SOUP_AVAILABLE_IN_2_26 -guint soup_status_proxify (guint status_code); - -/** - * SOUP_HTTP_ERROR: - * - * A #GError domain representing an HTTP status. Use a #SoupStatus for - * the <structfield>code</structfield> value. - **/ -#define SOUP_HTTP_ERROR (soup_http_error_quark()) -SOUP_AVAILABLE_IN_2_4 -GQuark soup_http_error_quark (void); G_END_DECLS diff --git a/tests/auth-test.c b/tests/auth-test.c index a018ad3c..5b8d354f 100644 --- a/tests/auth-test.c +++ b/tests/auth-test.c @@ -1065,7 +1065,7 @@ do_auth_close_test (void) g_signal_connect (acd.msg, "authenticate", G_CALLBACK (auth_close_authenticate), &acd); g_uri_unref (uri); - body = soup_test_session_async_send (acd.session, acd.msg); + body = soup_test_session_async_send (acd.session, acd.msg, NULL); soup_test_assert_message_status (acd.msg, SOUP_STATUS_OK); @@ -1099,6 +1099,7 @@ do_infinite_auth_test (void) SoupMessage *msg; char *uri; int timeout; + GError *error = NULL; SOUP_TEST_SKIP_IF_NO_APACHE; @@ -1110,17 +1111,13 @@ do_infinite_auth_test (void) g_free (uri); timeout = g_timeout_add (500, infinite_cancel, session); - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - "*stuck in infinite loop*"); - soup_test_session_send_message (session, msg); - g_test_assert_expected_messages (); - - soup_test_assert (soup_message_get_status (msg) != SOUP_STATUS_CANCELLED, - "Got stuck in loop"); + g_assert_null (soup_session_send (session, msg, NULL, &error)); + g_assert_error (error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_TOO_MANY_RESTARTS); soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED); g_source_remove (timeout); soup_test_session_abort_unref (session); + g_clear_error (&error); g_object_unref (msg); } @@ -1192,7 +1189,7 @@ do_disappearing_auth_test (void) g_signal_connect (msg, "authenticate", G_CALLBACK (disappear_authenticate), &counter); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert (counter <= 2, "Got stuck in loop"); @@ -1537,7 +1534,7 @@ cancel_after_retry_authenticate (SoupMessage *msg, CancelAfterRetryData *data) { if (retrying) { - soup_session_cancel_message (data->session, msg, SOUP_STATUS_CANCELLED); + soup_session_cancel_message (data->session, msg, 0); g_cancellable_cancel (data->cancellable); return FALSE; diff --git a/tests/cache-test.c b/tests/cache-test.c index 0a86ef87..0792753f 100644 --- a/tests/cache-test.c +++ b/tests/cache-test.c @@ -129,7 +129,6 @@ static char *do_request (SoupSession *session, static gboolean last_request_hit_network; static gboolean last_request_validated; static gboolean last_request_unqueued; -static guint cancelled_requests; static void copy_headers (const char *name, @@ -229,7 +228,6 @@ do_request_with_cancel (SoupSession *session, GCancellable *cancellable; last_request_validated = last_request_hit_network = last_request_unqueued = FALSE; - cancelled_requests = 0; uri = g_uri_parse_relative (base_uri, path, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri (method, uri); @@ -241,8 +239,10 @@ do_request_with_cancel (SoupSession *session, g_object_unref (stream); g_object_unref (msg); return; - } else + } else { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_clear_error (&error); + } g_clear_object (&cancellable); g_clear_object (&stream); @@ -277,8 +277,6 @@ static void request_unqueued (SoupSession *session, SoupMessage *msg, gpointer data) { - if (soup_message_get_status (msg) == SOUP_STATUS_CANCELLED) - cancelled_requests++; last_request_unqueued = TRUE; } @@ -507,14 +505,12 @@ do_cancel_test (gconstpointer data) debug_printf (1, " Cancel fresh resource with soup_session_message_cancel()\n"); flags = SOUP_TEST_REQUEST_CANCEL_MESSAGE | SOUP_TEST_REQUEST_CANCEL_IMMEDIATE; do_request_with_cancel (session, base_uri, "GET", "/1", flags); - g_assert_cmpint (cancelled_requests, ==, 1); soup_test_assert (last_request_unqueued, "Cancelled request /1 not unqueued"); debug_printf (1, " Cancel fresh resource with g_cancellable_cancel()\n"); flags = SOUP_TEST_REQUEST_CANCEL_CANCELLABLE | SOUP_TEST_REQUEST_CANCEL_IMMEDIATE; do_request_with_cancel (session, base_uri, "GET", "/1", flags); - g_assert_cmpint (cancelled_requests, ==, 1); soup_test_assert (last_request_unqueued, "Cancelled request /1 not unqueued"); @@ -530,14 +526,12 @@ do_cancel_test (gconstpointer data) debug_printf (1, " Cancel a revalidating resource with soup_session_message_cancel()\n"); flags = SOUP_TEST_REQUEST_CANCEL_MESSAGE | SOUP_TEST_REQUEST_CANCEL_IMMEDIATE; do_request_with_cancel (session, base_uri, "GET", "/2", flags); - g_assert_cmpint (cancelled_requests, ==, 2); soup_test_assert (last_request_unqueued, "Cancelled request /2 not unqueued"); debug_printf (1, " Cancel a revalidating resource with g_cancellable_cancel()\n"); flags = SOUP_TEST_REQUEST_CANCEL_CANCELLABLE | SOUP_TEST_REQUEST_CANCEL_IMMEDIATE; do_request_with_cancel (session, base_uri, "GET", "/2", flags); - g_assert_cmpint (cancelled_requests, ==, 2); soup_test_assert (last_request_unqueued, "Cancelled request /2 not unqueued"); @@ -585,7 +579,6 @@ do_refcounting_test (gconstpointer data) soup_session_add_feature (session, SOUP_SESSION_FEATURE (cache)); last_request_validated = last_request_hit_network = FALSE; - cancelled_requests = 0; uri = g_uri_parse_relative (base_uri, "/1", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); diff --git a/tests/connection-test.c b/tests/connection-test.c index 480b34c9..fea3aa38 100644 --- a/tests/connection-test.c +++ b/tests/connection-test.c @@ -504,7 +504,7 @@ do_max_conns_test_for_session (SoupSession *session) * session" error. */ for (i = 0; i < TEST_CONNS; i++) - soup_session_cancel_message (session, msgs[i], SOUP_STATUS_CANCELLED); + soup_session_cancel_message (session, msgs[i], 0); g_main_loop_run (max_conns_loop); } @@ -728,7 +728,7 @@ do_one_connection_state_test (SoupSession *session, g_signal_connect (msg, "network-event", G_CALLBACK (message_network_event), state); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_bytes_unref (body); g_object_unref (msg); diff --git a/tests/continue-test.c b/tests/continue-test.c index 4fc662b2..4f0666cd 100644 --- a/tests/continue-test.c +++ b/tests/continue-test.c @@ -134,7 +134,7 @@ do_message (const char *path, gboolean long_body, events = NULL; session = soup_test_session_new (NULL); g_assert (SOUP_IS_MESSAGE (msg)); - response_body = soup_test_session_async_send (session, msg); + response_body = soup_test_session_async_send (session, msg, NULL); g_assert (SOUP_IS_MESSAGE (msg)); soup_test_session_abort_unref (session); g_assert (SOUP_IS_MESSAGE (msg)); diff --git a/tests/hsts-db-test.c b/tests/hsts-db-test.c index 176ad029..e98914e2 100644 --- a/tests/hsts-db-test.c +++ b/tests/hsts-db-test.c @@ -63,11 +63,17 @@ session_get_uri (SoupSession *session, const char *uri, SoupStatus expected_stat { SoupMessage *msg; GBytes *body; + 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, 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); + else + g_assert_no_error (error); soup_test_assert_message_status (msg, expected_status); + g_clear_error (&error); g_bytes_unref (body); g_object_unref (msg); } @@ -145,7 +151,7 @@ do_hsts_db_subdomains_test (void) soup_test_session_abort_unref (session); session = hsts_db_session_new (); - session_get_uri (session, "http://subdomain.localhost", SOUP_STATUS_SSL_FAILED); + session_get_uri (session, "http://subdomain.localhost", SOUP_STATUS_NONE); soup_test_session_abort_unref (session); g_remove (DB_FILE); diff --git a/tests/hsts-test.c b/tests/hsts-test.c index dad4dcf0..2d75d1bb 100644 --- a/tests/hsts-test.c +++ b/tests/hsts-test.c @@ -109,11 +109,17 @@ session_get_uri (SoupSession *session, const char *uri, SoupStatus expected_stat { SoupMessage *msg; GBytes *body; + 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, 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); + else + g_assert_no_error (error); soup_test_assert_message_status (msg, expected_status); + g_clear_error (&error); g_bytes_unref (body); g_object_unref (msg); } @@ -289,7 +295,7 @@ do_hsts_subdomains_test (void) /* The enforcer should cause the request to ask for an HTTPS uri, which will fail with an SSL error as there's no server in subdomain.localhost. */ - session_get_uri (session, "http://subdomain.localhost", SOUP_STATUS_SSL_FAILED); + session_get_uri (session, "http://subdomain.localhost", SOUP_STATUS_NONE); soup_test_session_abort_unref (session); } @@ -422,7 +428,7 @@ do_hsts_utf8_address_test (void) /* The enforcer should cause the request to ask for an HTTPS uri, which will fail with an SSL error as there's no server in 食狮.中国.localhost. */ - session_get_uri (session, "http://食狮.中国.localhost", SOUP_STATUS_SSL_FAILED); + session_get_uri (session, "http://食狮.中国.localhost", SOUP_STATUS_NONE); soup_test_session_abort_unref (session); } diff --git a/tests/misc-test.c b/tests/misc-test.c index a9df51ae..8f19aca2 100644 --- a/tests/misc-test.c +++ b/tests/misc-test.c @@ -178,7 +178,6 @@ cu_one_completed (SoupMessage *msg, SoupSession *session) { debug_printf (2, " Message 1 completed\n"); - soup_test_assert_message_status (msg, SOUP_STATUS_CANT_CONNECT); g_object_unref (session); } @@ -194,7 +193,6 @@ cu_two_completed (SoupMessage *msg, GMainLoop *loop) { debug_printf (2, " Message 2 completed\n"); - soup_test_assert_message_status (msg, SOUP_STATUS_CANT_CONNECT); g_idle_add (cu_idle_quit, loop); } @@ -309,14 +307,14 @@ do_msg_reuse_test (void) msg = soup_message_new_from_uri ("GET", base_uri); g_signal_connect (msg, "authenticate", G_CALLBACK (reuse_test_authenticate), NULL); - soup_test_session_async_send (session, msg); + soup_test_session_async_send (session, msg, NULL); ensure_no_signal_handlers (msg, signal_ids, n_signal_ids); debug_printf (1, " Redirect message\n"); uri = g_uri_parse_relative (base_uri, "/redirect", SOUP_HTTP_URI_FLAGS, NULL); soup_message_set_uri (msg, uri); g_uri_unref (uri); - soup_test_session_async_send (session, msg); + soup_test_session_async_send (session, msg, NULL); g_assert_true (soup_uri_equal (soup_message_get_uri (msg), base_uri)); ensure_no_signal_handlers (msg, signal_ids, n_signal_ids); @@ -324,10 +322,10 @@ do_msg_reuse_test (void) uri = g_uri_parse_relative (base_uri, "/auth", SOUP_HTTP_URI_FLAGS, NULL); soup_message_set_uri (msg, uri); g_uri_unref (uri); - soup_test_session_async_send (session, msg); + soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); soup_message_set_uri (msg, base_uri); - soup_test_session_async_send (session, msg); + soup_test_session_async_send (session, msg, NULL); ensure_no_signal_handlers (msg, signal_ids, n_signal_ids); soup_test_session_abort_unref (session); @@ -337,11 +335,16 @@ do_msg_reuse_test (void) /* Handle unexpectedly-early aborts. */ static void -ea_msg_completed_one (SoupMessage *msg, - GMainLoop *loop) +ea_msg_completed_one (SoupSession *session, + GAsyncResult *result, + GMainLoop *loop) { + GError *error = NULL; + debug_printf (2, " Message 1 completed\n"); - soup_test_assert_message_status (msg, SOUP_STATUS_CANCELLED); + g_assert_null (soup_session_send_finish (session, result, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); g_main_loop_quit (loop); } @@ -370,7 +373,7 @@ ea_message_network_event (SoupMessage *msg, static void ea_message_starting (SoupMessage *msg, SoupSession *session) { - soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED); + soup_session_cancel_message (session, msg, 0); } static void @@ -378,9 +381,9 @@ do_early_abort_test (void) { SoupSession *session; SoupMessage *msg; - GBytes *body; GMainContext *context; GMainLoop *loop; + GError *error = NULL; g_test_bug ("596074"); g_test_bug ("618641"); @@ -390,9 +393,9 @@ do_early_abort_test (void) context = g_main_context_default (); loop = g_main_loop_new (context, TRUE); - g_signal_connect (msg, "finished", - G_CALLBACK (ea_msg_completed_one), loop); - soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, NULL, NULL, NULL); + soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)ea_msg_completed_one, + loop); g_object_unref (msg); g_main_context_iteration (context, FALSE); @@ -408,11 +411,11 @@ do_early_abort_test (void) g_signal_connect (msg, "network-event", G_CALLBACK (ea_message_network_event), session); - body = soup_test_session_async_send (session, msg); + g_assert_null (soup_test_session_async_send (session, msg, &error)); debug_printf (2, " Message 2 completed\n"); - soup_test_assert_message_status (msg, SOUP_STATUS_CANCELLED); - g_bytes_unref (body); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); g_object_unref (msg); while (g_main_context_pending (context)) @@ -427,11 +430,11 @@ do_early_abort_test (void) g_signal_connect (msg, "starting", G_CALLBACK (ea_message_starting), session); - body = soup_test_session_async_send (session, msg); + g_assert_null (soup_test_session_async_send (session, msg, &error)); debug_printf (2, " Message 3 completed\n"); - soup_test_assert_message_status (msg, SOUP_STATUS_CANCELLED); - g_bytes_unref (body); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); g_object_unref (msg); while (g_main_context_pending (context)) @@ -486,25 +489,18 @@ cancel_message_timeout (gpointer msg) { SoupSession *session = g_object_get_data (G_OBJECT (msg), "session"); - soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED); + soup_session_cancel_message (session, msg, 0); g_object_unref (msg); g_object_unref (session); return FALSE; } static void -set_done (SoupMessage *msg, - gboolean *done) -{ - *done = TRUE; -} - -static void do_cancel_while_reading_test_for_session (SoupSession *session) { SoupMessage *msg; GUri *uri; - gboolean done = FALSE; + GError *error = NULL; uri = g_uri_parse_relative (base_uri, "/slow", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); @@ -515,17 +511,9 @@ do_cancel_while_reading_test_for_session (SoupSession *session) g_object_ref (session); g_timeout_add (100, cancel_message_timeout, msg); - g_signal_connect (msg, "finished", - G_CALLBACK (set_done), &done); - soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, NULL, NULL, NULL); - while (!done) - g_main_context_iteration (NULL, TRUE); - /* We need one more iteration, because SoupMessage::finished is emitted - * right before the message is unqueued. - */ - g_main_context_iteration (NULL, TRUE); - - soup_test_assert_message_status (msg, SOUP_STATUS_CANCELLED); + g_assert_null (soup_test_session_async_send (session, msg, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); g_object_unref (msg); } diff --git a/tests/no-ssl-test.c b/tests/no-ssl-test.c index a5b9442d..009a254c 100644 --- a/tests/no-ssl-test.c +++ b/tests/no-ssl-test.c @@ -6,14 +6,16 @@ static void do_ssl_test_for_session (SoupSession *session, GUri *uri) { SoupMessage *msg; + GError *error; msg = soup_message_new_from_uri ("GET", uri); - soup_test_session_send_message (session, msg); - soup_test_assert_message_status (msg, SOUP_STATUS_SSL_FAILED); - + soup_session_send (session, msg, NULL, &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE); + g_assert_cmpuint (soup_message_get_status (msg), ==, SOUP_STATUS_NONE); g_assert_null (soup_message_get_tls_certificate (msg)); g_assert_cmpuint (soup_message_get_tls_certificate_errors (msg), ==, 0); + g_error_free (error); g_object_unref (msg); } diff --git a/tests/range-test.c b/tests/range-test.c index cc050720..08ca88bc 100644 --- a/tests/range-test.c +++ b/tests/range-test.c @@ -69,7 +69,7 @@ do_single_range (SoupSession *session, SoupMessage *msg, debug_printf (1, " Range: %s\n", soup_message_headers_get_one (soup_message_get_request_headers (msg), "Range")); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); if (!succeed) { soup_test_assert_message_status (msg, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE); @@ -120,7 +120,7 @@ do_multi_range (SoupSession *session, SoupMessage *msg, debug_printf (1, " Range: %s\n", soup_message_headers_get_one (soup_message_get_request_headers (msg), "Range")); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_PARTIAL_CONTENT); diff --git a/tests/redirect-test.c b/tests/redirect-test.c index 615da0fe..0e7e996f 100644 --- a/tests/redirect-test.c +++ b/tests/redirect-test.c @@ -19,6 +19,7 @@ typedef struct { typedef struct { TestRequest requests[3]; guint final_status; + guint error_code; const char *bugref; } TestCase; @@ -27,96 +28,99 @@ static TestCase tests[] = { { { { "GET", "/301", 301 }, { "GET", "/", 200 }, - { NULL } }, 200, NULL }, + { NULL } }, 200, 0, NULL }, { { { "GET", "/302", 302 }, { "GET", "/", 200 }, - { NULL } }, 200, NULL }, + { NULL } }, 200, 0, NULL }, { { { "GET", "/303", 303 }, { "GET", "/", 200 }, - { NULL } }, 200, NULL }, + { NULL } }, 200, 0, NULL }, { { { "GET", "/307", 307 }, { "GET", "/", 200 }, - { NULL } }, 200, NULL }, + { NULL } }, 200, 0, NULL }, { { { "GET", "/308", 308 }, { "GET", "/", 200 }, - { NULL } }, 200, NULL }, + { NULL } }, 200, 0, NULL }, { { { "HEAD", "/301", 301 }, { "HEAD", "/", 200 }, - { NULL } }, 200, "551190" }, + { NULL } }, 200, 0, "551190" }, { { { "HEAD", "/302", 302 }, { "HEAD", "/", 200 }, - { NULL } }, 200, "551190" }, + { NULL } }, 200, 0, "551190" }, /* 303 is a nonsensical response to HEAD, but some sites do * it anyway. :-/ */ { { { "HEAD", "/303", 303 }, { "HEAD", "/", 200 }, - { NULL } }, 200, "600830" }, + { NULL } }, 200, 0, "600830" }, { { { "HEAD", "/307", 307 }, { "HEAD", "/", 200 }, - { NULL } }, 200, "551190" }, + { NULL } }, 200, 0, "551190" }, { { { "HEAD", "/308", 308 }, { "HEAD", "/", 200 }, - { NULL } }, 200, "551190" }, + { NULL } }, 200, 0, "551190" }, /* A non-redirecty response to a GET or HEAD should not */ { { { "GET", "/300", 300 }, - { NULL } }, 300, NULL }, + { NULL } }, 300, 0, NULL }, { { { "GET", "/304", 304 }, - { NULL } }, 304, NULL }, + { NULL } }, 304, 0, NULL }, { { { "GET", "/305", 305 }, - { NULL } }, 305, NULL }, + { NULL } }, 305, 0, NULL }, { { { "GET", "/306", 306 }, - { NULL } }, 306, NULL }, + { NULL } }, 306, 0, NULL }, { { { "HEAD", "/300", 300 }, - { NULL } }, 300, "551190" }, + { NULL } }, 300, 0, "551190" }, { { { "HEAD", "/304", 304 }, - { NULL } }, 304, "551190" }, + { NULL } }, 304, 0, "551190" }, { { { "HEAD", "/305", 305 }, - { NULL } }, 305, "551190" }, + { NULL } }, 305, 0, "551190" }, { { { "HEAD", "/306", 306 }, - { NULL } }, 306, "551190" }, + { NULL } }, 306, 0, "551190" }, /* Test double-redirect */ { { { "GET", "/301/302", 301 }, { "GET", "/302", 302 }, - { "GET", "/", 200 } }, 200, NULL }, + { "GET", "/", 200 } }, 200, 0, NULL }, { { { "HEAD", "/301/302", 301 }, { "HEAD", "/302", 302 }, - { "HEAD", "/", 200 } }, 200, "551190" }, + { "HEAD", "/", 200 } }, 200, 0, "551190" }, /* POST should only automatically redirect on 301, 302 and 303 */ { { { "POST", "/301", 301 }, { "GET", "/", 200 }, - { NULL } }, 200, "586692" }, + { NULL } }, 200, 0, "586692" }, { { { "POST", "/302", 302 }, { "GET", "/", 200 }, - { NULL } }, 200, NULL }, + { NULL } }, 200, 0, NULL }, { { { "POST", "/303", 303 }, { "GET", "/", 200 }, - { NULL } }, 200, NULL }, + { NULL } }, 200, 0, NULL }, { { { "POST", "/307", 307 }, - { NULL } }, 307, NULL }, + { NULL } }, 307, 0, NULL }, /* Test behavior with recoverably-bad Location header */ { { { "GET", "/bad", 302 }, { "GET", "/bad%20with%20spaces", 200 }, - { NULL } }, 200, "566530" }, + { NULL } }, 200, 0, "566530" }, { { { "GET", "/bad-no-host", 302 }, - { NULL } }, 302, "528882" }, + { NULL } }, 302, SOUP_SESSION_ERROR_REDIRECT_BAD_URI, "528882" }, + + { { { "GET", "/bad-no-location", 302 }, + { NULL } }, 302, SOUP_SESSION_ERROR_REDIRECT_NO_LOCATION, NULL}, /* Test infinite redirection */ { { { "GET", "/bad-recursive", 302, TRUE }, - { NULL } }, SOUP_STATUS_TOO_MANY_REDIRECTS, "604383" }, + { NULL } }, 302, SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS, "604383" }, /* Test redirection to a different server */ { { { "GET", "/server2", 302 }, { "GET", "/on-server2", 200 }, - { NULL } }, 200, NULL }, + { NULL } }, 200, 0, NULL }, }; static const int n_tests = G_N_ELEMENTS (tests); @@ -164,6 +168,7 @@ do_message_api_test (SoupSession *session, TestCase *test) SoupMessage *msg; GBytes *body; TestRequest *treq; + GError *error = NULL; if (test->bugref) g_test_bug (test->bugref); @@ -186,10 +191,15 @@ do_message_api_test (SoupSession *session, TestCase *test) g_signal_connect (msg, "restarted", G_CALLBACK (restarted), &treq); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, &error); soup_test_assert_message_status (msg, test->final_status); + if (test->error_code) + g_assert_error (error, SOUP_SESSION_ERROR, test->error_code); + else + g_assert_no_error (error); + g_clear_error (&error); g_bytes_unref (body); g_object_unref (msg); } @@ -239,6 +249,10 @@ server_callback (SoupServer *server, soup_message_headers_replace (response_headers, "Location", "about:blank"); + } else if (!strcmp (path, "/bad-no-location")) { + soup_server_message_set_status (msg, SOUP_STATUS_FOUND, NULL); + soup_message_headers_replace (response_headers, + "Location", ""); } else if (!strcmp (path, "/bad with spaces")) soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); else diff --git a/tests/request-body-test.c b/tests/request-body-test.c index b2b6335b..c6227f00 100644 --- a/tests/request-body-test.c +++ b/tests/request-body-test.c @@ -119,7 +119,7 @@ do_request_test (gconstpointer data) G_CALLBACK (wrote_body_data), &ptd); if (flags & ASYNC) - soup_test_session_async_send (session, msg); + soup_test_session_async_send (session, msg, NULL); else soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_CREATED); diff --git a/tests/server-test.c b/tests/server-test.c index 36edb5a0..94fa142b 100644 --- a/tests/server-test.c +++ b/tests/server-test.c @@ -409,7 +409,7 @@ do_ipv6_test (ServerData *sd, gconstpointer test_data) debug_printf (1, " HTTP/1.1\n"); msg = soup_message_new_from_uri ("GET", sd->base_uri); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_bytes_unref (body); g_object_unref (msg); @@ -417,7 +417,7 @@ do_ipv6_test (ServerData *sd, gconstpointer test_data) debug_printf (1, " HTTP/1.0\n"); msg = soup_message_new_from_uri ("GET", sd->base_uri); soup_message_set_http_version (msg, SOUP_HTTP_1_0); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_bytes_unref (body); g_object_unref (msg); @@ -470,7 +470,7 @@ do_multi_test (ServerData *sd, GUri *uri1, GUri *uri2) uristr = g_uri_to_string (uri1); msg = soup_message_new ("GET", uristr); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_assert_cmpmem (uristr, strlen (uristr), g_bytes_get_data (body, NULL), g_bytes_get_size (body)); g_bytes_unref (body); @@ -479,7 +479,7 @@ do_multi_test (ServerData *sd, GUri *uri1, GUri *uri2) uristr = g_uri_to_string (uri2); msg = soup_message_new ("GET", uristr); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_assert_cmpmem (uristr, strlen (uristr), g_bytes_get_data (body, NULL), g_bytes_get_size (body)); g_bytes_unref (body); @@ -650,7 +650,7 @@ do_gsocket_import_test (void) session = soup_test_session_new (NULL); msg = soup_message_new_from_uri ("GET", uri); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_bytes_unref (body); g_object_unref (msg); @@ -716,7 +716,7 @@ do_fd_import_test (void) session = soup_test_session_new (NULL); msg = soup_message_new_from_uri ("GET", uri); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_bytes_unref (body); g_object_unref (msg); @@ -923,7 +923,7 @@ do_fail_404_test (ServerData *sd, gconstpointer test_data) session = soup_test_session_new (NULL); msg = soup_message_new_from_uri ("GET", sd->base_uri); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_NOT_FOUND); g_bytes_unref (body); g_object_unref (msg); @@ -950,7 +950,7 @@ do_fail_500_test (ServerData *sd, gconstpointer pause) msg = soup_message_new_from_uri ("GET", sd->base_uri); if (pause) soup_message_headers_append (soup_message_get_request_headers (msg), "X-Test-Server-Pause", "true"); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); g_bytes_unref (body); g_object_unref (msg); diff --git a/tests/session-test.c b/tests/session-test.c index 1ae68b5f..34a0f539 100644 --- a/tests/session-test.c +++ b/tests/session-test.c @@ -59,21 +59,29 @@ finished_cb (SoupMessage *msg, static void cancel_message_cb (SoupMessage *msg, gpointer session) { - soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED); + soup_session_cancel_message (session, msg, 0); +} + +static void +cancel_message_send_done (SoupSession *session, + GAsyncResult *result, + GError **error) +{ + g_assert_null (soup_session_send_finish (session, result, error)); g_main_loop_quit (loop); } static void do_test_for_session (SoupSession *session, gboolean queue_is_async, - gboolean send_is_blocking, - gboolean cancel_is_immediate) + gboolean send_is_blocking) { SoupMessage *msg; gboolean finished, local_timeout; guint timeout_id; GUri *timeout_uri; GBytes *body; + GError *error = NULL; debug_printf (1, " queue_message\n"); debug_printf (2, " requesting timeout\n"); @@ -133,33 +141,19 @@ do_test_for_session (SoupSession *session, debug_printf (1, " cancel_message\n"); msg = soup_message_new_from_uri ("GET", base_uri); - finished = FALSE; - g_signal_connect (msg, "finished", - G_CALLBACK (finished_cb), &finished); - soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, NULL, NULL, NULL); + soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)cancel_message_send_done, + &error); g_signal_connect (msg, "wrote-headers", G_CALLBACK (cancel_message_cb), session); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); - if (cancel_is_immediate) - g_assert_true (finished); - else - g_assert_false (finished); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); - if (!finished) { - debug_printf (2, " waiting for finished\n"); - while (!finished) - g_main_context_iteration (NULL, TRUE); - /* We need one iteration more because finished is emitted - * right before the item is unqueued. - */ - g_main_context_iteration (NULL, TRUE); - } g_main_loop_unref (loop); - - soup_test_assert_message_status (msg, SOUP_STATUS_CANCELLED); + g_clear_error (&error); g_object_unref (msg); } @@ -169,7 +163,7 @@ do_plain_tests (void) SoupSession *session; session = soup_test_session_new (NULL); - do_test_for_session (session, TRUE, TRUE, FALSE); + do_test_for_session (session, TRUE, TRUE); soup_test_session_abort_unref (session); } diff --git a/tests/sniffing-test.c b/tests/sniffing-test.c index 0bcc3bea..19f23f1c 100644 --- a/tests/sniffing-test.c +++ b/tests/sniffing-test.c @@ -211,7 +211,7 @@ do_signals_test (gboolean should_content_sniff, "signal::content_sniffed", content_sniffed, NULL, NULL); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); if (should_content_sniff) { soup_test_assert (g_object_get_data (G_OBJECT (msg), "content-sniffed") != NULL, @@ -300,7 +300,7 @@ test_sniffing (const char *path, const char *expected_type) g_signal_connect (msg, "content-sniffed", G_CALLBACK (sniffing_content_sniffed), &sniffed_type); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); g_assert_cmpstr (sniffed_type, ==, expected_type); g_free (sniffed_type); g_bytes_unref (body); @@ -352,7 +352,7 @@ test_disabled (gconstpointer data) g_signal_connect (msg, "content-sniffed", G_CALLBACK (sniffing_content_sniffed), &sniffed_type); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); g_assert_null (sniffed_type); g_bytes_unref (body); diff --git a/tests/ssl-test.c b/tests/ssl-test.c index 53b3441a..ed018488 100644 --- a/tests/ssl-test.c +++ b/tests/ssl-test.c @@ -15,7 +15,7 @@ static const StrictnessTest strictness_tests[] = { { "/ssl/strictness/strict/with-ca", TRUE, TRUE, SOUP_STATUS_OK }, { "/ssl/strictness/strict/without-ca", - TRUE, FALSE, SOUP_STATUS_SSL_FAILED }, + TRUE, FALSE, SOUP_STATUS_NONE }, { "/ssl/strictness/non-strict/with-ca", FALSE, TRUE, SOUP_STATUS_OK }, { "/ssl/strictness/non-strict/without-ca", @@ -36,7 +36,9 @@ do_strictness_test (gconstpointer data) const StrictnessTest *test = data; SoupSession *session; SoupMessage *msg; + GBytes *body; GTlsCertificateFlags flags = 0; + GError *error = NULL; SOUP_TEST_SKIP_IF_NO_TLS; @@ -52,23 +54,27 @@ do_strictness_test (gconstpointer data) g_signal_connect (msg, "accept-certificate", G_CALLBACK (accept_certificate), NULL); } - soup_test_session_send_message (session, msg); + body = soup_test_session_send (session, msg, NULL, &error); soup_test_assert_message_status (msg, test->expected_status); + if (test->expected_status != SOUP_STATUS_OK) + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); g_test_bug ("690176"); g_assert_nonnull (soup_message_get_tls_certificate (msg)); flags = soup_message_get_tls_certificate_errors (msg); g_test_bug ("665182"); - if (test->with_ca_list && SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (msg))) + if (test->with_ca_list && !error) g_assert_cmpuint (flags, ==, 0); else g_assert_cmpuint (flags, !=, 0); - if (soup_message_get_status (msg) == SOUP_STATUS_SSL_FAILED && - test->expected_status != SOUP_STATUS_SSL_FAILED) + if (soup_message_get_status (msg) == SOUP_STATUS_NONE && + test->expected_status != SOUP_STATUS_NONE) debug_printf (1, " tls error flags: 0x%x\n", flags); + g_clear_pointer (&body, g_bytes_unref); + g_clear_error (&error); g_object_unref (msg); soup_test_session_abort_unref (session); @@ -218,8 +224,9 @@ do_tls_interaction_test (void) /* Without a GTlsInteraction */ msg = soup_message_new_from_uri ("GET", test_uri); - body = soup_test_session_async_send (session, msg); - soup_test_assert_message_status (msg, SOUP_STATUS_SSL_FAILED); + body = soup_test_session_async_send (session, msg, &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED); + g_clear_error (&error); g_bytes_unref (body); g_object_unref (msg); @@ -231,7 +238,7 @@ do_tls_interaction_test (void) /* With a GTlsInteraction */ msg = soup_message_new_from_uri ("GET", test_uri); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_assert_nonnull (soup_message_get_tls_certificate (msg)); g_bytes_unref (body); diff --git a/tests/streaming-test.c b/tests/streaming-test.c index cfec948b..7c2ff1e4 100644 --- a/tests/streaming-test.c +++ b/tests/streaming-test.c @@ -93,7 +93,7 @@ do_request (SoupSession *session, GUri *base_uri, char *path) msg = soup_message_new_from_uri ("GET", uri); g_uri_unref (uri); - body = soup_test_session_async_send (session, msg); + body = soup_test_session_async_send (session, msg, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_assert_cmpint (g_bytes_get_size (body), ==, g_bytes_get_size (full_response)); diff --git a/tests/test-utils.c b/tests/test-utils.c index a057e0ed..9627d892 100644 --- a/tests/test-utils.c +++ b/tests/test-utils.c @@ -301,15 +301,22 @@ soup_test_session_abort_unref (SoupSession *session) g_object_unref (session); } +typedef struct { + GBytes *body; + GError *error; + gboolean done; +} SendAsyncData; + static void -send_async_ready_cb (SoupSession *session, - GAsyncResult *result, - GBytes **body) +send_async_ready_cb (SoupSession *session, + GAsyncResult *result, + SendAsyncData *data) { GInputStream *istream; GOutputStream *ostream; - istream = soup_session_send_finish (session, result, NULL); + data->done = TRUE; + istream = soup_session_send_finish (session, result, &data->error); if (!istream) return; @@ -318,40 +325,46 @@ send_async_ready_cb (SoupSession *session, istream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - NULL, NULL); - *body = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (ostream)); + NULL, + &data->error); + data->body = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (ostream)); g_object_unref (ostream); g_object_unref (istream); } static void on_message_finished (SoupMessage *msg, - gboolean *message_finished) + gboolean *message_finished) { *message_finished = TRUE; } GBytes * soup_test_session_async_send (SoupSession *session, - SoupMessage *msg) + SoupMessage *msg, + GError **error) { - gboolean message_finished = FALSE; + gboolean message_finished = FALSE; GMainContext *async_context = g_main_context_ref_thread_default (); gulong signal_id; - GBytes *body = NULL; + SendAsyncData data = { NULL, NULL, FALSE }; signal_id = g_signal_connect (msg, "finished", - G_CALLBACK (on_message_finished), &message_finished); + G_CALLBACK (on_message_finished), &message_finished); + soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, NULL, - (GAsyncReadyCallback)send_async_ready_cb, &body); + (GAsyncReadyCallback)send_async_ready_cb, &data); - while (!message_finished) + while (!data.done || !message_finished) g_main_context_iteration (async_context, TRUE); g_signal_handler_disconnect (msg, signal_id); + if (data.error) + g_propagate_error (error, data.error); + g_main_context_unref (async_context); - return body; + return data.body; } guint @@ -681,8 +694,7 @@ cancel_message_or_cancellable (CancelData *cancel_data) if (cancel_data->flags & SOUP_TEST_REQUEST_CANCEL_MESSAGE) { SoupMessage *msg = cancel_data->msg; - soup_session_cancel_message (cancel_data->session, msg, - SOUP_STATUS_CANCELLED); + soup_session_cancel_message (cancel_data->session, msg, 0); g_object_unref (msg); } else if (cancel_data->flags & SOUP_TEST_REQUEST_CANCEL_CANCELLABLE) { g_cancellable_cancel (cancel_data->cancellable); diff --git a/tests/test-utils.h b/tests/test-utils.h index 20b0b98d..0447f73f 100644 --- a/tests/test-utils.h +++ b/tests/test-utils.h @@ -54,7 +54,8 @@ typedef enum { SoupSession *soup_test_session_new (const char *propname, ...); void soup_test_session_abort_unref (SoupSession *session); GBytes *soup_test_session_async_send (SoupSession *session, - SoupMessage *msg); + SoupMessage *msg, + GError **error); guint soup_test_session_send_message (SoupSession *session, SoupMessage *msg); diff --git a/tests/timeout-test.c b/tests/timeout-test.c index 3d713757..0cbfd5b5 100644 --- a/tests/timeout-test.c +++ b/tests/timeout-test.c @@ -37,7 +37,7 @@ do_message_to_session (SoupSession *session, GUri *uri, g_signal_connect (msg, "finished", G_CALLBACK (message_finished), &finished); #if 0 - soup_test_session_async_send_message (session, msg); + soup_test_session_async_send_message (session, msg, NULL); #endif soup_test_assert_message_status (msg, expected_status); @@ -76,7 +76,9 @@ do_msg_tests_for_session (SoupSession *timeout_session, } do_message_to_session (timeout_session, fast_uri, "fast to timeout", SOUP_STATUS_OK); +#if 0 do_message_to_session (timeout_session, slow_uri, "slow to timeout", SOUP_STATUS_IO_ERROR); +#endif if (idle_session) { do_message_to_session (idle_session, fast_uri, "fast to idle", SOUP_STATUS_OK); |
