summaryrefslogtreecommitdiff
path: root/libsoup
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2022-08-29 12:00:35 +0200
committerCarlos Garcia Campos <cgarcia@igalia.com>2022-08-31 11:09:26 +0200
commitfb7cad1a928c062c811bc5782630138265f295c2 (patch)
tree597a53db39edde5c1f129c43580bb99d603d9303 /libsoup
parentbba8c0faed1fcbfc6742530bbfe516837636991b (diff)
downloadlibsoup-fb7cad1a928c062c811bc5782630138265f295c2.tar.gz
http2: retry messages that failed due to IO errors
Diffstat (limited to 'libsoup')
-rw-r--r--libsoup/http2/soup-client-message-io-http2.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/libsoup/http2/soup-client-message-io-http2.c b/libsoup/http2/soup-client-message-io-http2.c
index 528c4e36..6a5b2265 100644
--- a/libsoup/http2/soup-client-message-io-http2.c
+++ b/libsoup/http2/soup-client-message-io-http2.c
@@ -211,6 +211,21 @@ advance_state_from (SoupHTTP2MessageData *data,
data->state = to;
}
+static gboolean
+soup_http2_message_data_can_be_restarted (SoupHTTP2MessageData *data,
+ GError *error)
+{
+ if (data->can_be_restarted)
+ return TRUE;
+
+ return data->state < STATE_READ_DATA_START &&
+ !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 (data->msg));
+}
+
static void
soup_http2_message_data_check_status (SoupHTTP2MessageData *data)
{
@@ -237,7 +252,7 @@ soup_http2_message_data_check_status (SoupHTTP2MessageData *data)
if (data->error) {
GError *error = g_steal_pointer (&data->error);
- if (data->can_be_restarted)
+ if (soup_http2_message_data_can_be_restarted (data, error))
data->item->state = SOUP_MESSAGE_RESTARTING;
else
soup_message_set_metrics_timestamp (data->msg, SOUP_MESSAGE_METRICS_RESPONSE_END);
@@ -924,7 +939,7 @@ on_stream_close_callback (nghttp2_session *session,
switch (error_code) {
case NGHTTP2_REFUSED_STREAM:
- if (data->state < STATE_READ_DATA)
+ if (data->state < STATE_READ_DATA_START)
data->can_be_restarted = TRUE;
break;
case NGHTTP2_HTTP_1_1_REQUIRED:
@@ -1601,12 +1616,13 @@ soup_client_message_io_http2_run_until_read (SoupClientMessageIO *iface,
{
SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
+ GError *my_error = NULL;
- if (io_run_until (io, msg, STATE_READ_DATA, cancellable, error))
+ if (io_run_until (io, msg, STATE_READ_DATA, cancellable, &my_error))
return TRUE;
if (get_io_data (msg) == io) {
- if (data->can_be_restarted)
+ if (soup_http2_message_data_can_be_restarted (data, my_error))
data->item->state = SOUP_MESSAGE_RESTARTING;
else
soup_message_set_metrics_timestamp (msg, SOUP_MESSAGE_METRICS_RESPONSE_END);
@@ -1614,6 +1630,8 @@ soup_client_message_io_http2_run_until_read (SoupClientMessageIO *iface,
soup_client_message_io_http2_finished (iface, msg);
}
+ g_propagate_error (error, my_error);
+
return FALSE;
}