summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2023-01-26 12:51:00 +0100
committerMilan Crha <mcrha@redhat.com>2023-01-26 12:51:00 +0100
commit8dc7ab8352ee50bc626c0da1cfedac84bd64aa9e (patch)
tree18b570f6dd32648d052ac891f187253214b2df66
parenta2129e521663c51cc5babd39501f96c3cc1fa324 (diff)
downloadevolution-data-server-8dc7ab8352ee50bc626c0da1cfedac84bd64aa9e.tar.gz
ews-I#210 - Add option to always use HTTP/1
This adds the functionality into the ESoupSession, thus it can be reused by other parts, if needed. Related to https://gitlab.gnome.org/GNOME/evolution-ews/-/issues/210
-rw-r--r--CMakeLists.txt1
-rw-r--r--config.h.in3
-rw-r--r--src/libedataserver/e-soup-session.c118
-rw-r--r--src/libedataserver/e-soup-session.h5
4 files changed, 126 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7f8558336..f79e4965f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -915,6 +915,7 @@ set(CMAKE_REQUIRED_INCLUDES ${GNOME_PLATFORM_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${GNOME_PLATFORM_LDFLAGS})
CHECK_C_SOURCE_COMPILES("#include <gio/gio.h>
int main(void) { GPowerProfileMonitor *monitor = g_power_profile_monitor_dup_default (); g_clear_object (&monitor); return 0; }" HAVE_GPOWERPROFILEMONITOR)
+CHECK_SYMBOL_EXISTS(soup_message_set_force_http1 libsoup/soup.h HAVE_SOUP_MESSAGE_SET_FORCE_HTTP1)
unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES)
diff --git a/config.h.in b/config.h.in
index b17a753a4..d82fddda7 100644
--- a/config.h.in
+++ b/config.h.in
@@ -208,3 +208,6 @@
/* Defined, when malloc_trim symbol exists in malloc.h */
#cmakedefine HAVE_MALLOC_TRIM 1
+
+/* Defined, when libsoup has soup_message_set_force_http1() */
+#cmakedefine HAVE_SOUP_MESSAGE_SET_FORCE_HTTP1 1
diff --git a/src/libedataserver/e-soup-session.c b/src/libedataserver/e-soup-session.c
index f6645aea6..7a4d6ac45 100644
--- a/src/libedataserver/e-soup-session.c
+++ b/src/libedataserver/e-soup-session.c
@@ -60,12 +60,14 @@ struct _ESoupSessionPrivate {
ESoupAuthBearer *using_bearer_auth;
gboolean auth_prefilled; /* When TRUE, the first 'retrying' is ignored in the "authenticate" handler */
+ gboolean force_http1;
};
enum {
PROP_0,
PROP_SOURCE,
- PROP_CREDENTIALS
+ PROP_CREDENTIALS,
+ PROP_FORCE_HTTP1
};
G_DEFINE_TYPE_WITH_PRIVATE (ESoupSession, e_soup_session, SOUP_TYPE_SESSION)
@@ -508,6 +510,12 @@ e_soup_session_set_property (GObject *object,
E_SOUP_SESSION (object),
g_value_get_boxed (value));
return;
+
+ case PROP_FORCE_HTTP1:
+ e_soup_session_set_force_http1 (
+ E_SOUP_SESSION (object),
+ g_value_get_boolean (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -533,6 +541,13 @@ e_soup_session_get_property (GObject *object,
e_soup_session_dup_credentials (
E_SOUP_SESSION (object)));
return;
+
+ case PROP_FORCE_HTTP1:
+ g_value_set_boolean (
+ value,
+ e_soup_session_get_force_http1 (
+ E_SOUP_SESSION (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -604,6 +619,29 @@ e_soup_session_class_init (ESoupSessionClass *klass)
G_PARAM_READWRITE |
G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS));
+
+ /**
+ * ESoupSession:force-http1:
+ *
+ * Whether the messages created by the session should force use
+ * of HTTP/1 instead of trying HTTP/2 first and fallback to the HTTP/1
+ * when the newer version failed to connect.
+ *
+ * See e_soup_session_set_force_http1() for more information about the limitations.
+ *
+ * Since: 3.48
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FORCE_HTTP1,
+ g_param_spec_boolean (
+ "force-http1",
+ "Force HTTP/1",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS));
}
static void
@@ -815,6 +853,57 @@ e_soup_session_dup_credentials (ESoupSession *session)
}
/**
+ * e_soup_session_set_force_http1:
+ * @session: an #ESoupSession
+ * @force_http1: the value to set
+ *
+ * Sets whether the messages created through the @session using
+ * e_soup_session_new_message() or e_soup_session_new_message_from_uri()
+ * should force use of the HTTP/1, instead of trying HTTP/2 and fallback to HTTP/1,
+ * when the newer version cannot be used.
+ *
+ * The property has no effect when e_soup_session_util_get_force_http1_supported()
+ * returns %FALSE.
+ *
+ * Since: 3.48
+ **/
+void
+e_soup_session_set_force_http1 (ESoupSession *session,
+ gboolean force_http1)
+{
+ g_return_if_fail (E_IS_SOUP_SESSION (session));
+
+ #ifdef HAVE_SOUP_MESSAGE_SET_FORCE_HTTP1
+ if ((session->priv->force_http1 ? 1 : 0) == (force_http1 ? 1 : 0))
+ return;
+
+ session->priv->force_http1 = force_http1;
+
+ g_object_notify (G_OBJECT (session), "force-http1");
+ #endif
+}
+
+/**
+ * e_soup_session_get_force_http1:
+ * @session: an #ESoupSession
+ *
+ * Returns whether it's forced to use HTTP/1 for the messages
+ * created by the @session. See e_soup_session_set_force_http1()
+ * for more information about the limitations.
+ *
+ * Returns: whether it's forced to use HTTP/1
+ *
+ * Since: 3.48
+ **/
+gboolean
+e_soup_session_get_force_http1 (ESoupSession *session)
+{
+ g_return_val_if_fail (E_IS_SOUP_SESSION (session), FALSE);
+
+ return session->priv->force_http1;
+}
+
+/**
* e_soup_session_get_authentication_requires_credentials:
* @session: an #ESoupSession
*
@@ -1054,6 +1143,12 @@ e_soup_session_new_message_from_uri (ESoupSession *session,
e_soup_session_preset_message (message);
+ #ifdef HAVE_SOUP_MESSAGE_SET_FORCE_HTTP1
+ /* only set to TRUE, do not touch it otherwise */
+ if (session->priv->force_http1)
+ soup_message_set_force_http1 (message, TRUE);
+ #endif
+
return message;
}
@@ -2220,3 +2315,24 @@ e_soup_session_util_get_message_bytes (SoupMessage *message)
return g_object_get_data (G_OBJECT (message), E_SOUP_SESSION_MESSAGE_BYTES_KEY);
}
+
+/**
+ * e_soup_session_util_get_force_http1_supported:
+ *
+ * Checks whether e_soup_session_set_force_http1() can be used
+ * to force HTTP/1 usage. This depends on the libsoup version
+ * the data server had been compiled with.
+ *
+ * Returns: %TRUE, when the force of HTTP/1 is supported, %FALSE otherwise
+ *
+ * Since: 3.48
+ **/
+gboolean
+e_soup_session_util_get_force_http1_supported (void)
+{
+ #ifdef HAVE_SOUP_MESSAGE_SET_FORCE_HTTP1
+ return TRUE;
+ #else
+ return FALSE;
+ #endif
+}
diff --git a/src/libedataserver/e-soup-session.h b/src/libedataserver/e-soup-session.h
index b5949b4b6..d93038b21 100644
--- a/src/libedataserver/e-soup-session.h
+++ b/src/libedataserver/e-soup-session.h
@@ -90,6 +90,9 @@ void e_soup_session_set_credentials (ESoupSession *session,
const ENamedParameters *credentials);
ENamedParameters *
e_soup_session_dup_credentials (ESoupSession *session);
+void e_soup_session_set_force_http1 (ESoupSession *session,
+ gboolean force_http1);
+gboolean e_soup_session_get_force_http1 (ESoupSession *session);
gboolean e_soup_session_get_authentication_requires_credentials
(ESoupSession *session);
gboolean e_soup_session_get_ssl_error_details (ESoupSession *session,
@@ -159,6 +162,8 @@ void e_soup_session_util_set_message_request_body_from_data
GInputStream * e_soup_session_util_ref_message_request_body
(SoupMessage *message,
gssize *out_length);
+gboolean e_soup_session_util_get_force_http1_supported
+ (void);
G_END_DECLS
#endif /* E_SOUP_SESSION_H */