[libsoup/carlosgc/status: 1/5] Remove non-HTTP SoupStatus values
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/carlosgc/status: 1/5] Remove non-HTTP SoupStatus values
- Date: Sun, 15 Nov 2020 13:59:27 +0000 (UTC)
commit 64d8b462723b4cee38a51ae044ed7de8dd5b8325
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Thu Nov 12 15:34:02 2020 +0100
Remove non-HTTP SoupStatus values
Stop using the message status for internal or transport errors and
always use GError for those.
docs/reference/libsoup-3.0-sections.txt | 5 -
libsoup/auth/soup-auth-negotiate.c | 70 ++++----
libsoup/cache/soup-cache.c | 2 +-
libsoup/hsts/soup-hsts-enforcer.c | 2 +-
libsoup/server/soup-server-io.c | 6 +-
libsoup/server/soup-server.c | 6 +-
libsoup/soup-message-io.c | 64 +++-----
libsoup/soup-session.c | 279 +++++++++++++-------------------
libsoup/soup-session.h | 9 +-
libsoup/soup-status.c | 57 -------
libsoup/soup-status.h | 25 ---
tests/auth-test.c | 17 +-
tests/cache-test.c | 13 +-
tests/connection-test.c | 4 +-
tests/continue-test.c | 2 +-
tests/hsts-db-test.c | 10 +-
tests/hsts-test.c | 12 +-
tests/misc-test.c | 68 ++++----
tests/no-ssl-test.c | 8 +-
tests/range-test.c | 4 +-
tests/redirect-test.c | 72 +++++----
tests/request-body-test.c | 2 +-
tests/server-test.c | 16 +-
tests/session-test.c | 40 ++---
tests/sniffing-test.c | 6 +-
tests/ssl-test.c | 23 ++-
tests/streaming-test.c | 2 +-
tests/test-utils.c | 44 +++--
tests/test-utils.h | 3 +-
tests/timeout-test.c | 4 +-
30 files changed, 364 insertions(+), 511 deletions(-)
---
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt
index f66f50fc..fb476edf 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
@@ -210,10 +209,6 @@ 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
@@ -1183,51 +1246,6 @@ soup_session_unqueue_item (SoupSession *session,
soup_message_queue_item_unref (item);
}
-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)
{
@@ -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
@@ -20,14 +20,6 @@
* HTTP (and libsoup) status codes.
**/
-/**
- * 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" },
@@ -280,32 +249,6 @@ soup_status_get_phrase (guint status_code)
return "Unknown Error";
}
-/**
- * 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)
diff --git a/libsoup/soup-status.h b/libsoup/soup-status.h
index cc7512f9..4235b0f9 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 */
@@ -103,14 +88,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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]