[evolution-ews/wip/mcrha/soup3] Make compile the m365 part (untested)



commit 7b7a41f994d1444dba80bbd0bb5524cfc1ff01df
Author: Milan Crha <mcrha redhat com>
Date:   Wed Jan 5 17:01:08 2022 +0100

    Make compile the m365 part (untested)

 src/Microsoft365/camel/camel-m365-store.c   |   7 +-
 src/Microsoft365/common/e-m365-connection.c | 567 +++++-----------------------
 src/Microsoft365/common/e-m365-connection.h |  15 +-
 src/Microsoft365/registry/e-m365-backend.c  |   4 +-
 4 files changed, 110 insertions(+), 483 deletions(-)
---
diff --git a/src/Microsoft365/camel/camel-m365-store.c b/src/Microsoft365/camel/camel-m365-store.c
index a0f3f264..78ab2f31 100644
--- a/src/Microsoft365/camel/camel-m365-store.c
+++ b/src/Microsoft365/camel/camel-m365-store.c
@@ -198,7 +198,7 @@ m365_store_read_default_folders (CamelM365Store *m365_store,
                message = soup_message_new (SOUP_METHOD_GET, uri);
 
                if (!message) {
-                       g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), 
uri);
+                       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Malformed URI: “%s”"), 
uri);
 
                        g_ptr_array_unref (requests);
                        g_free (uri);
