[evolution-ews/wip/mcrha/soup3] Modify OAL functions
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/mcrha/soup3] Modify OAL functions
- Date: Thu, 16 Dec 2021 13:05:45 +0000 (UTC)
commit e8203acef25d1eb427cd7a882653997415eb95bd
Author: Milan Crha <mcrha redhat com>
Date: Thu Dec 16 14:05:18 2021 +0100
Modify OAL functions
src/EWS/common/e-ews-connection.c | 737 +++++++++++++-------------------------
src/EWS/common/e-ews-connection.h | 4 +-
src/EWS/common/e-ews-request.c | 6 +-
src/EWS/common/e-soap-request.c | 157 +++++++-
src/EWS/common/e-soap-request.h | 29 ++
src/EWS/common/e-soap-response.c | 69 ++--
src/EWS/common/e-soap-response.h | 6 +
7 files changed, 473 insertions(+), 535 deletions(-)
---
diff --git a/src/EWS/common/e-ews-connection.c b/src/EWS/common/e-ews-connection.c
index f5a70f7d..ca442735 100644
--- a/src/EWS/common/e-ews-connection.c
+++ b/src/EWS/common/e-ews-connection.c
@@ -556,22 +556,38 @@ e_ews_connection_send_request_sync (EEwsConnection *cnc,
}
if (!local_error) {
- response = e_soap_response_new ();
+ ESoapRequestCustomProcessFn custom_process_fn = NULL;
+ gpointer custom_process_data = NULL;
- if (!e_soap_response_from_message_sync (response, message, input_stream, cancellable,
&local_error)) {
- g_clear_object (&response);
+ e_soap_request_get_custom_process_fn (request, &custom_process_fn,
&custom_process_data);
- if (!local_error) {
- g_set_error (&local_error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_NORESPONSE,
- _("No response: %s"), soup_message_get_reason_phrase
(messsage));
- }
- }
+ if (custom_process_fn) {
+ custom_process_fn (request, message, input_stream, custom_process_data,
&repeat, cancellable, &local_error);
+ } else {
+ ESoapResponseProgressFn progress_fn = NULL;
+ gpointer progress_data = NULL;
+
+ e_soap_request_get_progress_fn (request, &progress_fn, &progress_data);
+
+ response = e_soap_response_new ();
- if (response) {
- repeat = e_ews_connection_handle_backoff_policy (cnc, response, cancellable,
&local_error);
+ e_soap_response_set_progress_fn (request, progress_fn, progress_data);
- if (repeat || local_error)
+ if (!e_soap_response_from_message_sync (response, message, input_stream,
cancellable, &local_error)) {
g_clear_object (&response);
+
+ if (!local_error) {
+ g_set_error (&local_error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_NORESPONSE,
+ _("No response: %s"), soup_message_get_reason_phrase
(messsage));
+ }
+ }
+
+ if (response) {
+ repeat = e_ews_connection_handle_backoff_policy (cnc, response,
cancellable, &local_error);
+
+ if (repeat || local_error)
+ g_clear_object (&response);
+ }
}
}
@@ -579,7 +595,7 @@ e_ews_connection_send_request_sync (EEwsConnection *cnc,
g_clear_object (&message);
}
- if (local_error) {
+ if (local_error)
g_propagate_error (error, local_error);
if (response && cnc->priv->version == E_EWS_EXCHANGE_UNKNOWN) {
@@ -2675,14 +2691,12 @@ post_restarted (SoupMessage *msg,
);
}
-static SoupMessage *
-e_ews_get_msg_for_url (EEwsConnection *cnc,
- const gchar *url,
- xmlOutputBuffer *buf,
- GError **error)
+static ESoapRequest *
+e_ews_create_request_for_url (const gchar *url,
+ xmlOutputBuffer *buf,
+ GError **error)
{
- SoupMessage *msg;
- CamelEwsSettings *settings;
+ ESoapRequest *request;
if (url == NULL) {
g_set_error_literal (
@@ -2691,37 +2705,28 @@ e_ews_get_msg_for_url (EEwsConnection *cnc,
return NULL;
}
- msg = soup_message_new (buf != NULL ? "POST" : "GET", url);
- if (!msg) {
+ request = e_soap_request_new (buf ? SOUP_METHOD_POST : SOUP_METHOD_GET, uri, FALSE, NULL, NULL, NULL);
+ if (!request) {
g_set_error (
error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
_("URL ā%sā is not valid"), url);
return NULL;
}
- if (cnc->priv->source)
- e_soup_ssl_trust_connect (request, cnc->priv->source);
-
- settings = e_ews_connection_ref_settings (cnc);
- e_ews_connection_utils_set_user_agent_header (request, settings);
- g_clear_object (&settings);
-
- if (buf != NULL) {
- soup_message_set_request (
- msg, "text/xml; charset=utf-8", SOUP_MEMORY_COPY,
- (gchar *)
+ if (buf) {
+ e_soap_request_set_custom_body (request, "text/xml; charset=utf-8",
#ifdef LIBXML2_NEW_BUFFER
xmlOutputBufferGetContent (buf), xmlOutputBufferGetSize (buf)
#else
buf->buffer->content, buf->buffer->use
#endif
);
- g_signal_connect (
- msg, "restarted",
- G_CALLBACK (post_restarted), buf);
+ } else {
+ /* No body set for the GET request */
+ e_soap_request_set_custom_body (request, "", NULL, 0);
}
- return msg;
+ return request;
}
static void
@@ -2917,11 +2922,11 @@ e_ews_discover_prepare_messages_and_send (GSimpleAsyncResult *simple,
}
/* Passing a NULL URL string returns NULL. */
- ad->msgs[0] = e_ews_get_msg_for_url (ad->cnc, url1, ad->buf, &local_error);
- ad->msgs[1] = e_ews_get_msg_for_url (ad->cnc, url2, ad->buf, local_error ? NULL : &local_error);
- ad->msgs[2] = e_ews_get_msg_for_url (ad->cnc, url3, ad->buf, local_error ? NULL : &local_error);
- ad->msgs[3] = e_ews_get_msg_for_url (ad->cnc, url4, ad->buf, local_error ? NULL : &local_error);
- ad->msgs[4] = e_ews_get_msg_for_url (ad->cnc, url5, ad->buf, local_error ? NULL : &local_error);
+ ad->msgs[0] = e_ews_create_request_for_url (url1, ad->buf, &local_error);
+ ad->msgs[1] = e_ews_create_request_for_url (url2, ad->buf, local_error ? NULL : &local_error);
+ ad->msgs[2] = e_ews_create_request_for_url (url3, ad->buf, local_error ? NULL : &local_error);
+ ad->msgs[3] = e_ews_create_request_for_url (url4, ad->buf, local_error ? NULL : &local_error);
+ ad->msgs[4] = e_ews_create_request_for_url (url5, ad->buf, local_error ? NULL : &local_error);
if (!is_outlook && *domain && (ad->msgs[0] || ad->msgs[1] || ad->msgs[2] || ad->msgs[3] ||
ad->msgs[4])) {
gchar *tmp;
@@ -2929,7 +2934,7 @@ e_ews_discover_prepare_messages_and_send (GSimpleAsyncResult *simple,
tmp = g_strdup_printf ("http%s://%s/", use_secure ? "s" : "", domain);
/* Fake SoupMessage, for the autodiscovery with SRV record help */
- ad->msgs[5] = e_ews_get_msg_for_url (ad->cnc, tmp, ad->buf, local_error ? NULL :
&local_error);
+ ad->msgs[5] = e_ews_create_request_for_url (tmp, ad->buf, local_error ? NULL : &local_error);
if (ad->msgs[5]) {
g_resolver_lookup_service_async (g_resolver_get_default (), "autodiscover", "tcp",
domain, ad->cancellable,
@@ -3123,49 +3128,28 @@ e_ews_autodiscover_ws_url_finish (CamelEwsSettings *settings,
return TRUE;
}
-struct _oal_req_data {
- EEwsConnection *cnc;
- SoupMessage *soup_message;
- gchar *oal_id;
- gchar *oal_element;
+typedef struct _OalRequestData {
+ const gchar *oal_id;
+ const gchar *oal_element;
- GSList *oals;
- GSList *elements;
+ GSList *oals; /* EwsOAL * */
+ GSList *elements; /* EwsOALDetails */
gchar *etag;
-
- GCancellable *cancellable;
- gulong cancel_id;
-
- /* for dowloading oal file */
- gchar *cache_filename;
- GError *error;
- ESoapResponseProgressFn progress_fn;
- gpointer progress_data;
- gsize response_size;
- gsize received_size;
-};
+} OalRequestData;
static void
-oal_req_data_free (struct _oal_req_data *data)
+oal_request_data_init (OalRequestData *req_data)
{
- /* The SoupMessage is owned by the SoupSession. */
- g_object_unref (data->cnc);
-
- g_free (data->oal_id);
- g_free (data->oal_element);
- g_free (data->etag);
-
- g_slist_free_full (data->oals, (GDestroyNotify) ews_oal_free);
- g_slist_free_full (data->elements, (GDestroyNotify) ews_oal_details_free);
-
- if (data->cancellable != NULL) {
- g_cancellable_disconnect (data->cancellable, data->cancel_id);
- g_object_unref (data->cancellable);
- }
+ memset (req_data, 0, sizeof (OalRequestData));
+}
- g_free (data->cache_filename);
+static void
+oal_request_data_clear (OalRequestData *req_data)
+{
+ g_free (req_data->etag);
- g_slice_free (struct _oal_req_data, data);
+ g_slist_free_full (req_data->oals, (GDestroyNotify) ews_oal_free);
+ g_slist_free_full (req_data->elements, (GDestroyNotify) ews_oal_details_free);
}
static gchar *
@@ -3245,114 +3229,77 @@ parse_oal_full_details (xmlNode *node,
/* this is run in cnc->priv->soup_thread */
static void
-oal_response_cb (SoupSession *soup_session,
- SoupMessage *soup_message,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
- struct _oal_req_data *data;
+e_ews_process_oal_data_response (ESoupaRequest *request,
+ SoupMessage *message,
+ GInputStream *input_stream,
+ gpointer user_data,
+ gboolean *out_repeat,
+ GCancellable *cancellable,
+ GError **error)
+{
+ OalRequestData *req_data = user_data;
+ ESoapResponse *response;
+ ESoapResponseProgressFn progress_fn = NULL;
+ gpointer progress_data = NULL;
const gchar *etag;
xmlDoc *doc;
- xmlNode *node;
- simple = G_SIMPLE_ASYNC_RESULT (user_data);
- data = g_simple_async_result_get_op_res_gpointer (simple);
+ e_soap_request_get_progress_fn (request, &progress_fn, &progress_data);
- ews_connection_check_ssl_error (data->cnc, soup_message);
+ response = e_soap_response_new ();
- if (ews_connection_credentials_failed (data->cnc, soup_message, simple)) {
- goto exit;
- } else if (soup_message->status_code != SOUP_STATUS_OK) {
- if (soup_message->status_code == SOUP_STATUS_UNAUTHORIZED &&
- soup_message_get_response_headers (soup_message)) {
- const gchar *diagnostics;
-
- diagnostics = soup_message_headers_get_list (soup_message_get_response_headers
(soup_message), "X-MS-DIAGNOSTICS");
- if (diagnostics && strstr (diagnostics, "invalid_grant")) {
- g_simple_async_result_set_error (
- simple,
- EWS_CONNECTION_ERROR,
- EWS_CONNECTION_ERROR_ACCESSDENIED,
- "%s", diagnostics);
- goto exit;
- } else if (diagnostics && *diagnostics) {
- g_simple_async_result_set_error (
- simple,
- EWS_CONNECTION_ERROR,
- EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED,
- "%s", diagnostics);
- goto exit;
- }
- }
- g_simple_async_result_set_error (
- simple, E_SOUP_SESSION_ERROR,
- soup_message->status_code,
- "%d %s",
- soup_message->status_code,
- soup_message->reason_phrase);
- goto exit;
+ e_soap_response_set_progress_fn (request, progress_fn, progress_data);
+
+ doc = e_soap_response_xmldoc_from_message_sync (response, message, input_stream, cancellable, error);
+
+ g_clear_object (&response);
+
+ if (!doc) {
+ if (error && !*error)
+ g_set_error_literal (error, EWS_CONNECTION_ERROR, -1, _("Failed to parse oab XML"));
+ return;
}
etag = soup_message_headers_get_one (soup_message_get_response_headers (soup_message), "ETag");
if (etag)
- data->etag = g_strdup (etag);
-
- doc = xmlReadMemory (
- soup_message->response_body->data,
- soup_message->response_body->length,
- "oab.xml", NULL, 0);
- if (doc == NULL) {
- g_simple_async_result_set_error (
- simple, EWS_CONNECTION_ERROR, -1,
- "%s", _("Failed to parse oab XML"));
- goto exit;
- }
+ req_data->etag = g_strdup (etag);
node = xmlDocGetRootElement (doc);
- if (strcmp ((gchar *) node->name, "OAB") != 0) {
- g_simple_async_result_set_error (
- simple, EWS_CONNECTION_ERROR, -1,
- "%s", _("Failed to find <OAB> element\n"));
- goto exit_doc;
- }
+ if (strcmp ((gchar *) node->name, "OAB") == 0) {
+ xmlNode *node;
- for (node = node->children; node; node = node->next) {
- if (node->type == XML_ELEMENT_NODE && strcmp ((gchar *) node->name, "OAL") == 0) {
- if (data->oal_id == NULL) {
- EwsOAL *oal = g_new0 (EwsOAL, 1);
+ for (node = node->children; node; node = node->next) {
+ if (node->type == XML_ELEMENT_NODE && strcmp ((gchar *) node->name, "OAL") == 0) {
+ if (req_data->oal_id == NULL) {
+ EwsOAL *oal = g_new0 (EwsOAL, 1);
- oal->id = get_property (node, "id");
- oal->dn = get_property (node, "dn");
- oal->name = get_property (node, "name");
+ oal->id = get_property (node, "id");
+ oal->dn = get_property (node, "dn");
+ oal->name = get_property (node, "name");
- data->oals = g_slist_prepend (data->oals, oal);
- } else {
- gchar *id = get_property (node, "id");
+ req_data->oals = g_slist_prepend (req_data->oals, oal);
+ } else {
+ gchar *id = get_property (node, "id");
+
+ if (strcmp (id, req_data->oal_id) == 0) {
+ /* parse details of full_details file */
+ req_data->elements = parse_oal_full_details (node,
req_data->oal_element);
- if (strcmp (id, data->oal_id) == 0) {
- /* parse details of full_details file */
- data->elements = parse_oal_full_details (node, data->oal_element);
+ g_free (id);
+ break;
+ }
g_free (id);
- break;
}
-
- g_free (id);
}
}
- }
- data->oals = g_slist_reverse (data->oals);
+ req_data->oals = g_slist_reverse (req_data->oals);
+ } else {
+ g_set_error_literal (error, EWS_CONNECTION_ERROR, -1, _("Failed to find <OAB> element\n"));
+ }
- exit_doc:
xmlFreeDoc (doc);
- exit:
- g_simple_async_result_complete_in_idle (simple);
- /* This is run in cnc->priv->soup_thread, and the cnc is held by simple, thus
- * for cases when the complete_in_idle is finished before the unref call, when
- * the cnc will be left with the last reference and thus cannot join the soup_thread
- * while still in it, the unref is done in a dedicated thread. */
- e_ews_connection_utils_unref_in_thread (simple);
}
static void
@@ -3364,109 +3311,43 @@ ews_cancel_msg (GCancellable *cancellable,
gboolean
e_ews_connection_get_oal_list_sync (EEwsConnection *cnc,
- GSList **oals,
+ GSList **out_oals,
GCancellable *cancellable,
GError **error)
{
ESoapRequest *request;
ESoapResponse *response;
- gboolean success;
+ OalRequestData req_data;
+ GError *local_error = NULL;
g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (out_oals != NULL, FALSE);
- closure = e_async_closure_new ();
+ *out_oals = NULL;
- e_ews_connection_get_oal_list (
- cnc, cancellable, e_async_closure_callback, closure);
+ request = e_ews_create_request_for_url (cnc->priv->uri, NULL, error);
- result = e_async_closure_wait (closure);
+ if (!request)
+ return FALSE;
- success = e_ews_connection_get_oal_list_finish (
- cnc, result, oals, error);
+ oal_request_data_init (&req_data);
- response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
-
- if (!response) {
- g_clear_object (&request);
- return FALSE;
- }
+ e_soap_request_set_custom_process_fn (request, e_ews_process_oal_data_response, &req_data);
- success = e_ews_process__response (cnc, response, , error);
+ response = e_ews_connection_send_request_sync (cnc, request, cancellable, &local_error);
+ g_warn_if_fail (response == NULL);
g_clear_object (&request);
g_clear_object (&response);
- return success;
-}
-
-void
-e_ews_connection_get_oal_list (EEwsConnection *cnc,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
- SoupMessage *soup_message;
- struct _oal_req_data *data;
- GError *error = NULL;
-
- g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+ if (!local_error)
+ *out_oals = g_steal_pointer (&req_data.oals);
- soup_message = e_ews_get_msg_for_url (cnc, cnc->priv->uri, NULL, &error);
+ oal_req_data_clear (&req_data);
- simple = g_simple_async_result_new (
- G_OBJECT (cnc), callback, user_data,
- e_ews_connection_get_oal_list);
-
- if (!soup_message) {
+ if (local_error) {
g_propagate_error (error, local_error);
- g_simple_async_result_complete_in_idle (simple);
- return;
- }
-
- data = g_slice_new0 (struct _oal_req_data);
- data->cnc = g_object_ref (cnc);
- data->soup_message = soup_message; /* the session owns this */
-
- if (G_IS_CANCELLABLE (cancellable)) {
- data->cancellable = g_object_ref (cancellable);
- data->cancel_id = g_cancellable_connect (
- data->cancellable,
- G_CALLBACK (ews_cancel_msg),
- data, (GDestroyNotify) NULL);
- }
-
- g_simple_async_result_set_op_res_gpointer (
- simple, data, (GDestroyNotify) oal_req_data_free);
-
- ews_connection_schedule_queue_message (cnc, soup_message, oal_response_cb, simple);
-}
-
-gboolean
-e_ews_connection_get_oal_list_finish (EEwsConnection *cnc,
- GAsyncResult *result,
- GSList **oals,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- struct _oal_req_data *data;
-
- g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-
- g_return_val_if_fail (
- g_simple_async_result_is_valid (
- result, G_OBJECT (cnc), e_ews_connection_get_oal_list),
- FALSE);
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- data = g_simple_async_result_get_op_res_gpointer (simple);
-
- if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
-
- if (oals != NULL) {
- *oals = data->oals;
- data->oals = NULL;
}
return TRUE;
@@ -3484,184 +3365,63 @@ e_ews_connection_get_oal_detail_sync (EEwsConnection *cnc,
{
ESoapRequest *request;
ESoapResponse *response;
- gboolean success;
+ OalRequestData req_data;
+ gchar *tmp_oal_id = NULL;
+ GError *local_error = NULL;
g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (oal_id, FALSE);
- closure = e_async_closure_new ();
-
- e_ews_connection_get_oal_detail (
- cnc, oal_id, oal_element, old_etag,
- cancellable, e_async_closure_callback, closure);
+ if (out_elements)
+ *out_elements = NULL;
+ if (out_etag)
+ *out_etag = NULL;
- result = e_async_closure_wait (closure);
+ request = e_ews_create_request_for_url (cnc->priv->uri, NULL, error);
- success = e_ews_connection_get_oal_detail_finish (
- cnc, result, elements, etag, error);
-
- response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
-
- if (!response) {
- g_clear_object (&request);
+ if (!request)
return FALSE;
- }
-
- success = e_ews_process__response (cnc, response, , error);
-
- g_clear_object (&request);
- g_clear_object (&response);
-
- return success;
-}
-
-void
-e_ews_connection_get_oal_detail (EEwsConnection *cnc,
- const gchar *oal_id,
- const gchar *oal_element,
- const gchar *etag,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
- SoupMessage *soup_message;
- struct _oal_req_data *data;
- gchar *sep;
- GError *error = NULL;
-
- g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
-
- soup_message = e_ews_get_msg_for_url (cnc, cnc->priv->uri, NULL, &error);
-
- simple = g_simple_async_result_new (
- G_OBJECT (cnc), callback, user_data,
- e_ews_connection_get_oal_detail);
-
- if (!soup_message) {
- g_propagate_error (error, local_error);
- g_simple_async_result_complete_in_idle (simple);
- return;
- }
-
- if (etag && *etag)
- soup_message_headers_replace (soup_message_get_request_headers (soup_message),
- "If-None-Match", etag);
-
- data = g_slice_new0 (struct _oal_req_data);
- data->cnc = g_object_ref (cnc);
- data->soup_message = soup_message; /* the session owns this */
- data->oal_id = g_strdup (oal_id);
- data->oal_element = g_strdup (oal_element);
/* oal_id can be of form "GUID:name", but here is compared only GUID */
- sep = strchr (data->oal_id, ':');
- if (sep)
- *sep = '\0';
+ if (strchr (oal_id, ':')) {
+ gchar *sep;
- if (G_IS_CANCELLABLE (cancellable)) {
- data->cancellable = g_object_ref (cancellable);
- data->cancel_id = g_cancellable_connect (
- data->cancellable,
- G_CALLBACK (ews_cancel_msg),
- data, (GDestroyNotify) NULL);
+ tmp_oal_id = g_strdup (oal_id);
+ sep = strchr (tmp_oal_id, ':');
+ if (sep)
+ *sep = '\0';
}
- g_simple_async_result_set_op_res_gpointer (
- simple, data, (GDestroyNotify) oal_req_data_free);
-
- ews_connection_schedule_queue_message (cnc, soup_message, oal_response_cb, simple);
-}
+ oal_request_data_init (&req_data);
-gboolean
-e_ews_connection_get_oal_detail_finish (EEwsConnection *cnc,
- GAsyncResult *result,
- GSList **elements,
- gchar **etag,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- struct _oal_req_data *data;
+ req_data.oal_id = tmp_oal_id ? tmp_oal_id : oal_id;
+ req_data.oal_element = oal_element;
- g_return_val_if_fail (cnc != NULL, FALSE);
- g_return_val_if_fail (
- g_simple_async_result_is_valid (
- result, G_OBJECT (cnc), e_ews_connection_get_oal_detail),
- FALSE);
+ e_soap_request_set_custom_process_fn (request, e_ews_process_oal_data_response, &req_data);
+ e_soap_request_set_etag (request, old_etag);
- simple = G_SIMPLE_ASYNC_RESULT (result);
- data = g_simple_async_result_get_op_res_gpointer (simple);
+ response = e_ews_connection_send_request_sync (cnc, request, cancellable, &local_error);
+ g_warn_if_fail (response == NULL);
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
+ g_clear_object (&request);
+ g_clear_object (&response);
+ g_free (tmp_oal_id);
- if (elements != NULL) {
- *elements = data->elements;
- data->elements = NULL;
- }
- if (etag != NULL) {
- *etag = data->etag;
- data->etag = NULL;
+ if (!local_error) {
+ if (out_elements)
+ *out_elements = g_steal_pointer (&req_data.elements);
+ if (out_etag)
+ *out_etag = g_steal_pointer (&req_data.etag);
}
- return TRUE;
+ oal_req_data_clear (&req_data);
-}
-
-static void
-oal_download_response_cb (SoupSession *soup_session,
- SoupMessage *soup_message,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
- struct _oal_req_data *data;
-
- simple = G_SIMPLE_ASYNC_RESULT (user_data);
- data = g_simple_async_result_get_op_res_gpointer (simple);
-
- ews_connection_check_ssl_error (data->cnc, soup_message);
-
- if (ews_connection_credentials_failed (data->cnc, soup_message, simple)) {
- g_unlink (data->cache_filename);
- } else if (soup_message->status_code != SOUP_STATUS_OK) {
- g_simple_async_result_set_error (
- simple, E_SOUP_SESSION_ERROR,
- soup_message->status_code,
- "%d %s",
- soup_message->status_code,
- soup_message->reason_phrase);
- g_unlink (data->cache_filename);
-
- } else if (data->error != NULL) {
- g_simple_async_result_take_error (simple, data->error);
- data->error = NULL;
- g_unlink (data->cache_filename);
+ if (local_error) {
+ g_propagate_error (error, local_error);
+ return FALSE;
}
- g_simple_async_result_complete_in_idle (simple);
- e_ews_connection_utils_unref_in_thread (simple);
-}
-
-static void
-ews_soup_got_headers (SoupMessage *msg,
- gpointer user_data)
-{
- struct _oal_req_data *data = (struct _oal_req_data *) user_data;
- const gchar *size;
-
- size = soup_message_headers_get_one (soup_message_get_response_headers (request), "Content-Length");
-
- if (size)
- data->response_size = strtol (size, NULL, 10);
-}
-
-static void
-ews_soup_restarted (SoupMessage *msg,
- gpointer user_data)
-{
- struct _oal_req_data *data = (struct _oal_req_data *) user_data;
-
- data->response_size = 0;
- data->received_size = 0;
+ return TRUE;
}
static void
@@ -3697,6 +3457,66 @@ ews_soup_got_chunk (SoupMessage *msg,
}
}
+typedef struct _DownloadOalData {
+ const gchar *cache_filename;
+ gint fd;
+} DownloadOalData;
+
+#define BUFFER_SIZE 16384
+
+static void
+e_ews_process_download_oal_file_response (ESoupaRequest *request,
+ SoupMessage *message,
+ GInputStream *input_stream,
+ gpointer user_data,
+ gboolean *out_repeat,
+ GCancellable *cancellable,
+ GError **error)
+{
+ DownloadOalData *dod = user_data;
+ ESoapResponseProgressFn progress_fn = NULL;
+ gpointer progress_data = NULL;
+ const gchar *size;
+ gpointer buffer;
+ gsize response_size = 0;
+ gsize response_received = 0;
+ gsize progress_percent = 0;
+ gsize nread = 0;
+
+ g_return_if_fail (dod != NULL);
+ g_return_if_fail (dod->fd != -1);
+
+ e_soap_request_get_progress_fn (request, &progress_fn, &progress_data);
+
+ size = soup_message_headers_get_one (soup_message_get_response_headers (soup_msg), "Content-Length");
+
+ if (size)
+ response_size = g_ascii_strtoll (size, NULL, 10);
+
+ buffer = g_malloc (BUFFER_SIZE);
+
+ while (success = g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &nread, cancellable,
error),
+ success && nread > 0) {
+ response_received += nread;
+
+ if (response_size && progress_fn) {
+ gint pc = response_received * 100 / response_size;
+ if (progress_percent != pc) {
+ progress_percent = pc;
+ progress_fn (progress_data, progress_percent);
+ }
+ }
+
+ if (write (dod->fd, (const gchar *) buffer, nread) != nread) {
+ g_set_error (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_UNKNOWN,
+ "Failed to write streaming data to file '%s': %s", dod->cache_filename,
g_strerror (errno));
+ break;
+ }
+ }
+
+ g_free (buffer);
+}
+
gboolean
e_ews_connection_download_oal_file_sync (EEwsConnection *cnc,
const gchar *cache_filename,
@@ -3707,113 +3527,46 @@ e_ews_connection_download_oal_file_sync (EEwsConnection *cnc,
{
ESoapRequest *request;
ESoapResponse *response;
- gboolean success;
+ DownloadOalData dod;
+ GError *local_error = NULL;
g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
- closure = e_async_closure_new ();
+ request = e_ews_create_request_for_url (cnc->priv->uri, NULL, error);
- e_ews_connection_download_oal_file (
- cnc, cache_filename,
- progress_fn, progress_data, cancellable,
- e_async_closure_callback, closure);
-
- result = e_async_closure_wait (closure);
-
- success = e_ews_connection_download_oal_file_finish (
- cnc, result, error);
+ if (!request)
+ return FALSE;
- response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+ /* Prepare the file */
+ g_unlink (cache_filename);
- if (!response) {
+ dod.cache_filename = cache_filename;
+ dod.fd = g_open (data->cache_filename, O_RDONLY | O_WRONLY | O_APPEND | O_CREAT, 0600);
+ if (dod.fd == -1) {
+ g_set_error (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_UNKNOWN,
+ "Failed to open the cache file '%s': %s", cache_filename, g_strerror (errno));
g_clear_object (&request);
+
return FALSE;
}
- success = e_ews_process__response (cnc, response, , error);
+ e_soap_request_set_progress_fn (request, progress_fn, progress_data);
- g_clear_object (&request);
- g_clear_object (&response);
+ e_soap_request_set_custom_process_fn (request, e_ews_process_download_oal_file_response, &dod);
- return success;
-}
+ response = e_ews_connection_send_request_sync (cnc, request, cancellable, &local_error);
+ g_warn_if_fail (response == NULL);
-void
-e_ews_connection_download_oal_file (EEwsConnection *cnc,
- const gchar *cache_filename,
- ESoapResponseProgressFn progress_fn,
- gpointer progress_data,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
- SoupMessage *soup_message;
- struct _oal_req_data *data;
- GError *error = NULL;
-
- g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
-
- soup_message = e_ews_get_msg_for_url (cnc, cnc->priv->uri, NULL, &error);
-
- simple = g_simple_async_result_new (
- G_OBJECT (cnc), callback, user_data,
- e_ews_connection_download_oal_file);
+ g_clear_object (&request);
+ g_clear_object (&response);
+ close (dod.fd);
- if (!soup_message) {
+ if (local_error) {
g_propagate_error (error, local_error);
- g_simple_async_result_complete_in_idle (simple);
- return;
- }
-
- data = g_slice_new0 (struct _oal_req_data);
- data->cnc = g_object_ref (cnc);
- data->soup_message = soup_message; /* the session owns this */
- data->cache_filename = g_strdup (cache_filename);
- data->progress_fn = progress_fn;
- data->progress_data = progress_data;
-
- if (G_IS_CANCELLABLE (cancellable)) {
- data->cancellable = g_object_ref (cancellable);
- data->cancel_id = g_cancellable_connect (
- data->cancellable,
- G_CALLBACK (ews_cancel_msg),
- data, (GDestroyNotify) NULL);
+ return FALSE;
}
- g_simple_async_result_set_op_res_gpointer (
- simple, data, (GDestroyNotify) oal_req_data_free);
-
- g_signal_connect (
- soup_message, "got-headers",
- G_CALLBACK (ews_soup_got_headers), data);
- g_signal_connect (
- soup_message, "got-chunk",
- G_CALLBACK (ews_soup_got_chunk), data);
- g_signal_connect (
- soup_message, "restarted",
- G_CALLBACK (ews_soup_restarted), data);
-
- ews_connection_schedule_queue_message (cnc, soup_message, oal_download_response_cb, simple);
-}
-
-gboolean
-e_ews_connection_download_oal_file_finish (EEwsConnection *cnc,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple;
-
- g_return_val_if_fail (cnc != NULL, FALSE);
- g_return_val_if_fail (
- g_simple_async_result_is_valid (
- result, G_OBJECT (cnc),
- e_ews_connection_download_oal_file), FALSE);
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- /* Assume success unless a GError is set. */
- return !g_simple_async_result_propagate_error (simple, error);
+ return TRUE;
}
const gchar *
diff --git a/src/EWS/common/e-ews-connection.h b/src/EWS/common/e-ews-connection.h
index 6776a0e6..7380e046 100644
--- a/src/EWS/common/e-ews-connection.h
+++ b/src/EWS/common/e-ews-connection.h
@@ -728,7 +728,7 @@ gboolean e_ews_connection_get_attachments_sync
GError **error);
gboolean e_ews_connection_get_oal_list_sync
(EEwsConnection *cnc,
- GSList **out_oals,
+ GSList **out_oals, /* EwsOAL * */
GCancellable *cancellable,
GError **error);
gboolean e_ews_connection_get_oal_detail_sync
@@ -736,7 +736,7 @@ gboolean e_ews_connection_get_oal_detail_sync
const gchar *oal_id,
const gchar *oal_element,
const gchar *old_etag,
- GSList **out_elements,
+ GSList **out_elements, /* EwsOALDetails * */
gchar **out_etag,
GCancellable *cancellable,
GError **error);
diff --git a/src/EWS/common/e-ews-request.c b/src/EWS/common/e-ews-request.c
index ffa20d05..26dcfb30 100644
--- a/src/EWS/common/e-ews-request.c
+++ b/src/EWS/common/e-ews-request.c
@@ -57,15 +57,13 @@ e_ews_request_new_with_header (CamelEwsSettings *settings,
const gchar *attribute_value,
EEwsServerVersion server_version,
EEwsServerVersion minimum_version,
- gboolean force_minimum_version,
- gboolean standard_handlers)
+ gboolean force_minimum_version)
{
ESoapRequest *req;
const gchar *server_ver;
EEwsServerVersion version;
- req = e_soap_request_new (
- SOUP_METHOD_POST, uri, FALSE, NULL, NULL, NULL, standard_handlers);
+ req = e_soap_request_new (SOUP_METHOD_POST, uri, FALSE, NULL, NULL, NULL);
if (req == NULL) {
g_warning ("%s: Could not build SOAP message for uri '%s'", G_STRFUNC, uri);
return NULL;
diff --git a/src/EWS/common/e-soap-request.c b/src/EWS/common/e-soap-request.c
index 6e55ac76..9acda9dd 100644
--- a/src/EWS/common/e-soap-request.c
+++ b/src/EWS/common/e-soap-request.c
@@ -23,6 +23,18 @@ struct _ESoapRequestPrivate {
gchar *method;
GUri *uri;
+ ESoapResponseProgressFn progress_fn;
+ gpointer progress_data;
+
+ ESoapRequestCustomProcessFn custom_process_fn;
+ gpointer custom_process_data;
+
+ gchar *custom_body_content_type;
+ gpointer custom_body_data;
+ gssize custom_body_data_len;
+
+ gchar *etag;
+
gchar *certificate_pem;
GTlsCertificateFlags certificate_errors;
@@ -47,6 +59,9 @@ soap_request_finalize (GObject *object)
g_clear_pointer (&req->priv->method, g_free);
g_clear_pointer (&req->priv->uri, g_uri_unref);
+ g_clear_pointer (&req->priv->custom_body_content_type, g_free);
+ g_clear_pointer (&req->priv->custom_body_data, g_free);
+ g_clear_pointer (&req->priv->etag, g_free);
g_clear_pointer (&req->priv->certificate_pem, g_free);
g_clear_pointer (&req->priv->doc, xmlFreeDoc);
@@ -854,6 +869,30 @@ e_soap_request_get_xml_doc (ESoapRequest *req)
return req->priv->doc;
}
+void
+e_soap_request_set_progress_fn (ESoapRequest *req,
+ ESoapResponseProgressFn fn,
+ gpointer user_data)
+{
+ g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+ req->priv->progress_fn = fn;
+ req->priv->progress_data = user_data;
+}
+
+void
+e_soap_request_get_progress_fn (ESoapRequest *req,
+ ESoapResponseProgressFn *out_fn,
+ gpointer *out_user_data)
+{
+ g_return_if_fail (E_IS_SOAP_REQUEST (req));
+ g_return_if_fail (out_fn != NULL);
+ g_return_if_fail (out_user_data != NULL);
+
+ *out_fn = req->priv->progress_fn;
+ *out_user_data = req->priv->progress_data;
+}
+
/**
* e_soap_request_persist:
* @req: the #ESoapRequest.
@@ -863,6 +902,9 @@ e_soap_request_get_xml_doc (ESoapRequest *req)
*
* Writes the serialized XML tree to the #SoupMessage's buffer.
*
+ * When a custom body was set with e_soap_request_set_custom_body(), then that body
+ * is used instead.
+ *
* Returns: (nullable) (transfer full): a #SoupMessage containing the SOAP request
* as its request body, or %NULL on error.
*/
@@ -873,30 +915,105 @@ e_soap_request_persist (ESoapRequest *req,
GError **error)
{
SoupMessage *message;
- xmlChar *body;
- gint len;
- g_return_if_fail (E_IS_SOAP_REQUEST (req));
+ g_return_val_if_fail (E_IS_SOAP_REQUEST (req), NULL);
message = e_soup_session_new_message_from_uri (soup_session, req->priv->method, req->priv->uri,
error);
if (!message)
return NULL;
- xmlDocDumpMemory (req->priv->doc, &body, &len);
-
- e_soup_session_util_set_message_request_body_from_data (message, FALSE,
- "text/xml; charset=utf-8", body, len, (GDestroyNotify) xmlFree);
+ if (req->priv->custom_body_content_type) {
+ /* Can use empty string as content_type to indicate no body to be set */
+ if (*req->priv->custom_body_content_type && req->priv->custom_body_data) {
+ e_soup_session_util_set_message_request_body_from_data (message, TRUE,
+ req->priv->custom_body_content_type,
+ req->priv->custom_body_data,
+ req->priv->custom_body_data_len, NULL);
+ }
+ } else {
+ xmlChar *body;
+ gint len;
+
+ xmlDocDumpMemory (req->priv->doc, &body, &len);
+
+ e_soup_session_util_set_message_request_body_from_data (message, FALSE,
+ "text/xml; charset=utf-8", body, len, (GDestroyNotify) xmlFree);
+ }
e_ews_connection_utils_set_user_agent_header (message, settings);
- soup_message_headers_replace (
- soup_message_get_request_headers (message),
- "Connection", "Keep-Alive");
+ soup_message_headers_replace (soup_message_get_request_headers (message), "Connection", "Keep-Alive");
+
+ if (req->priv->etag && *req->priv->etag)
+ soup_message_headers_replace (soup_message_get_request_headers (soup_message),
"If-None-Match", req->priv->etag);
return message;
}
+/**
+ * e_soap_request_set_custom_body:
+ * @req: the #ESoapRequest.
+ * @content_type: (optional): content type of the custom body
+ * @body: (optional): the custom message body, or %NULL; ignored when @content_type is %NULL
+ * @body_len: length of the @body; ignored when @content_type is %NULL
+ *
+ * Stores custom body for the request, to be used instead of the SOAP @req content.
+ * The @content_type can be %NULL to unset the custom body, or an empty string to indicate
+ * no body should be set. The @body and @body_len parameters are ignored in these cases,
+ * otherwise they are required.
+ *
+ * This function exists only to make internal API simpler.
+ **/
+void
+e_soap_request_set_custom_body (ESoapRequest *req,
+ const gchar *content_type,
+ gconstpointer body,
+ gsize body_len)
+{
+ g_return_val_if_fail (E_IS_SOAP_REQUEST (req), NULL);
+
+ if (content_type && *content_type)
+ g_return_val_if_fail (body != NULL, NULL);
+
+ g_clear_pointer (&req->priv->custom_body_content_type, g_free);
+ g_clear_pointer (&req->priv->custom_body_data, g_free);
+ req->priv->custom_body_data_len = 0;
+
+ if (content_type) {
+ req->priv->custom_body_content_type = g_strdup (req->priv->custom_body_content_type);
+
+ if (*content_type) {
+ req->priv->custom_body_data = g_memdup2 (body, body_len);
+ req->priv->custom_body_data_len = body_len;
+ }
+ }
+}
+
+void
+e_soap_request_set_custom_process_fn (ESoapRequest *req,
+ ESoapRequestCustomProcessFn fn,
+ gpointer user_data)
+{
+ g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+ req->priv->custom_process_fn = fn;
+ req->priv->custom_process_data = user_data;
+}
+
+void
+e_soap_request_get_custom_process_fn (ESoapRequest *req,
+ ESoapRequestCustomProcessFn *out_fn,
+ gpointer *out_user_data)
+{
+ g_return_if_fail (E_IS_SOAP_REQUEST (req));
+ g_return_if_fail (out_fn != NULL);
+ g_return_if_fail (out_user_data != NULL);
+
+ *out_fn = req->priv->custom_process_fn;
+ *out_user_data = req->priv->custom_process_data;
+}
+
/**
* e_soap_request_take_tls_error_details:
* @req: an #ESoapRequest
@@ -952,3 +1069,23 @@ e_soap_request_get_tls_error_details (ESoapRequest *req,
return TRUE;
}
+
+void
+e_soap_request_set_etag (ESoapRequest *req,
+ const gchar *etag)
+{
+ g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+ if (g_strcmp0 (req->priv->etag, etag) != 0) {
+ g_clear_pointer (&req->priv->etag, g_free);
+ req->priv->etag = g_strdup ((etag && *etag) ? etag : NULL);
+ }
+}
+
+const gchar *
+e_soap_request_get_etag (ESoapRequest *req)
+{
+ g_return_val_if_fail (E_IS_SOAP_REQUEST (req), NULL);
+
+ return req->priv->etag;
+}
diff --git a/src/EWS/common/e-soap-request.h b/src/EWS/common/e-soap-request.h
index d716f1a0..e3ac9894 100644
--- a/src/EWS/common/e-soap-request.h
+++ b/src/EWS/common/e-soap-request.h
@@ -35,6 +35,14 @@
G_BEGIN_DECLS
+typedef gboolean (* ESoapRequestCustomProcessFn) (ESoupaRequest *request,
+ SoupMessage *message,
+ GInputStream *input_stream,
+ gpointer user_data,
+ gboolean *out_repeat,
+ GCancellable *cancellable,
+ GError **error);
+
typedef struct _ESoapRequest ESoapRequest;
typedef struct _ESoapRequestClass ESoapRequestClass;
typedef struct _ESoapRequestPrivate ESoapRequestPrivate;
@@ -128,10 +136,28 @@ const gchar * e_soap_request_get_namespace_prefix
(ESoapRequest *req,
const gchar *ns_uri);
xmlDocPtr e_soap_request_get_xml_doc (ESoapRequest *req);
+void e_soap_request_set_progress_fn (ESoapRequest *req,
+ ESoapResponseProgressFn fn,
+ gpointer user_data);
+void e_soap_request_get_progress_fn (ESoapRequest *req,
+ ESoapResponseProgressFn *out_fn,
+ gpointer *out_user_data);
SoupMessage * e_soap_request_persist (ESoapRequest *req,
ESoupSession *soup_session,
CamelEwsSettings *settings,
GError **error);
+void e_soap_request_set_custom_body (ESoapRequest *req,
+ const gchar *content_type,
+ gconstpointer body,
+ gssize body_len);
+void e_soap_request_set_custom_process_fn
+ (ESoapRequest *req,
+ ESoapRequestCustomProcessFn fn,
+ gpointer user_data);
+void e_soap_request_get_custom_process_fn
+ (ESoapRequest *req,
+ ESoapRequestCustomProcessFn *out_fn,
+ gpointer *out_user_data);
void e_soap_request_take_tls_error_details
(ESoapRequest *req,
gchar *certificate_pem,
@@ -140,6 +166,9 @@ gboolean e_soap_request_get_tls_error_details
(ESoapRequest *req,
const gchar **out_certificate_pem,
GTlsCertificateFlags *out_certificate_errors);
+void e_soap_request_set_etag (ESoapRequest *req,
+ const gchar *etag);
+const gchar * e_soap_request_get_etag (ESoapRequest *req);
G_END_DECLS
diff --git a/src/EWS/common/e-soap-response.c b/src/EWS/common/e-soap-response.c
index 911fe6a5..609d36bb 100644
--- a/src/EWS/common/e-soap-response.c
+++ b/src/EWS/common/e-soap-response.c
@@ -33,9 +33,6 @@ struct _ESoapResponsePrivate {
gint steal_fd;
/* Progress callbacks */
- gsize response_size;
- gsize response_received;
- gsize progress_percent;
ESoapProgressFn progress_fn;
gpointer progress_data;
};
@@ -378,26 +375,26 @@ soap_sax_characters (gpointer _ctxt,
#define BUFFER_SIZE 16384
-gboolean
-e_soap_response_from_message_sync (ESoapResponse *response,
- SoupMessage *msg,
- GInputStream *response_data,
- GCancellable *cancellable,
- GError **error)
+xmlDoc *
+e_soap_response_xmldoc_from_message_sync (ESoapResponse *response,
+ SoupMessage *msg,
+ GInputStream *response_data,
+ GCancellable *cancellable,
+ GError **error)
{
const gchar *size;
+ xmlDoc xmldoc = NULL;
gboolean success;
gpointer buffer;
+ gsize response_size = 0;
+ gsize response_received = 0;
+ gsize progress_percent = 0;
gsize nread = 0;
g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), FALSE);
g_return_val_if_fail (SOAP_IS_MESSAGE (msg), FALSE);
g_return_val_if_fail (G_IS_INPUT_STREAM (response_data), FALSE);
- response->priv->response_size = 0;
- response->priv->response_received = 0;
- response->priv->progress_percent = 0;
-
/* Discard the existing context, if there is one, and start again */
if (response->priv->ctxt) {
if (response->priv->ctxt->myDoc)
@@ -414,19 +411,19 @@ e_soap_response_from_message_sync (ESoapResponse *response,
size = soup_message_headers_get_one (soup_message_get_response_headers (soup_msg), "Content-Length");
if (size)
- req->priv->response_size = g_ascii_strtoll (size, NULL, 10);
+ response_size = g_ascii_strtoll (size, NULL, 10);
buffer = g_malloc (BUFFER_SIZE);
while (success = g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &nread, cancellable,
error),
success && nread > 0) {
- response->priv->response_received += nread;
+ response_received += nread;
- if (response->priv->response_size && response->priv->progress_fn) {
- gint pc = response->priv->response_received * 100 / response->priv->response_size;
- if (response->priv->progress_percent != pc) {
- response->priv->progress_percent = pc;
- response->priv->progress_fn (response->priv->progress_data,
response->priv->progress_percent);
+ if (response_size && response->priv->progress_fn) {
+ gint pc = response_received * 100 / response_size;
+ if (progress_percent != pc) {
+ progress_percent = pc;
+ response->priv->progress_fn (response->priv->progress_data, progress_percent);
}
}
@@ -453,13 +450,6 @@ e_soap_response_from_message_sync (ESoapResponse *response,
xmlFreeParserCtxt (response->priv->ctxt);
response->priv->ctxt = NULL;
-
- if (xmldoc) {
- success = e_soap_response_from_xmldoc (response, xmldoc);
- if (!success)
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
"Received invalid SOAP response");
- } else
- succeess = FALSE;
} else {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "No data read");
success = FALSE;
@@ -478,6 +468,31 @@ e_soap_response_from_message_sync (ESoapResponse *response,
response->priv->steal_fd = -1;
}
+ return xmldoc;
+}
+
+gboolean
+e_soap_response_from_message_sync (ESoapResponse *response,
+ SoupMessage *msg,
+ GInputStream *response_data,
+ GCancellable *cancellable,
+ GError **error)
+{
+ xmlDoc *xmldoc;
+ gboolean successs = FALSE;
+
+ g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), FALSE);
+ g_return_val_if_fail (SOAP_IS_MESSAGE (msg), FALSE);
+ g_return_val_if_fail (G_IS_INPUT_STREAM (response_data), FALSE);
+
+ xmldoc = e_soap_response_xmldoc_from_message_sync (response, msg, response_data, cancellable, error);
+
+ if (xmldoc) {
+ success = e_soap_response_from_xmldoc (response, xmldoc);
+ if (!success)
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Received invalid
SOAP response");
+ }
+
return success;
}
diff --git a/src/EWS/common/e-soap-response.h b/src/EWS/common/e-soap-response.h
index 6849a962..122067f4 100644
--- a/src/EWS/common/e-soap-response.h
+++ b/src/EWS/common/e-soap-response.h
@@ -64,6 +64,12 @@ gboolean e_soap_response_from_message_sync
GInputStream *response_data,
GCancellable *cancellable,
GError **error);
+xmlDoc * e_soap_response_xmldoc_from_message_sync
+ (ESoapResponse *response,
+ SoupMessage *msg,
+ GInputStream *response_data,
+ GCancellable *cancellable,
+ GError **error);
/* used only with e_soap_response_from_message_sync() */
void e_soap_response_store_node_data (ESoapResponse *response,
const gchar *nodename,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]