diff options
-rw-r--r-- | libsoup/http2/soup-client-message-io-http2.c | 26 | ||||
-rw-r--r-- | tests/connection-test.c | 39 |
2 files changed, 48 insertions, 17 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; } diff --git a/tests/connection-test.c b/tests/connection-test.c index 8a1ca7e5..18b75f31 100644 --- a/tests/connection-test.c +++ b/tests/connection-test.c @@ -13,6 +13,7 @@ static SoupServer *server; static GUri *base_uri; +static GUri *base_https_uri; static GMutex server_mutex; static void @@ -63,7 +64,6 @@ timeout_request_finished (SoupServer *server, gpointer user_data) { SoupServerConnection *conn; - GMainContext *context = g_main_context_get_thread_default (); GIOStream *iostream; GInputStream *istream; GSource *source; @@ -79,8 +79,6 @@ timeout_request_finished (SoupServer *server, g_source_unref (source); g_mutex_unlock (&server_mutex); - while (soup_server_connection_is_connected (conn)) - g_main_context_iteration (context, TRUE); } static void @@ -261,14 +259,17 @@ request_queued_socket_collector (SoupSession *session, } static void -do_timeout_test_for_session (SoupSession *session) +do_timeout_test_for_base_uri (GUri *base_uri) { + SoupSession *session; SoupMessage *msg; GSocket *sockets[4] = { NULL, NULL, NULL, NULL }; GUri *timeout_uri; int i; GBytes *body; + session = soup_test_session_new (NULL); + g_signal_connect (session, "request-queued", G_CALLBACK (request_queued_socket_collector), &sockets); @@ -311,23 +312,24 @@ do_timeout_test_for_session (SoupSession *session) for (i = 0; sockets[i]; i++) g_object_unref (sockets[i]); + + soup_test_session_abort_unref (session); } static void do_persistent_connection_timeout_test (void) { - SoupSession *session; - g_test_bug ("631525"); - debug_printf (1, " Normal session, message API\n"); - session = soup_test_session_new (NULL); - do_timeout_test_for_session (session); - soup_test_session_abort_unref (session); + debug_printf (1, " HTTP/1\n"); + do_timeout_test_for_base_uri (base_uri); + + debug_printf (1, " HTTP/2\n"); + do_timeout_test_for_base_uri (base_https_uri); } static void -do_persistent_connection_timeout_test_with_cancellation (void) +do_persistent_connection_timeout_test_with_cancellation_for_base_uri (GUri *base_uri) { SoupSession *session; SoupMessage *msg; @@ -410,6 +412,16 @@ do_persistent_connection_timeout_test_with_cancellation (void) soup_test_session_abort_unref (session); } +static void +do_persistent_connection_timeout_test_with_cancellation (void) +{ + debug_printf (1, " HTTP/1\n"); + do_persistent_connection_timeout_test_with_cancellation_for_base_uri (base_uri); + + debug_printf (1, " HTTP/2\n"); + do_persistent_connection_timeout_test_with_cancellation_for_base_uri (base_https_uri); +} + static GMainLoop *max_conns_loop; static int msgs_done; static guint quit_loop_timeout; @@ -1693,9 +1705,10 @@ main (int argc, char **argv) test_init (argc, argv, NULL); apache_init (); - server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD); - soup_server_add_handler (server, NULL, server_callback, "http", NULL); + server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD | SOUP_TEST_SERVER_HTTP2); + soup_server_add_handler (server, NULL, server_callback, NULL, NULL); base_uri = soup_test_server_get_uri (server, "http", NULL); + base_https_uri = soup_test_server_get_uri (server, "https", NULL); g_test_add_func ("/connection/content-length-framing", do_content_length_framing_test); g_test_add_func ("/connection/persistent-connection-timeout", do_persistent_connection_timeout_test); |