@@ -222,7 +222,8 @@ m365_store_read_default_folders (CamelM365Store *m365_store,
                        SoupMessage *message = g_ptr_array_index (requests, ii);
                        JsonNode *node = NULL;
 
-                       if (message->status_code > 0 && SOUP_STATUS_IS_SUCCESSFUL (message->status_code) &&
+                       if (e_m365_connection_util_get_message_status_code (message) > 0 &&
+                           SOUP_STATUS_IS_SUCCESSFUL (e_m365_connection_util_get_message_status_code 
(message)) &&
                            e_m365_connection_json_node_from_message (message, NULL, &node, cancellable, 
NULL) &&
                            node && JSON_NODE_HOLDS_OBJECT (node)) {
                                JsonObject *object = json_node_get_object (node);
@@ -1809,7 +1810,7 @@ camel_m365_store_maybe_disconnect (CamelM365Store *m365_store,
        if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED)
                return;
 
-       if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+       if (g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                CamelSession *session;
                ESourceRegistry *registry = NULL;
 
diff --git a/src/Microsoft365/common/e-m365-connection.c b/src/Microsoft365/common/e-m365-connection.c
index 14f24cb8..226a55d7 100644
--- a/src/Microsoft365/common/e-m365-connection.c
+++ b/src/Microsoft365/common/e-m365-connection.c
@@ -33,15 +33,10 @@ struct _EM365ConnectionPrivate {
        CamelM365Settings *settings;
        SoupSession *soup_session;
        GProxyResolver *proxy_resolver;
-       ESoupAuthBearer *bearer_auth;
 
        gchar *user; /* The default user for the URL */
        gchar *impersonate_user;
 
-       gboolean ssl_info_set;
-       gchar *ssl_certificate_pem;
-       GTlsCertificateFlags ssl_certificate_errors;
-
        gchar *hash_key; /* in the opened connections hash */
 
        /* How many microseconds to wait, until can execute a new request.
@@ -77,269 +72,6 @@ m365_log_enabled (void)
        return log_enabled == 1;
 }
 
-static SoupSession *
-m365_connection_ref_soup_session (EM365Connection *cnc)
-{
-       SoupSession *soup_session = NULL;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), NULL);
-
-       LOCK (cnc);
-
-       if (cnc->priv->soup_session)
-               soup_session = g_object_ref (cnc->priv->soup_session);
-
-       UNLOCK (cnc);
-
-       return soup_session;
-}
-
-static void
-m365_connection_utils_ensure_bearer_auth_usage (SoupSession *session,
-                                               SoupMessage *message,
-                                               ESoupAuthBearer *bearer)
-{
-       SoupAuthManager *auth_manager;
-       SoupSessionFeature *feature;
-       GUri *uri;
-
-       g_return_if_fail (SOUP_IS_SESSION (session));
-
-       /* Preload the SoupAuthManager with a valid "Bearer" token
-        * when using OAuth 2.0. This avoids an extra unauthorized
-        * HTTP round-trip, which apparently Google doesn't like. */
-
-       feature = soup_session_get_feature (SOUP_SESSION (session), SOUP_TYPE_AUTH_MANAGER);
-
-       if (!soup_session_feature_has_feature (feature, E_TYPE_SOUP_AUTH_BEARER)) {
-               /* Add the "Bearer" auth type to support OAuth 2.0. */
-               soup_session_feature_add_feature (feature, E_TYPE_SOUP_AUTH_BEARER);
-       }
-
-       uri = message ? soup_message_get_uri (message) : NULL;
-       if (uri && g_uri_get_host (uri) && *g_uri_get_host (uri)) {
-               uri = g_uri_build (G_URI_FLAGS_PARSE_RELAXED,
-                       g_uri_get_scheme (uri),
-                       NULL /* userinfo */,
-                       g_uri_get_host (uri),
-                       g_uri_get_port (uri),
-                       NULL /* path */,
-                       NULL /* query */,
-                       NULL /* fragment */);
-       } else {
-               uri = NULL;
-       }
-
-       g_return_if_fail (uri != NULL);
-
-       auth_manager = SOUP_AUTH_MANAGER (feature);
-
-       /* This will make sure the 'bearer' is used regardless of the current 'auth_manager' state.
-          See https://gitlab.gnome.org/GNOME/libsoup/-/issues/196 for more information. */
-       soup_auth_manager_clear_cached_credentials (auth_manager);
-       soup_auth_manager_use_auth (auth_manager, uri, SOUP_AUTH (bearer));
-
-       g_uri_unref (uri);
-}
-
-static gboolean
-m365_connection_utils_setup_bearer_auth (EM365Connection *cnc,
-                                        SoupSession *session,
-                                        SoupMessage *message,
-                                        gboolean is_in_authenticate_handler,
-                                        ESoupAuthBearer *bearer,
-                                        GCancellable *cancellable,
-                                        GError **error)
-{
-       ESource *source;
-       gchar *access_token = NULL;
-       gint expires_in_seconds = -1;
-       gboolean success = FALSE;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (E_IS_SOUP_AUTH_BEARER (bearer), FALSE);
-
-       source = e_m365_connection_get_source (cnc);
-
-       success = e_source_get_oauth2_access_token_sync (source, cancellable,
-               &access_token, &expires_in_seconds, error);
-
-       if (success) {
-               e_soup_auth_bearer_set_access_token (bearer, access_token, expires_in_seconds);
-
-               if (!is_in_authenticate_handler) {
-                       if (session)
-                               g_object_ref (session);
-                       else
-                               session = m365_connection_ref_soup_session (cnc);
-
-                       m365_connection_utils_ensure_bearer_auth_usage (session, message, bearer);
-
-                       g_clear_object (&session);
-               }
-       }
-
-       g_free (access_token);
-
-       return success;
-}
-
-static gboolean
-m365_connection_utils_prepare_bearer_auth (EM365Connection *cnc,
-                                          SoupSession *session,
-                                          SoupMessage *message,
-                                          GCancellable *cancellable)
-{
-       ESource *source;
-       ESoupAuthBearer *using_bearer_auth;
-       gboolean success;
-       GError *local_error = NULL;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
-
-       source = e_m365_connection_get_source (cnc);
-       if (!source)
-               return TRUE;
-
-       using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
-       if (using_bearer_auth) {
-               success = m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, 
using_bearer_auth, cancellable, &local_error);
-               g_clear_object (&using_bearer_auth);
-       } else {
-               SoupAuth *soup_auth;
-               GUri *uri;
-
-               uri = message ? soup_message_get_uri (message) : NULL;
-               if (uri && g_uri_get_host (uri) && *g_uri_get_host (uri)) {
-                       uri = g_uri_build (G_URI_FLAGS_PARSE_RELAXED,
-                               g_uri_get_scheme (uri),
-                               NULL /* userinfo */,
-                               g_uri_get_host (uri),
-                               g_uri_get_port (uri),
-                               NULL /* path */,
-                               NULL /* query */,
-                               NULL /* fragment */);
-               } else {
-                       uri = NULL;
-               }
-
-               g_warn_if_fail (uri != NULL);
-
-               if (!uri) {
-                       soup_message_set_status_full (message, SOUP_STATUS_MALFORMED, "Cannot get host from 
message");
-                       return FALSE;
-               }
-
-               soup_auth = g_object_new (E_TYPE_SOUP_AUTH_BEARER, SOUP_AUTH_HOST, g_uri_get_host (uri), 
NULL);
-
-               success = m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, 
E_SOUP_AUTH_BEARER (soup_auth), cancellable, &local_error);
-               if (success)
-                       e_m365_connection_set_bearer_auth (cnc, E_SOUP_AUTH_BEARER (soup_auth));
-
-               g_object_unref (soup_auth);
-               g_uri_unref (uri);
-       }
-
-       if (!success) {
-               if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-                       soup_message_set_status (message, SOUP_STATUS_CANCELLED);
-               else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
-                        g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-                       soup_message_set_status_full (message, SOUP_STATUS_UNAUTHORIZED, 
local_error->message);
-               else
-                       soup_message_set_status_full (message, SOUP_STATUS_MALFORMED, local_error ? 
local_error->message : _("Unknown error"));
-       }
-
-       g_clear_error (&local_error);
-
-       return success;
-}
-
-static gboolean
-m365_connection_authenticate (SoupMessage *msg,
-                             SoupAuth *auth,
-                             gboolean retrying,
-                             gpointer user_data)
-{
-       EM365Connection *cnc = user_data;
-       ESoupAuthBearer *using_bearer_auth;
-       GError *local_error = NULL;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), TRUE);
-
-       using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
-
-       if (E_IS_SOUP_AUTH_BEARER (auth)) {
-               g_object_ref (auth);
-               g_warn_if_fail ((gpointer) using_bearer_auth == (gpointer) auth);
-
-               g_clear_object (&using_bearer_auth);
-               using_bearer_auth = E_SOUP_AUTH_BEARER (auth);
-
-               e_m365_connection_set_bearer_auth (cnc, using_bearer_auth);
-       }
-
-       if (!using_bearer_auth) {
-               g_warn_if_reached ();
-               return TRUE;
-       }
-
-       m365_connection_utils_setup_bearer_auth (cnc, cnc->priv->soup_session, msg, TRUE, E_SOUP_AUTH_BEARER 
(auth), NULL, &local_error);
-
-       if (local_error)
-               soup_message_set_status_full (msg, SOUP_STATUS_IO_ERROR, local_error->message);
-
-       g_object_unref (using_bearer_auth);
-       g_clear_error (&local_error);
-
-       return TRUE;
-}
-
-static gboolean
-m365_connection_utils_prepare_message (EM365Connection *cnc,
-                                      SoupSession *session,
-                                      SoupMessage *message,
-                                      GCancellable *cancellable)
-{
-       ESoupAuthBearer *using_bearer_auth;
-       ESource *source;
-       GError *local_error = NULL;
-
-       source = e_m365_connection_get_source (cnc);
-       if (source)
-               e_soup_ssl_trust_connect (message, source);
-
-       if (!g_signal_handler_find (message, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, 
m365_connection_authenticate, cnc)) {
-               g_signal_connect (
-                       message, "authenticate",
-                       G_CALLBACK (m365_connection_authenticate), cnc);
-       }
-
-       if (!m365_connection_utils_prepare_bearer_auth (cnc, session, message, cancellable))
-               return FALSE;
-
-       using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
-
-       if (using_bearer_auth &&
-           e_soup_auth_bearer_is_expired (using_bearer_auth) &&
-           !m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, using_bearer_auth, 
cancellable, &local_error)) {
-               if (local_error) {
-                       soup_message_set_status_full (message, SOUP_STATUS_BAD_REQUEST, local_error->message);
-                       g_clear_error (&local_error);
-               } else {
-                       soup_message_set_status (message, SOUP_STATUS_BAD_REQUEST);
-               }
-
-               g_object_unref (using_bearer_auth);
-
-               return FALSE;
-       }
-
-       g_clear_object (&using_bearer_auth);
-
-       return TRUE;
-}
-
 static void
 m365_connection_set_settings (EM365Connection *cnc,
                              CamelM365Settings *settings)
