[libsoup/carlosgc/http-1-1-required] http2: handle HTTP_1_1_REQUIRED stream error




commit 5a57bdee5078b94ccecdb00b0b88204c9c7a6585
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Fri Apr 22 13:15:22 2022 +0200

    http2: handle HTTP_1_1_REQUIRED stream error
    
    Force http version in message to 1.1 and mark it to be restarted.
    
    Fixes #275

 libsoup/http2/soup-client-message-io-http2.c | 10 ++++++-
 tests/http2-test.c                           | 39 ++++++++++++++++++++++++++++
 tests/httpd.conf.in                          |  4 +++
 3 files changed, 52 insertions(+), 1 deletion(-)
---
diff --git a/libsoup/http2/soup-client-message-io-http2.c b/libsoup/http2/soup-client-message-io-http2.c
index e0d96241..6e9e48b3 100644
--- a/libsoup/http2/soup-client-message-io-http2.c
+++ b/libsoup/http2/soup-client-message-io-http2.c
@@ -960,8 +960,16 @@ on_stream_close_callback (nghttp2_session *session,
 
         data->io->in_callback++;
 
-        if (error_code == NGHTTP2_REFUSED_STREAM && data->state < STATE_READ_DATA)
+        switch (error_code) {
+        case NGHTTP2_REFUSED_STREAM:
+                if (data->state < STATE_READ_DATA)
+                        data->can_be_restarted = TRUE;
+                break;
+        case NGHTTP2_HTTP_1_1_REQUIRED:
+                soup_message_set_force_http_version (data->item->msg, SOUP_HTTP_1_1);
                 data->can_be_restarted = TRUE;
+                break;
+        }
 
         data->io->in_callback--;
         return 0;
diff --git a/tests/http2-test.c b/tests/http2-test.c
index cbc6c41b..689fa2f5 100644
--- a/tests/http2-test.c
+++ b/tests/http2-test.c
@@ -1013,6 +1013,39 @@ do_timeout_test (Test *test, gconstpointer data)
                 g_main_context_iteration (NULL, FALSE);
 }
 
+static void
+message_restarted (SoupMessage *msg,
+                   gboolean    *was_restarted)
+{
+        *was_restarted = TRUE;
+}
+
+static void
+do_http_1_1_required_test (Test *test, gconstpointer data)
+{
+        SoupMessage *msg;
+        GBytes *response;
+        gboolean was_restarted = FALSE;
+        GError *error = NULL;
+
+        SOUP_TEST_SKIP_IF_NO_APACHE;
+
+        msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:47525/client-cert";);
+        soup_message_set_force_http_version (msg, SOUP_HTTP_2_0);
+        g_signal_connect (msg, "restarted",
+                          G_CALLBACK (message_restarted), &was_restarted);
+        response = soup_test_session_async_send (test->session, msg, NULL, &error);
+        g_assert_no_error (error);
+        g_assert_cmpuint (soup_message_get_status (msg), ==, 403);
+        g_assert_true (was_restarted);
+        g_assert_nonnull (response);
+        g_bytes_unref (response);
+        g_object_unref (msg);
+
+        while (g_main_context_pending (NULL))
+                g_main_context_iteration (NULL, FALSE);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1025,6 +1058,8 @@ main (int argc, char **argv)
                 return 1;
         }
 
+        apache_init ();
+
         g_test_add ("/http2/basic/async", Test, NULL,
                     setup_session,
                     do_basic_async_test,
@@ -1125,6 +1160,10 @@ main (int argc, char **argv)
                     setup_session,
                     do_timeout_test,
                     teardown_session);
+        g_test_add ("/http2/http-1-1-required", Test, NULL,
+                    setup_session,
+                    do_http_1_1_required_test,
+                    teardown_session);
 
        ret = g_test_run ();
 
diff --git a/tests/httpd.conf.in b/tests/httpd.conf.in
index 66f081dd..809dc5ca 100644
--- a/tests/httpd.conf.in
+++ b/tests/httpd.conf.in
@@ -284,3 +284,7 @@ Alias /Digest .
   # test RFC2069-style Digest
   AuthDigestQop none
 </Location>
+
+<Location /client-cert>
+  SSLVerifyClient require
+</Location>
\ No newline at end of file


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]