diff options
author | Milan Crha <mcrha@redhat.com> | 2023-01-26 12:51:00 +0100 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2023-01-26 12:51:00 +0100 |
commit | 8dc7ab8352ee50bc626c0da1cfedac84bd64aa9e (patch) | |
tree | 18b570f6dd32648d052ac891f187253214b2df66 | |
parent | a2129e521663c51cc5babd39501f96c3cc1fa324 (diff) | |
download | evolution-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.txt | 1 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rw-r--r-- | src/libedataserver/e-soup-session.c | 118 | ||||
-rw-r--r-- | src/libedataserver/e-soup-session.h | 5 |
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 */ |