@@ -536,6 +268,8 @@ m365_connection_constructed (GObject *object)
        /* Chain up to parent's method. */
        G_OBJECT_CLASS (e_m365_connection_parent_class)->constructed (object);
 
+       cnc->priv->soup_session = SOUP_SESSION (e_soup_session_new (cnc->priv->source));
+
        if (m365_log_enabled ()) {
                SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_BODY);
 
@@ -546,13 +280,23 @@ m365_connection_constructed (GObject *object)
 
        soup_session_add_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_COOKIE_JAR);
        soup_session_add_feature_by_type (cnc->priv->soup_session, E_TYPE_SOUP_AUTH_BEARER);
+
+       /* This can use only OAuth2 authentication, which should be set on the ESource */
        soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_BASIC);
+       soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_NTLM);
+       soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_NEGOTIATE);
+       soup_session_add_feature_by_type (cnc->priv->soup_session, E_TYPE_SOUP_AUTH_BEARER);
 
        cnc->priv->hash_key = camel_network_settings_dup_user (CAMEL_NETWORK_SETTINGS (cnc->priv->settings));
 
        if (!cnc->priv->hash_key)
                cnc->priv->hash_key = g_strdup ("no-user");
 
+       e_binding_bind_property (
+               cnc, "proxy-resolver",
+               cnc->priv->soup_session, "proxy-resolver",
+               G_BINDING_SYNC_CREATE);
+
        e_binding_bind_property (
                cnc->priv->settings, "timeout",
                cnc->priv->soup_session, "timeout",
@@ -580,17 +324,10 @@ m365_connection_dispose (GObject *object)
 
        LOCK (cnc);
 
-       if (cnc->priv->soup_session) {
-               g_signal_handlers_disconnect_by_func (
-                       cnc->priv->soup_session,
-                       m365_connection_authenticate, object);
-       }
-
        g_clear_object (&cnc->priv->source);
        g_clear_object (&cnc->priv->settings);
        g_clear_object (&cnc->priv->soup_session);
        g_clear_object (&cnc->priv->proxy_resolver);
-       g_clear_object (&cnc->priv->bearer_auth);
 
        UNLOCK (cnc);
 
@@ -604,7 +341,6 @@ m365_connection_finalize (GObject *object)
        EM365Connection *cnc = E_M365_CONNECTION (object);
 
        g_rec_mutex_clear (&cnc->priv->property_lock);
-       g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
        g_clear_pointer (&cnc->priv->user, g_free);
        g_clear_pointer (&cnc->priv->impersonate_user, g_free);
        g_free (cnc->priv->hash_key);
@@ -717,22 +453,38 @@ e_m365_connection_init (EM365Connection *cnc)
        g_rec_mutex_init (&cnc->priv->property_lock);
 
        cnc->priv->backoff_for_usec = 0;
-       cnc->priv->soup_session = soup_session_new_with_options (
-               "timeout", 90,
-               NULL);
-
-       /* Do not use G_BINDING_SYNC_CREATE, because we don't have a GProxyResolver yet anyway. */
-       e_binding_bind_property (
-               cnc, "proxy-resolver",
-               cnc->priv->soup_session, "proxy-resolver",
-               G_BINDING_DEFAULT);
 }
 
 gboolean
 e_m365_connection_util_delta_token_failed (const GError *error)
 {
-       return g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
-              g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_BAD_REQUEST);
+       return g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
+              g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_BAD_REQUEST);
+}
+
+void
+e_m365_connection_util_set_message_status_code (SoupMessage *message,
+                                               gint status_code)
+{
+       g_return_if_fail (SOUP_IS_MESSAGE (message));
+
+       g_object_set_data (G_OBJECT (message), "m365-batch-status-code",
+               GINT_TO_POINTER (status_code));
+}
+
+gint
+e_m365_connection_util_get_message_status_code (SoupMessage *message)
+{
+       gint status_code;
+
+       g_return_val_if_fail (SOUP_IS_MESSAGE (message), -1);
+
+       status_code = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (message), "m365-batch-status-code"));
+
+       if (!status_code)
+               status_code = soup_message_get_status (message);
+
+       return status_code;
 }
 
 EM365Connection *
