[evolution-data-server/gnome-3-26] Bug 787656 - Do not use Transfer-Encoding:chunked for CalDAV/CardDAV PUT



commit ef8b553fd383c097a321145e4808be03f6460a90
Author: Milan Crha <mcrha redhat com>
Date:   Tue Sep 26 14:20:56 2017 +0200

    Bug 787656 - Do not use Transfer-Encoding:chunked for CalDAV/CardDAV PUT

 src/libedataserver/e-webdav-session.c |   86 ++++++++++++++++++++++++++++++---
 1 files changed, 79 insertions(+), 7 deletions(-)
---
diff --git a/src/libedataserver/e-webdav-session.c b/src/libedataserver/e-webdav-session.c
index c1c02cb..c396814 100644
--- a/src/libedataserver/e-webdav-session.c
+++ b/src/libedataserver/e-webdav-session.c
@@ -2175,7 +2175,9 @@ e_webdav_session_write_restarted (SoupMessage *message,
  * The @stream should support also #GSeekable interface, because the data
  * send can require restart of the send due to redirect or other reasons.
  *
- * The e_webdav_session_put_data_sync() can be used to write data stored in memory.
+ * This method uses Transfer-Encoding:chunked, in contrast to the
+ * e_webdav_session_put_data_sync(), which writes data stored in memory
+ * like any other request.
  *
  * Returns: Whether succeeded.
  *
@@ -2349,7 +2351,7 @@ e_webdav_session_put_sync (EWebDAVSession *webdav,
  *
  * The @out_etag contains ETag of the resource after it had been saved.
  *
- * To read large data use e_webdav_session_put_sync() instead.
+ * To write large data use e_webdav_session_put_sync() instead.
  *
  * Returns: Whether succeeded.
  *
@@ -2367,7 +2369,9 @@ e_webdav_session_put_data_sync (EWebDAVSession *webdav,
                                GCancellable *cancellable,
                                GError **error)
 {
-       GInputStream *input_stream;
+       SoupRequestHTTP *request;
+       SoupMessage *message;
+       GByteArray *ret_bytes;
        gboolean success;
 
        g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE);
@@ -2377,13 +2381,81 @@ e_webdav_session_put_data_sync (EWebDAVSession *webdav,
 
        if (length == (gsize) -1)
                length = strlen (bytes);
+       if (out_href)
+               *out_href = NULL;
+       if (out_etag)
+               *out_etag = NULL;
+
+       request = e_webdav_session_new_request (webdav, SOUP_METHOD_PUT, uri, error);
+       if (!request)
+               return FALSE;
 
-       input_stream = g_memory_input_stream_new_from_data (bytes, length, NULL);
+       message = soup_request_http_get_message (request);
+       if (!message) {
+               g_warn_if_fail (message != NULL);
+               g_object_unref (request);
 
-       success = e_webdav_session_put_sync (webdav, uri, etag, content_type,
-               input_stream, out_href, out_etag, cancellable, error);
+               return FALSE;
+       }
 
-       g_object_unref (input_stream);
+       if (!etag || *etag) {
+               ESource *source;
+               gboolean avoid_ifmatch = FALSE;
+
+               source = e_soup_session_get_source (E_SOUP_SESSION (webdav));
+               if (source && e_source_has_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND)) {
+                       ESourceWebdav *webdav_extension;
+
+                       webdav_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
+                       avoid_ifmatch = e_source_webdav_get_avoid_ifmatch (webdav_extension);
+               }
+
+               if (!avoid_ifmatch) {
+                       if (etag) {
+                               gint len = strlen (etag);
+
+                               if (*etag == '\"' && len > 2 && etag[len - 1] == '\"') {
+                                       soup_message_headers_replace (message->request_headers, "If-Match", 
etag);
+                               } else {
+                                       gchar *quoted;
+
+                                       quoted = g_strconcat ("\"", etag, "\"", NULL);
+                                       soup_message_headers_replace (message->request_headers, "If-Match", 
quoted);
+                                       g_free (quoted);
+                               }
+                       } else {
+                               soup_message_headers_replace (message->request_headers, "If-None-Match", "*");
+                       }
+               }
+       }
+
+       if (content_type && *content_type)
+               soup_message_headers_replace (message->request_headers, "Content-Type", content_type);
+
+       soup_message_set_request (message, content_type, SOUP_MEMORY_TEMPORARY, bytes, length);
+
+       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) &&
+               ret_bytes != NULL;
+
+       if (success) {
+               if (success && !SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
+                       success = FALSE;
+
+                       g_set_error (error, SOUP_HTTP_ERROR, message->status_code,
+                               _("Failed to put data to server, error code %d (%s)"), message->status_code,
+                               e_soup_session_util_status_to_string (message->status_code, 
message->reason_phrase));
+               }
+       }
+
+       if (success)
+               e_webdav_session_extract_href_and_etag (message, out_href, out_etag);
+
+       if (ret_bytes)
+               g_byte_array_free (ret_bytes, TRUE);
+       g_object_unref (message);
+       g_object_unref (request);
 
        return success;
 }


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