[evolution-data-server/gnome-3-34] I#145 - WebDAV: Not every 403/Forbidden means wrong credentials
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-3-34] I#145 - WebDAV: Not every 403/Forbidden means wrong credentials
- Date: Mon, 9 Sep 2019 09:54:44 +0000 (UTC)
commit 95435817f6d5da565d242dab766ef06a2960c7f0
Author: Milan Crha <mcrha redhat com>
Date: Mon Sep 9 11:54:41 2019 +0200
I#145 - WebDAV: Not every 403/Forbidden means wrong credentials
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/145
.../backends/carddav/e-book-backend-carddav.c | 22 +-
.../backends/caldav/e-cal-backend-caldav.c | 22 +-
src/libedataserver/e-webdav-session.c | 231 +++++++++++++++------
src/libedataserver/e-webdav-session.h | 3 +
4 files changed, 213 insertions(+), 65 deletions(-)
---
diff --git a/src/addressbook/backends/carddav/e-book-backend-carddav.c
b/src/addressbook/backends/carddav/e-book-backend-carddav.c
index 3509229ea..979899a1e 100644
--- a/src/addressbook/backends/carddav/e-book-backend-carddav.c
+++ b/src/addressbook/backends/carddav/e-book-backend-carddav.c
@@ -616,17 +616,33 @@ ebb_carddav_check_credentials_error (EBookBackendCardDAV *bbdav,
op_error->code = E_CLIENT_ERROR_TLS_NOT_AVAILABLE;
} else if (g_error_matches (op_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
g_error_matches (op_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN)) {
+ gboolean was_forbidden = g_error_matches (op_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN);
+
op_error->domain = E_CLIENT_ERROR;
op_error->code = E_CLIENT_ERROR_AUTHENTICATION_REQUIRED;
if (webdav) {
ENamedParameters *credentials;
+ gboolean empty_credentials;
credentials = e_soup_session_dup_credentials (E_SOUP_SESSION (webdav));
- if (credentials && e_named_parameters_count (credentials) > 0)
- op_error->code = E_CLIENT_ERROR_AUTHENTICATION_FAILED;
-
+ empty_credentials = !credentials || !e_named_parameters_count (credentials);
e_named_parameters_free (credentials);
+
+ if (!empty_credentials) {
+ if (was_forbidden) {
+ if (e_webdav_session_get_last_dav_error_is_permission (webdav)) {
+ op_error->code = E_CLIENT_ERROR_PERMISSION_DENIED;
+ g_free (op_error->message);
+ op_error->message = g_strdup (e_client_error_to_string
(op_error->code));
+ } else {
+ /* To avoid credentials prompt */
+ op_error->code = E_CLIENT_ERROR_OTHER_ERROR;
+ }
+ } else {
+ op_error->code = E_CLIENT_ERROR_AUTHENTICATION_FAILED;
+ }
+ }
}
}
}
diff --git a/src/calendar/backends/caldav/e-cal-backend-caldav.c
b/src/calendar/backends/caldav/e-cal-backend-caldav.c
index 6628d60dd..aabd3cd2d 100644
--- a/src/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/src/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -727,17 +727,33 @@ ecb_caldav_check_credentials_error (ECalBackendCalDAV *cbdav,
op_error->code = E_CLIENT_ERROR_TLS_NOT_AVAILABLE;
} else if (g_error_matches (op_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
g_error_matches (op_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN)) {
+ gboolean was_forbidden = g_error_matches (op_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN);
+
op_error->domain = E_CLIENT_ERROR;
op_error->code = E_CLIENT_ERROR_AUTHENTICATION_REQUIRED;
if (webdav) {
ENamedParameters *credentials;
+ gboolean empty_credentials;
credentials = e_soup_session_dup_credentials (E_SOUP_SESSION (webdav));
- if (credentials && e_named_parameters_count (credentials) > 0)
- op_error->code = E_CLIENT_ERROR_AUTHENTICATION_FAILED;
-
+ empty_credentials = !credentials || !e_named_parameters_count (credentials);
e_named_parameters_free (credentials);
+
+ if (!empty_credentials) {
+ if (was_forbidden) {
+ if (e_webdav_session_get_last_dav_error_is_permission (webdav)) {
+ op_error->code = E_CLIENT_ERROR_PERMISSION_DENIED;
+ g_free (op_error->message);
+ op_error->message = g_strdup (e_client_error_to_string
(op_error->code));
+ } else {
+ /* To avoid credentials prompt */
+ op_error->code = E_CLIENT_ERROR_OTHER_ERROR;
+ }
+ } else {
+ op_error->code = E_CLIENT_ERROR_AUTHENTICATION_FAILED;
+ }
+ }
}
}
}
diff --git a/src/libedataserver/e-webdav-session.c b/src/libedataserver/e-webdav-session.c
index 721eff64e..de0cc29ed 100644
--- a/src/libedataserver/e-webdav-session.c
+++ b/src/libedataserver/e-webdav-session.c
@@ -42,7 +42,7 @@
#define BUFFER_SIZE 16384
struct _EWebDAVSessionPrivate {
- gboolean dummy;
+ gchar *last_dav_error_code;
};
G_DEFINE_TYPE (EWebDAVSession, e_webdav_session, E_TYPE_SOUP_SESSION)
@@ -595,10 +595,26 @@ e_webdav_access_control_entry_get_privileges (EWebDAVAccessControlEntry *ace)
return ace->privileges;
}
+static void
+e_webdav_session_finalize (GObject *object)
+{
+ EWebDAVSession *webdav = E_WEBDAV_SESSION (object);
+
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_webdav_session_parent_class)->finalize (object);
+}
+
static void
e_webdav_session_class_init (EWebDAVSessionClass *klass)
{
+ GObjectClass *object_class;
+
g_type_class_add_private (klass, sizeof (EWebDAVSessionPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = e_webdav_session_finalize;
}
static void
@@ -630,6 +646,48 @@ e_webdav_session_new (ESource *source)
NULL);
}
+/**
+ * e_webdav_session_get_last_dav_error_code:
+ * @webdav: an #EWebDAVSession
+ *
+ * Returns last DAV error code as returned by the server. Each recognized code
+ * is enclosed in "[]" in the returned string, to be able to distinguish between
+ * them, in case the server returned multiple codes.
+ *
+ * The string is valid until the next request is executed.
+ *
+ * Returns: (transfer none): a DAV error from the last request, or %NULL, when
+ * no error had been recognized.
+ *
+ * Since: 3.34.1
+ **/
+const gchar *
+e_webdav_session_get_last_dav_error_code (EWebDAVSession *webdav)
+{
+ g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), NULL);
+
+ return webdav->priv->last_dav_error_code;
+}
+
+/**
+ * e_webdav_session_get_last_dav_error_is_permission:
+ * @webdav: an #EWebDAVSession
+ *
+ * Returns: whether the last recognized DAV error code contains an error
+ * which means that user doesn't have permission for the operation. If there
+ * is no DAV error stored, then returns %FALSE.
+ *
+ * Since: 3.34.1
+ **/
+gboolean
+e_webdav_session_get_last_dav_error_is_permission (EWebDAVSession *webdav)
+{
+ g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
+
+ return webdav->priv->last_dav_error_code &&
+ strstr (webdav->priv->last_dav_error_code, "[need-privileges]");
+}
+
/**
* e_webdav_session_new_request:
* @webdav: an #EWebDAVSession
@@ -736,7 +794,8 @@ static gboolean
e_webdav_session_extract_dav_error (EWebDAVSession *webdav,
xmlXPathContextPtr xpath_ctx,
const gchar *xpath_prefix,
- gchar **out_detail_text)
+ gchar **out_detail_text,
+ gboolean can_change_last_dav_error_code)
{
xmlXPathObjectPtr xpath_obj;
gchar *detail_text;
@@ -764,11 +823,17 @@ e_webdav_session_extract_dav_error (EWebDAVSession *webdav,
for (node = xpath_obj->nodesetval->nodeTab[0]->children; node; node = node->next) {
if (node->type == XML_ELEMENT_NODE &&
- node->name && *(node->name))
+ node->name && *(node->name)) {
g_string_append_printf (text, "[%s]", (const gchar *) node->name);
+ }
}
if (text->len > 0) {
+ if (can_change_last_dav_error_code) {
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+ webdav->priv->last_dav_error_code = g_strdup (text->str);
+ }
+
if (detail_text) {
g_strstrip (detail_text);
if (*detail_text)
@@ -790,41 +855,14 @@ e_webdav_session_extract_dav_error (EWebDAVSession *webdav,
return detail_text != NULL;
}
-/**
- * e_webdav_session_replace_with_detailed_error:
- * @webdav: an #EWebDAVSession
- * @request: a #SoupRequestHTTP
- * @response_data: (nullable): received response data, or %NULL
- * @ignore_multistatus: whether to ignore multistatus responses
- * @prefix: (nullable): error message prefix, used when replacing, or %NULL
- * @inout_error: (inout) (nullable) (transfer full): a #GError variable to replace content to, or %NULL
- *
- * Tries to read detailed error information from @response_data,
- * if not provided, then from @request's response_body. If the detailed
- * error cannot be found, then does nothing, otherwise frees the content
- * of @inout_error, if any, and then populates it with an error message
- * prefixed with @prefix.
- *
- * The @prefix might be of form "Failed to something", because the resulting
- * error message will be:
- * "Failed to something: HTTP error code XXX (reason_phrase): detailed_error".
- * When @prefix is %NULL, the error message will be:
- * "Failed with HTTP error code XXX (reason phrase): detailed_error".
- *
- * As the caller might not be interested in errors, also the @inout_error
- * can be %NULL, in which case the function does nothing.
- *
- * Returns: Whether any detailed error had been recognized.
- *
- * Since: 3.26
- **/
-gboolean
-e_webdav_session_replace_with_detailed_error (EWebDAVSession *webdav,
- SoupRequestHTTP *request,
- const GByteArray *response_data,
- gboolean ignore_multistatus,
- const gchar *prefix,
- GError **inout_error)
+static gboolean
+e_webdav_session_replace_with_detailed_error_internal (EWebDAVSession *webdav,
+ SoupRequestHTTP *request,
+ const GByteArray *response_data,
+ gboolean ignore_multistatus,
+ const gchar *prefix,
+ GError **inout_error,
+ gboolean can_change_last_dav_error_code)
{
SoupMessage *message;
GByteArray byte_array = { 0 };
@@ -896,7 +934,7 @@ e_webdav_session_replace_with_detailed_error (EWebDAVSession *webdav,
NULL);
if (xpath_ctx &&
- e_webdav_session_extract_dav_error (webdav, xpath_ctx, "", &detail_text)) {
+ e_webdav_session_extract_dav_error (webdav, xpath_ctx, "", &detail_text,
can_change_last_dav_error_code)) {
/* do nothing, detail_text is set */
} else if (xpath_ctx) {
const gchar *path_prefix = NULL;
@@ -920,9 +958,9 @@ e_webdav_session_replace_with_detailed_error (EWebDAVSession *webdav,
detail_text = e_xml_xpath_eval_as_string (xpath_ctx,
"%s/D:responsedescription", path_prefix);
if (!detail_text)
- e_webdav_session_extract_dav_error (webdav,
xpath_ctx, path_prefix, &detail_text);
+ e_webdav_session_extract_dav_error (webdav,
xpath_ctx, path_prefix, &detail_text, can_change_last_dav_error_code);
} else {
- e_webdav_session_extract_dav_error (webdav, xpath_ctx,
path_prefix, &detail_text);
+ e_webdav_session_extract_dav_error (webdav, xpath_ctx,
path_prefix, &detail_text, can_change_last_dav_error_code);
}
g_free (status);
@@ -1016,6 +1054,45 @@ e_webdav_session_replace_with_detailed_error (EWebDAVSession *webdav,
return error_set;
}
+/**
+ * e_webdav_session_replace_with_detailed_error:
+ * @webdav: an #EWebDAVSession
+ * @request: a #SoupRequestHTTP
+ * @response_data: (nullable): received response data, or %NULL
+ * @ignore_multistatus: whether to ignore multistatus responses
+ * @prefix: (nullable): error message prefix, used when replacing, or %NULL
+ * @inout_error: (inout) (nullable) (transfer full): a #GError variable to replace content to, or %NULL
+ *
+ * Tries to read detailed error information from @response_data,
+ * if not provided, then from @request's response_body. If the detailed
+ * error cannot be found, then does nothing, otherwise frees the content
+ * of @inout_error, if any, and then populates it with an error message
+ * prefixed with @prefix.
+ *
+ * The @prefix might be of form "Failed to something", because the resulting
+ * error message will be:
+ * "Failed to something: HTTP error code XXX (reason_phrase): detailed_error".
+ * When @prefix is %NULL, the error message will be:
+ * "Failed with HTTP error code XXX (reason phrase): detailed_error".
+ *
+ * As the caller might not be interested in errors, also the @inout_error
+ * can be %NULL, in which case the function does nothing.
+ *
+ * Returns: Whether any detailed error had been recognized.
+ *
+ * Since: 3.26
+ **/
+gboolean
+e_webdav_session_replace_with_detailed_error (EWebDAVSession *webdav,
+ SoupRequestHTTP *request,
+ const GByteArray *response_data,
+ gboolean ignore_multistatus,
+ const gchar *prefix,
+ GError **inout_error)
+{
+ return e_webdav_session_replace_with_detailed_error_internal (webdav, request, response_data,
ignore_multistatus, prefix, inout_error, FALSE);
+}
+
/**
* e_webdav_session_ensure_full_uri:
* @webdav: an #EWebDAVSession
@@ -1160,6 +1237,8 @@ e_webdav_session_options_sync (EWebDAVSession *webdav,
*out_capabilities = NULL;
*out_allows = NULL;
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_OPTIONS, uri, error);
if (!request)
return FALSE;
@@ -1239,6 +1318,8 @@ e_webdav_session_post_with_content_type_sync (EWebDAVSession *webdav,
if (data_length == (gsize) -1)
data_length = strlen (data);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_POST, uri, error);
if (!request)
return FALSE;
@@ -1256,7 +1337,7 @@ e_webdav_session_post_with_content_type_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, TRUE, _("Failed to
post data"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, TRUE,
_("Failed to post data"), error, TRUE) &&
bytes != NULL;
if (success) {
@@ -1368,6 +1449,8 @@ e_webdav_session_propfind_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_XML_DOCUMENT (xml), FALSE);
g_return_val_if_fail (func != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_PROPFIND, uri, error);
if (!request)
return FALSE;
@@ -1402,7 +1485,7 @@ e_webdav_session_propfind_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, TRUE, _("Failed to
get properties"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, TRUE,
_("Failed to get properties"), error, TRUE) &&
bytes != NULL;
if (success)
@@ -1449,6 +1532,8 @@ e_webdav_session_proppatch_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
g_return_val_if_fail (E_IS_XML_DOCUMENT (xml), FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_PROPPATCH, uri, error);
if (!request)
return FALSE;
@@ -1476,7 +1561,7 @@ e_webdav_session_proppatch_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
update properties"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to update properties"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -1550,6 +1635,8 @@ e_webdav_session_report_sync (EWebDAVSession *webdav,
if (out_content)
*out_content = NULL;
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, "REPORT", uri, error);
if (!request)
return FALSE;
@@ -1580,7 +1667,7 @@ e_webdav_session_report_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, TRUE, _("Failed to
issue REPORT"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, TRUE,
_("Failed to issue REPORT"), error, TRUE) &&
bytes != NULL;
if (success && func && message->status_code == SOUP_STATUS_MULTI_STATUS)
@@ -1633,13 +1720,15 @@ e_webdav_session_mkcol_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_MKCOL, uri, error);
if (!request)
return FALSE;
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
create collection"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to create collection"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -1687,6 +1776,8 @@ e_webdav_session_mkcol_addressbook_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_MKCOL, uri, error);
if (!request)
return FALSE;
@@ -1742,7 +1833,7 @@ e_webdav_session_mkcol_addressbook_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
create address book"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to create address book"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -1796,6 +1887,8 @@ e_webdav_session_mkcalendar_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, "MKCALENDAR", uri, error);
if (!request)
return FALSE;
@@ -1902,7 +1995,7 @@ e_webdav_session_mkcalendar_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
create calendar"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to create calendar"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -1995,6 +2088,8 @@ e_webdav_session_get_sync (EWebDAVSession *webdav,
g_return_val_if_fail (uri != NULL, FALSE);
g_return_val_if_fail (G_IS_OUTPUT_STREAM (out_stream), FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_GET, uri, error);
if (!request)
return FALSE;
@@ -2034,7 +2129,7 @@ e_webdav_session_get_sync (EWebDAVSession *webdav,
tmp_bytes.data = buffer;
tmp_bytes.len = nread;
- success = !e_webdav_session_replace_with_detailed_error (webdav, request,
&tmp_bytes, FALSE, _("Failed to read resource"), error);
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav,
request, &tmp_bytes, FALSE, _("Failed to read resource"), error, TRUE);
if (!success)
break;
}
@@ -2045,7 +2140,7 @@ e_webdav_session_get_sync (EWebDAVSession *webdav,
}
if (success && first_chunk) {
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, NULL,
FALSE, _("Failed to read resource"), error);
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request,
NULL, FALSE, _("Failed to read resource"), error, TRUE);
} else if (success && !first_chunk && log_level == SOUP_LOGGER_LOG_BODY) {
fprintf (stdout, "\n");
fflush (stdout);
@@ -2294,6 +2389,8 @@ e_webdav_session_put_sync (EWebDAVSession *webdav,
if (out_etag)
*out_etag = NULL;
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_PUT, uri, error);
if (!request)
return FALSE;
@@ -2357,7 +2454,7 @@ e_webdav_session_put_sync (EWebDAVSession *webdav,
g_signal_handler_disconnect (message, wrote_headers_id);
g_signal_handler_disconnect (message, wrote_chunk_id);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
put data"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to put data"), error, TRUE) &&
bytes != NULL;
if (cwd.wrote_any && cwd.log_level == SOUP_LOGGER_LOG_BODY) {
@@ -2459,6 +2556,8 @@ e_webdav_session_put_data_sync (EWebDAVSession *webdav,
if (out_etag)
*out_etag = NULL;
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_PUT, uri, error);
if (!request)
return FALSE;
@@ -2501,7 +2600,7 @@ e_webdav_session_put_data_sync (EWebDAVSession *webdav,
ret_bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, ret_bytes, FALSE, _("Failed
to put data"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, ret_bytes, FALSE,
_("Failed to put data"), error, TRUE) &&
ret_bytes != NULL;
if (success) {
@@ -2567,6 +2666,8 @@ e_webdav_session_delete_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_DELETE, uri, error);
if (!request)
return FALSE;
@@ -2601,7 +2702,7 @@ e_webdav_session_delete_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
delete resource"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to delete resource"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -2650,6 +2751,8 @@ e_webdav_session_copy_sync (EWebDAVSession *webdav,
g_return_val_if_fail (destination_uri != NULL, FALSE);
g_return_val_if_fail (depth != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_COPY, source_uri, error);
if (!request)
return FALSE;
@@ -2668,7 +2771,7 @@ e_webdav_session_copy_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
copy resource"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to copy resource"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -2712,6 +2815,8 @@ e_webdav_session_move_sync (EWebDAVSession *webdav,
g_return_val_if_fail (source_uri != NULL, FALSE);
g_return_val_if_fail (destination_uri != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_MOVE, source_uri, error);
if (!request)
return FALSE;
@@ -2730,7 +2835,7 @@ e_webdav_session_move_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
move resource"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to move resource"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -2790,6 +2895,8 @@ e_webdav_session_lock_sync (EWebDAVSession *webdav,
*out_lock_token = NULL;
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_LOCK, uri, error);
if (!request)
return FALSE;
@@ -2835,7 +2942,7 @@ e_webdav_session_lock_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
lock resource"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to lock resource"), error, TRUE) &&
bytes != NULL;
if (success && out_xml_response) {
@@ -2919,6 +3026,8 @@ e_webdav_session_refresh_lock_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
g_return_val_if_fail (lock_token != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_LOCK, uri, error);
if (!request)
return FALSE;
@@ -2943,7 +3052,7 @@ e_webdav_session_refresh_lock_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
refresh lock"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to refresh lock"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -2986,6 +3095,8 @@ e_webdav_session_unlock_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
g_return_val_if_fail (lock_token != NULL, FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, SOUP_METHOD_UNLOCK, uri, error);
if (!request)
return FALSE;
@@ -3002,7 +3113,7 @@ e_webdav_session_unlock_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, FALSE, _("Failed to
unlock"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to unlock"), error, TRUE) &&
bytes != NULL;
if (bytes)
@@ -4093,6 +4204,8 @@ e_webdav_session_acl_sync (EWebDAVSession *webdav,
g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
g_return_val_if_fail (E_IS_XML_DOCUMENT (xml), FALSE);
+ g_clear_pointer (&webdav->priv->last_dav_error_code, g_free);
+
request = e_webdav_session_new_request (webdav, "ACL", uri, error);
if (!request)
return FALSE;
@@ -4120,7 +4233,7 @@ e_webdav_session_acl_sync (EWebDAVSession *webdav,
bytes = e_soup_session_send_request_simple_sync (E_SOUP_SESSION (webdav), request, cancellable,
error);
- success = !e_webdav_session_replace_with_detailed_error (webdav, request, bytes, TRUE, _("Failed to
get access control list"), error) &&
+ success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, TRUE,
_("Failed to get access control list"), error, TRUE) &&
bytes != NULL;
if (bytes)
diff --git a/src/libedataserver/e-webdav-session.h b/src/libedataserver/e-webdav-session.h
index a542d0d77..0345e437e 100644
--- a/src/libedataserver/e-webdav-session.h
+++ b/src/libedataserver/e-webdav-session.h
@@ -338,6 +338,9 @@ struct _EWebDAVSessionClass {
GType e_webdav_session_get_type (void) G_GNUC_CONST;
EWebDAVSession *e_webdav_session_new (ESource *source);
+const gchar * e_webdav_session_get_last_dav_error_code(EWebDAVSession *webdav);
+gboolean e_webdav_session_get_last_dav_error_is_permission
+ (EWebDAVSession *webdav);
SoupRequestHTTP *
e_webdav_session_new_request (EWebDAVSession *webdav,
const gchar *method,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]