@@ -854,7 +606,7 @@ e_m365_connection_get_concurrent_connections (EM365Connection *cnc)
 
        LOCK (cnc);
 
-       g_object_get (G_OBJECT (cnc->priv->soup_session), SOUP_SESSION_MAX_CONNS, &current_cc, NULL);
+       g_object_get (G_OBJECT (cnc->priv->soup_session), "max-conns", &current_cc, NULL);
 
        UNLOCK (cnc);
 
@@ -879,8 +631,8 @@ e_m365_connection_set_concurrent_connections (EM365Connection *cnc,
        LOCK (cnc);
 
        g_object_set (G_OBJECT (cnc->priv->soup_session),
-               SOUP_SESSION_MAX_CONNS, concurrent_connections,
-               SOUP_SESSION_MAX_CONNS_PER_HOST, concurrent_connections,
+               "max-conns", concurrent_connections,
+               "max-conns-per-host", concurrent_connections,
                NULL);
 
        UNLOCK (cnc);
@@ -935,43 +687,6 @@ e_m365_connection_set_proxy_resolver (EM365Connection *cnc,
                g_object_notify (G_OBJECT (cnc), "proxy-resolver");
 }
 
-ESoupAuthBearer *
-e_m365_connection_ref_bearer_auth (EM365Connection *cnc)
-{
-       ESoupAuthBearer *res = NULL;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), NULL);
-
-       LOCK (cnc);
-
-       if (cnc->priv->bearer_auth)
-               res = g_object_ref (cnc->priv->bearer_auth);
-
-       UNLOCK (cnc);
-
-       return res;
-}
-
-void
-e_m365_connection_set_bearer_auth (EM365Connection *cnc,
-                                  ESoupAuthBearer *bearer_auth)
-{
-       g_return_if_fail (E_IS_M365_CONNECTION (cnc));
-
-       LOCK (cnc);
-
-       if (cnc->priv->bearer_auth != bearer_auth) {
-               g_clear_object (&cnc->priv->bearer_auth);
-
-               cnc->priv->bearer_auth = bearer_auth;
-
-               if (cnc->priv->bearer_auth)
-                       g_object_ref (cnc->priv->bearer_auth);
-       }
-
-       UNLOCK (cnc);
-}
-
 static void
 m365_connection_request_cancelled_cb (GCancellable *cancellable,
                                      gpointer user_data)
@@ -983,35 +698,6 @@ m365_connection_request_cancelled_cb (GCancellable *cancellable,
        e_flag_set (flag);
 }
 
