[libsoup/carlosgc/http-1-1-required: 3/4] message: make it possible to force http/2 too




commit 4fd79c8f9b7f75c57b54dfc5a44dedcd662be4f7
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Wed Apr 13 10:19:51 2022 +0200

    message: make it possible to force http/2 too
    
    Now that apache supports http/2 for tests, we need a way to force http/2
    because http1 is still the preferred protocol. This changes the API to
    force http1 into force http version. It's not exactly the same because
    force http1 also included http 1.0, but forcing http 1.1 should just
    work too.

 libsoup/soup-connection.c      | 45 +++++++++++++++++++++++++++---------------
 libsoup/soup-message-private.h |  6 +++---
 libsoup/soup-message.c         | 19 +++++++++++-------
 libsoup/soup-session.c         | 15 ++++++--------
 4 files changed, 50 insertions(+), 35 deletions(-)
---
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 783ede8b..01d8c66e 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -31,7 +31,7 @@ typedef struct {
        SoupSocketProperties *socket_props;
         guint64 id;
         GSocketAddress *remote_address;
-        gboolean force_http1;
+        guint8 force_http_version;
 
        GUri *proxy_uri;
        gboolean ssl;
@@ -75,7 +75,7 @@ enum {
        PROP_TLS_CERTIFICATE_ERRORS,
         PROP_TLS_PROTOCOL_VERSION,
         PROP_TLS_CIPHERSUITE_NAME,
-        PROP_FORCE_HTTP1,
+        PROP_FORCE_HTTP_VERSION,
 
        LAST_PROPERTY
 };
@@ -95,6 +95,7 @@ soup_connection_init (SoupConnection *conn)
         SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
 
         priv->http_version = SOUP_HTTP_1_1;
+        priv->force_http_version = G_MAXUINT8;
 }
 
 static void
@@ -156,8 +157,8 @@ soup_connection_set_property (GObject *object, guint prop_id,
        case PROP_ID:
                priv->id = g_value_get_uint64 (value);
                break;
-       case PROP_FORCE_HTTP1:
-               priv->force_http1 = g_value_get_boolean (value);
+       case PROP_FORCE_HTTP_VERSION:
+               priv->force_http_version = g_value_get_uchar (value);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -202,8 +203,8 @@ soup_connection_get_property (GObject *object, guint prop_id,
         case PROP_TLS_CIPHERSUITE_NAME:
                 g_value_set_string (value, soup_connection_get_tls_ciphersuite_name (SOUP_CONNECTION 
(object)));
                 break;
-       case PROP_FORCE_HTTP1:
-               g_value_set_boolean (value, priv->force_http1);
+       case PROP_FORCE_HTTP_VERSION:
+               g_value_set_uchar (value, priv->force_http_version);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -344,12 +345,13 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
                                      NULL,
                                      G_PARAM_READABLE |
                                      G_PARAM_STATIC_STRINGS);
-        properties[PROP_FORCE_HTTP1] =
-                g_param_spec_boolean ("force-http1",
-                                      "Force HTTP 1.x",
-                                      "Force connection to use HTTP 1.x",
-                                      FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
-                                      G_PARAM_STATIC_STRINGS);
+        properties[PROP_FORCE_HTTP_VERSION] =
+                g_param_spec_uchar ("force-http-version",
+                                    "Force HTTP version",
+                                    "Force connection to use a specific HTTP version",
+                                    0, G_MAXUINT8, G_MAXUINT8,
+                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_STATIC_STRINGS);
 
         g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
 }