-static void
-m365_connection_extract_ssl_data (EM365Connection *cnc,
-                                 SoupMessage *message)
-{
-       GTlsCertificate *certificate = NULL;
-
-       g_return_if_fail (E_IS_M365_CONNECTION (cnc));
-       g_return_if_fail (SOUP_IS_MESSAGE (message));
-
-       LOCK (cnc);
-
-       g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
-       cnc->priv->ssl_info_set = FALSE;
-
-       g_object_get (G_OBJECT (message),
-               "tls-certificate", &certificate,
-               "tls-errors", &cnc->priv->ssl_certificate_errors,
-               NULL);
-
-       if (certificate) {
-               g_object_get (certificate, "certificate-pem", &cnc->priv->ssl_certificate_pem, NULL);
-               cnc->priv->ssl_info_set = TRUE;
-
-               g_object_unref (certificate);
-       }
-
-       UNLOCK (cnc);
-}
-
 /* An example error response:
 
   {
@@ -1032,6 +718,7 @@ m365_connection_extract_error (JsonNode *node,
                               GError **error)
 {
        JsonObject *object;
+       GQuark domain = E_SOUP_SESSION_ERROR;
        const gchar *code, *message;
 
        if (!node || !JSON_NODE_HOLDS_OBJECT (node))
@@ -1048,15 +735,17 @@ m365_connection_extract_error (JsonNode *node,
        if (!code && !message)
                return FALSE;
 
-       if (!status_code || SOUP_STATUS_IS_SUCCESSFUL (status_code))
-               status_code = SOUP_STATUS_MALFORMED;
-       else if (g_strcmp0 (code, "ErrorInvalidUser") == 0)
+       if (!status_code || status_code == -1 || SOUP_STATUS_IS_SUCCESSFUL (status_code)) {
+               domain = G_IO_ERROR;
+               status_code = G_IO_ERROR_INVALID_DATA;
+       } else if (g_strcmp0 (code, "ErrorInvalidUser") == 0) {
                status_code = SOUP_STATUS_UNAUTHORIZED;
+       }
 
        if (code && message)
-               g_set_error (error, SOUP_HTTP_ERROR, status_code, "%s: %s", code, message);
+               g_set_error (error, domain, status_code, "%s: %s", code, message);
        else
-               g_set_error_literal (error, SOUP_HTTP_ERROR, status_code, code ? code : message);
+               g_set_error_literal (error, domain, status_code, code ? code : message);
 
        return TRUE;
 }
@@ -1093,7 +782,7 @@ e_m365_connection_json_node_from_message (SoupMessage *message,
        if (message_json_object) {
                *out_node = json_node_init_object (json_node_new (JSON_NODE_OBJECT), message_json_object);
 
-               success = !m365_connection_extract_error (*out_node, message->status_code, &local_error);
+               success = !m365_connection_extract_error (*out_node, 
e_m365_connection_util_get_message_status_code (message), &local_error);
        } else {
                const gchar *content_type;
 
@@ -1108,24 +797,15 @@ e_m365_connection_json_node_from_message (SoupMessage *message,
                        if (input_stream) {
                                success = json_parser_load_from_stream (json_parser, input_stream, 
cancellable, error);
                        } else {
-                               SoupBuffer *sbuffer;
-
-                               sbuffer = soup_message_body_flatten (message->response_body);
-
-                               if (sbuffer) {
-                                       success = json_parser_load_from_data (json_parser, sbuffer->data, 
sbuffer->length, error);
-                                       soup_buffer_free (sbuffer);
-                               } else {
-                                       /* This should not happen, it's for safety check only, thus the 
string is not localized */
-                                       success = FALSE;
-                                       g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "No 
JSON data found");
-                               }
+                               /* This should not happen, it's for safety check only, thus the string is not 
localized */
+                               success = FALSE;
+                               g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "No JSON 
data found");
                        }
 
                        if (success) {
                                *out_node = json_parser_steal_root (json_parser);
 
-                               success = !m365_connection_extract_error (*out_node, message->status_code, 
&local_error);
+                               success = !m365_connection_extract_error (*out_node, 
e_m365_connection_util_get_message_status_code (message), &local_error);
                        }
 
                        g_object_unref (json_parser);
@@ -1229,37 +909,27 @@ m365_connection_send_request_sync (EM365Connection *cnc,
                if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
                        UNLOCK (cnc);
 
-                       soup_message_set_status (message, SOUP_STATUS_CANCELLED);
+                       e_m365_connection_util_set_message_status_code (message, -1);
 
                        return FALSE;
                }
 
                soup_session = cnc->priv->soup_session ? g_object_ref (cnc->priv->soup_session) : NULL;
 
-               g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
-               cnc->priv->ssl_certificate_errors = 0;
-               cnc->priv->ssl_info_set = FALSE;
-
                UNLOCK (cnc);
 
-               if (soup_session &&
-                   m365_connection_utils_prepare_message (cnc, soup_session, message, cancellable)) {
+               if (soup_session) {
                        GInputStream *input_stream;
 
-                       input_stream = soup_session_send (soup_session, message, cancellable, error);
+                       input_stream = e_soup_session_send_message_sync (E_SOUP_SESSION (soup_session), 
message, cancellable, error);
 
                        success = input_stream != NULL;
 
-                       if (success && m365_log_enabled ())
-                               input_stream = e_soup_logger_attach (message, input_stream);
-
                        /* Throttling - https://docs.microsoft.com/en-us/graph/throttling  */
-                       if (message->status_code == 429 ||
+                       if (e_m365_connection_util_get_message_status_code (message) == 429 ||
                            /* 
https://docs.microsoft.com/en-us/graph/best-practices-concept#handling-expected-errors */
-                           message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE) {
+                           e_m365_connection_util_get_message_status_code (message) == 
SOUP_STATUS_SERVICE_UNAVAILABLE) {
                                need_retry = TRUE;
-                       } else if (message->status_code == SOUP_STATUS_SSL_FAILED) {
-                               m365_connection_extract_ssl_data (cnc, message);
                        }
 
                        if (need_retry) {
@@ -1284,13 +954,13 @@ m365_connection_send_request_sync (EM365Connection *cnc,
                                if (cnc->priv->backoff_for_usec < need_retry_seconds * G_USEC_PER_SEC)
                                        cnc->priv->backoff_for_usec = need_retry_seconds * G_USEC_PER_SEC;
 
-                               if (message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE)
+                               if (e_m365_connection_util_get_message_status_code (message) == 
SOUP_STATUS_SERVICE_UNAVAILABLE)
                                        soup_session_abort (soup_session);
 
                                UNLOCK (cnc);
 
                                success = FALSE;
-                       } else if (success && raw_data_func && SOUP_STATUS_IS_SUCCESSFUL 
(message->status_code)) {
+                       } else if (success && raw_data_func && SOUP_STATUS_IS_SUCCESSFUL 
(e_m365_connection_util_get_message_status_code (message))) {
                                success = raw_data_func (cnc, message, input_stream, func_user_data, 
cancellable, error);
                        } else if (success) {
                                JsonNode *node = NULL;
@@ -1319,14 +989,13 @@ m365_connection_send_request_sync (EM365Connection *cnc,
                                        }
 
                                        g_free (next_link);
-                               } else if (error && !*error && message->status_code && 
!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
-                                       if (message->status_code == SOUP_STATUS_CANCELLED) {
-                                               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
-                                                       message->reason_phrase ? message->reason_phrase : 
soup_status_get_phrase (message->status_code));
-                                       } else {
-                                               g_set_error_literal (error, SOUP_HTTP_ERROR, 
message->status_code,
-                                                       message->reason_phrase ? message->reason_phrase : 
soup_status_get_phrase (message->status_code));
-                                       }
+                               } else if (error && !*error && e_m365_connection_util_get_message_status_code 
(message) && !SOUP_STATUS_IS_SUCCESSFUL (e_m365_connection_util_get_message_status_code (message))) {
+                                       if (e_m365_connection_util_get_message_status_code (message) == -1)
+                                               g_set_error_literal (error, G_IO_ERROR, 
G_IO_ERROR_INVALID_DATA, _("Invalid data"));
+                                       else
+                                               g_set_error_literal (error, E_SOUP_SESSION_ERROR, 
e_m365_connection_util_get_message_status_code (message),
+                                                       soup_message_get_reason_phrase (message) ? 
soup_message_get_reason_phrase (message) :
+                                                       soup_status_get_phrase 
(e_m365_connection_util_get_message_status_code (message)));
                                }
 
                                if (node)
@@ -1335,15 +1004,14 @@ m365_connection_send_request_sync (EM365Connection *cnc,
 
                        g_clear_object (&input_stream);
                } else {
-                       if (!message->status_code)
-                               soup_message_set_status (message, SOUP_STATUS_CANCELLED);
-
-                       if (message->status_code == SOUP_STATUS_CANCELLED) {
-                               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
-                                       message->reason_phrase ? message->reason_phrase : 
soup_status_get_phrase (message->status_code));
+                       if (!e_m365_connection_util_get_message_status_code (message)) {
+                               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation 
was cancelled"));
+                       } else if (e_m365_connection_util_get_message_status_code (message) == -1) {
+                               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Invalid 
data"));
                        } else {
-                               g_set_error_literal (error, SOUP_HTTP_ERROR, message->status_code,
-                                       message->reason_phrase ? message->reason_phrase : 
soup_status_get_phrase (message->status_code));
+                               g_set_error_literal (error, E_SOUP_SESSION_ERROR, 
e_m365_connection_util_get_message_status_code (message),
+                                       soup_message_get_reason_phrase (message) ? 
soup_message_get_reason_phrase (message) :
+                                       soup_status_get_phrase 
(e_m365_connection_util_get_message_status_code (message)));
                        }
                }
 
@@ -1537,36 +1205,12 @@ m365_connection_new_soup_message (const gchar *method,
                if ((csm_flags & CSM_DISABLE_RESPONSE) != 0)
                        soup_message_headers_append (request_headers, "Prefer", "return=minimal");
        } else {
-               g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), uri);
+               g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Malformed URI: “%s”"), uri);
        }
 
        return message;
 }
 