@@ -568,11 +570,22 @@ new_tls_connection (SoupConnection    *conn,
         GPtrArray *advertised_protocols = g_ptr_array_sized_new (4);
 
         // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
-        if (!priv->force_http1)
+        switch (priv->force_http_version) {
+        case SOUP_HTTP_1_0:
+                g_ptr_array_add (advertised_protocols, "http/1.0");
+                break;
+        case SOUP_HTTP_1_1:
+                g_ptr_array_add (advertised_protocols, "http/1.1");
+                break;
+        case SOUP_HTTP_2_0:
                 g_ptr_array_add (advertised_protocols, "h2");
-
-        g_ptr_array_add (advertised_protocols, "http/1.1");
-        g_ptr_array_add (advertised_protocols, "http/1.0");
+                break;
+        default:
+                g_ptr_array_add (advertised_protocols, "h2");
+                g_ptr_array_add (advertised_protocols, "http/1.1");
+                g_ptr_array_add (advertised_protocols, "http/1.0");
+                break;
+        }
         g_ptr_array_add (advertised_protocols, NULL);
 
         tls_interaction = priv->socket_props->tls_interaction ? g_object_ref 
(priv->socket_props->tls_interaction) : soup_tls_interaction_new (conn);
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index 8b3ad56f..c036630e 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -147,10 +147,10 @@ void soup_message_update_request_host_if_needed (SoupMessage *msg);
 
 void soup_message_force_keep_alive_if_needed    (SoupMessage *msg);
 
-void soup_message_set_force_http1               (SoupMessage *msg,
-                                                 gboolean     force_http1);
+void     soup_message_set_force_http_version    (SoupMessage *msg,
+                                                 guint8       version);
 
-gboolean soup_message_get_force_http1           (SoupMessage *msg);
+guint8   soup_message_get_force_http_version    (SoupMessage *msg);
 
 void     soup_message_set_is_misdirected_retry  (SoupMessage *msg,
                                                  gboolean     is_misdirected_retry);
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index ad408b11..984dfdd4 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -94,9 +94,9 @@ typedef struct {
        gboolean is_top_level_navigation;
         gboolean is_options_ping;
         gboolean is_preconnect;
-        gboolean force_http1;
         gboolean is_misdirected_retry;
         guint    last_connection_id;
+        guint8   force_http_version;
         GSocketAddress *remote_address;
 
         SoupMessageMetrics *metrics;
@@ -164,6 +164,7 @@ soup_message_init (SoupMessage *msg)
 
        priv->http_version = priv->orig_http_version = SOUP_HTTP_1_1;
        priv->priority = SOUP_MESSAGE_PRIORITY_NORMAL;
+        priv->force_http_version = G_MAXUINT8;
 
        priv->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
        priv->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
@@ -1243,7 +1244,11 @@ soup_message_restarted (SoupMessage *msg)
 void
 soup_message_finished (SoupMessage *msg)
 {
+        SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
        g_signal_emit (msg, signals[FINISHED], 0);
+
+        priv->force_http_version = G_MAXUINT8;
 }
 
 gboolean
@@ -3219,20 +3224,20 @@ soup_message_force_keep_alive_if_needed (SoupMessage *msg)
 }
 
 void
-soup_message_set_force_http1 (SoupMessage *msg,
-                              gboolean     force_http1)
+soup_message_set_force_http_version (SoupMessage *msg,
+                                     guint8       version)
 {
         SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
 
-        priv->force_http1 = force_http1;
+        priv->force_http_version = version;
 }
 
-gboolean
-soup_message_get_force_http1 (SoupMessage *msg)
+guint8
+soup_message_get_force_http_version (SoupMessage *msg)
 {
         SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
 
-        return priv->force_http1;
+        return priv->force_http_version;
 }
 
 void
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 9dc3d111..a698f28e 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -1816,7 +1816,7 @@ get_connection_for_host (SoupSession *session,
 {
        SoupSessionPrivate *priv = soup_session_get_instance_private (session);
        GSocketConnectable *remote_connectable;
-        gboolean force_http1;
+        guint8 force_http_version;
        SoupConnection *conn;
        GSList *conns;
 
@@ -1829,10 +1829,7 @@ get_connection_for_host (SoupSession *session,
                return conn;
        }
 
-        if (g_getenv ("SOUP_FORCE_HTTP1"))
-                force_http1 = TRUE;
-        else
-                force_http1 = soup_message_get_force_http1 (item->msg);
+        force_http_version = g_getenv ("SOUP_FORCE_HTTP1") ? SOUP_HTTP_1_1 : 
soup_message_get_force_http_version (item->msg);
 
        for (conns = host->connections; conns; conns = conns->next) {
                 SoupHTTPVersion http_version;
@@ -1840,7 +1837,7 @@ get_connection_for_host (SoupSession *session,
                conn = conns->data;
 
                 http_version = soup_connection_get_negotiated_protocol (conn);
-                if (force_http1 && http_version > SOUP_HTTP_1_1)
+                if (force_http_version <= SOUP_HTTP_1_1 && http_version > SOUP_HTTP_1_1)
                         continue;
 
                switch (soup_connection_get_state (conn)) {
@@ -1859,7 +1856,7 @@ get_connection_for_host (SoupSession *session,
                         /* Always wait if we have a pending connection as it may be
                          * an h2 connection which will be shared. http/1.x connections
                          * will only be slightly delayed. */
-                        if (!force_http1 && !need_new_connection && !item->connect_only)
+                        if (force_http_version > SOUP_HTTP_1_1 && !need_new_connection && 
!item->connect_only)
                                 return NULL;
                default:
                        break;
@@ -1894,7 +1891,7 @@ get_connection_for_host (SoupSession *session,
                             "remote-connectable", remote_connectable,
                             "ssl", soup_uri_is_https (host->uri),
                             "socket-properties", priv->socket_props,
-                             "force-http1", force_http1,
+                             "force-http-version", force_http_version,
                             NULL);
        g_object_unref (remote_connectable);
 
@@ -3927,7 +3924,7 @@ soup_session_websocket_connect_async (SoupSession          *session,
         /* WebSocket negotiation over HTTP/2 is not currently supported
          * and in practice all websocket servers support HTTP1.x with
          * HTTP/2 not providing a tangible benefit */
-        soup_message_set_force_http1 (msg, TRUE);
+        soup_message_set_force_http_version (msg, SOUP_HTTP_1_1);
 
        item = soup_session_append_queue_item (session, msg, TRUE, cancellable);
        item->io_priority = io_priority;


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