-gboolean
-e_m365_connection_get_ssl_error_details (EM365Connection *cnc,
-                                        gchar **out_certificate_pem,
-                                        GTlsCertificateFlags *out_certificate_errors)
-{
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (out_certificate_pem != NULL, FALSE);
-       g_return_val_if_fail (out_certificate_errors != NULL, FALSE);
-
-       LOCK (cnc);
-
-       if (!cnc->priv->ssl_info_set) {
-               UNLOCK (cnc);
-               return FALSE;
-       }
-
-       *out_certificate_pem = g_strdup (cnc->priv->ssl_certificate_pem);
-       *out_certificate_errors = cnc->priv->ssl_certificate_errors;
-
-       UNLOCK (cnc);
-
-       return TRUE;
-}
-
 ESourceAuthenticationResult
 e_m365_connection_authenticate_sync (EM365Connection *cnc,
                                     const gchar *user_override,
@@ -1619,35 +1263,22 @@ e_m365_connection_authenticate_sync (EM365Connection *cnc,
        if (success) {
                result = E_SOURCE_AUTHENTICATION_ACCEPTED;
        } else {
-               if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_CANCELLED)) {
-                       local_error->domain = G_IO_ERROR;
-                       local_error->code = G_IO_ERROR_CANCELLED;
-               } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
+               if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+                       /* Nothing to do */
+               } else if (e_soup_session_get_ssl_error_details (E_SOUP_SESSION (cnc->priv->soup_session), 
out_certificate_pem, out_certificate_errors)) {
                        result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
+               } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+                       LOCK (cnc);
 
-                       if (out_certificate_pem || out_certificate_errors)
-                               e_m365_connection_get_ssl_error_details (cnc, out_certificate_pem, 
out_certificate_errors);
-               } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
-                       ESoupAuthBearer *bearer;
-
-                       bearer = e_m365_connection_ref_bearer_auth (cnc);
-
-                       if (bearer) {
-                               LOCK (cnc);
-
-                               if (cnc->priv->impersonate_user) {
-                                       g_propagate_error (error, local_error);
-                                       local_error = NULL;
-                               } else {
-                                       result = E_SOURCE_AUTHENTICATION_REJECTED;
-                               }
-
-                               UNLOCK (cnc);
+                       if (cnc->priv->impersonate_user) {
+                               g_propagate_error (error, local_error);
+                               local_error = NULL;
                        } else {
-                               result = E_SOURCE_AUTHENTICATION_REQUIRED;
+                               result = E_SOURCE_AUTHENTICATION_REJECTED;
                        }
 
-                       g_clear_object (&bearer);
+                       UNLOCK (cnc);
+
                        g_clear_error (&local_error);
                }
 
@@ -1741,7 +1372,7 @@ e_m365_connection_construct_uri (EM365Connection *cnc,
                if (use_user) {
                        gchar *encoded;
 
-                       encoded = soup_uri_encode (use_user, NULL);
+                       encoded = g_uri_escape_string (use_user, NULL, FALSE);
 
                        g_string_append_c (uri, '/');
                        g_string_append (uri, encoded);
@@ -1785,7 +1416,7 @@ e_m365_connection_construct_uri (EM365Connection *cnc,
                        if (*value) {
                                gchar *encoded;
 
-                               encoded = soup_uri_encode (value, NULL);
+                               encoded = g_uri_escape_string (value, NULL, FALSE);
 
                                g_string_append (uri, encoded);
 
@@ -1866,7 +1497,7 @@ e_m365_connection_fill_batch_response (SoupMessage *message,
        g_return_if_fail (SOUP_IS_MESSAGE (message));
        g_return_if_fail (object != NULL);
 
-       message->status_code = e_m365_json_get_int_member (object, "status", SOUP_STATUS_MALFORMED);
+       e_m365_connection_util_set_message_status_code (message, e_m365_json_get_int_member (object, 
"status", -1));
 
        subobject = e_m365_json_get_object_member (object, "headers");
 
@@ -1989,13 +1620,13 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
                if (!submessage)
                        continue;
 
-               submessage->status_code = SOUP_STATUS_IO_ERROR;
+               e_m365_connection_util_set_message_status_code (submessage, -1);
 
                guri = soup_message_get_uri (submessage);
                uri = guri ? g_uri_to_string_partial (guri, G_URI_HIDE_PASSWORD) : NULL;
 
                if (!uri) {
-                       submessage->status_code = SOUP_STATUS_MALFORMED;
+                       g_warning ("%s: Batch message ignored due to no URI", G_STRFUNC);
                        continue;
                }
 
@@ -2011,7 +1642,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
                e_m365_json_begin_object_member (builder, NULL);
 
                e_m365_json_add_string_member (builder, "id", buff);
-               e_m365_json_add_string_member (builder, "method", submessage->method);
+               e_m365_json_add_string_member (builder, "method", soup_message_get_method (submessage));
                e_m365_json_add_string_member (builder, "url", use_uri);
 
                g_free (uri);
@@ -2049,7 +1680,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
 
                                parser = json_parser_new_immutable ();
 
-                               success = json_parser_load_from_stream (parser, request_body, error);
+                               success = json_parser_load_from_stream (parser, request_body, cancellable, 
error);
 
                                if (!success)
                                        g_prefix_error (error, "%s", _("Failed to parse own Json data"));
@@ -2071,7 +1702,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
                                buffer = g_new0 (guint8, n_buffer_sz);
                                array = g_byte_array_sized_new (request_body_length + 1);
 
-                               while (g_input_stream_read_all (request_body, buffer, n_buffer_sz, &n_read, 
cancellable, NULL))) {
+                               while (g_input_stream_read_all (request_body, buffer, n_buffer_sz, &n_read, 
cancellable, NULL)) {
                                        if (n_read > 0)
                                                g_byte_array_append (array, buffer, n_read);
                                }
@@ -2080,7 +1711,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
                                buffer[0] = '\0';
                                g_byte_array_append (array, buffer, 1);
 
-                               e_m365_json_add_string_member (builder, "body", array->data);
+                               e_m365_json_add_string_member (builder, "body", (const gchar *) array->data);
 
                                g_byte_array_unref (array);
                                g_free (buffer);
@@ -2145,9 +1776,9 @@ e_m365_connection_batch_request_sync (EM365Connection *cnc,
                                        continue;
 
                                /* Throttling - https://docs.microsoft.com/en-us/graph/throttling  */
-                               if (message->status_code == 429 ||
+                               if (e_m365_connection_util_get_message_status_code (message) == 429 ||
                                    /* 
https://docs.microsoft.com/en-us/graph/best-practices-concept#handling-expected-errors */
-                                   message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE) {
+                                   e_m365_connection_util_get_message_status_code (message) == 
SOUP_STATUS_SERVICE_UNAVAILABLE) {
                                        const gchar *retry_after_str;
                                        gint64 retry_after;
 
diff --git a/src/Microsoft365/common/e-m365-connection.h b/src/Microsoft365/common/e-m365-connection.h
index e12a18be..89cee114 100644
--- a/src/Microsoft365/common/e-m365-connection.h
+++ b/src/Microsoft365/common/e-m365-connection.h
@@ -76,6 +76,11 @@ struct _EM365ConnectionClass {
 
 gboolean       e_m365_connection_util_delta_token_failed
                                                (const GError *error);
+void           e_m365_connection_util_set_message_status_code
+                                               (SoupMessage *message,
+                                                gint status_code);
+gint           e_m365_connection_util_get_message_status_code
+                                               (SoupMessage *message);
 
 GType          e_m365_connection_get_type      (void) G_GNUC_CONST;
 
@@ -105,16 +110,6 @@ GProxyResolver *e_m365_connection_ref_proxy_resolver
 void           e_m365_connection_set_proxy_resolver
                                                (EM365Connection *cnc,
                                                 GProxyResolver *proxy_resolver);
-ESoupAuthBearer *
-               e_m365_connection_ref_bearer_auth
-                                               (EM365Connection *cnc);
-void           e_m365_connection_set_bearer_auth
-                                               (EM365Connection *cnc,
-                                                ESoupAuthBearer *bearer_auth);
-gboolean       e_m365_connection_get_ssl_error_details
-                                               (EM365Connection *cnc,
-                                                gchar **out_certificate_pem,
-                                                GTlsCertificateFlags *out_certificate_errors);
 ESourceAuthenticationResult
                e_m365_connection_authenticate_sync
                                                (EM365Connection *cnc,
diff --git a/src/Microsoft365/registry/e-m365-backend.c b/src/Microsoft365/registry/e-m365-backend.c
index a19917b0..e8bb3580 100644
--- a/src/Microsoft365/registry/e-m365-backend.c
+++ b/src/Microsoft365/registry/e-m365-backend.c
@@ -344,8 +344,8 @@ m365_backend_sync_contact_folders_sync (EM365Backend *m365_backend,
                        id, NULL, display_name, TRUE, NULL);
 
                json_object_unref (user_contacts);
-       } else if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_NOT_FOUND) ||
-                  g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+       } else if (g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_NOT_FOUND) ||
+                  g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                m365_backend_remove_resource (m365_backend, E_SOURCE_EXTENSION_ADDRESS_BOOK, NULL);
        }
 


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