[libsoup/carlosgc/request-body-stream: 3/4] forms: Use GBytes instead of SoupMessageBody




commit 0d7e672e29fa3318d9631206bee2fc5a7733f355
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Thu Oct 8 14:00:17 2020 +0200

    forms: Use GBytes instead of SoupMessageBody
    
    Use the body stream always for requests in client side.

 libsoup/soup-form.c              | 15 +++++++++----
 libsoup/soup-message-server-io.c |  6 ++++--
 libsoup/soup-message.c           |  3 ++-
 libsoup/soup-multipart.c         | 46 ++++++++++++++++++++--------------------
 libsoup/soup-multipart.h         |  4 ++--
 tests/header-parsing-test.c      |  7 +-----
 tests/range-test.c               | 10 +++------
 7 files changed, 46 insertions(+), 45 deletions(-)
---
diff --git a/libsoup/soup-form.c b/libsoup/soup-form.c
index 84acf486..32e7de3c 100644
--- a/libsoup/soup-form.c
+++ b/libsoup/soup-form.c
@@ -153,14 +153,16 @@ soup_form_decode_multipart (SoupMessage *msg, const char *file_control_name,
        SoupMultipart *multipart;
        GHashTable *form_data_set, *params;
        SoupMessageHeaders *part_headers;
+       GBytes *body;
        GBytes *part_body;
        char *disposition, *name;
        int i;
 
        g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
 
-       multipart = soup_multipart_new_from_message (msg->request_headers,
-                                                    msg->request_body);
+       body = soup_message_body_flatten (msg->request_body);
+       multipart = soup_multipart_new_from_message (msg->request_headers, body);
+       g_bytes_unref (body);
        if (!multipart)
                return NULL;
 
@@ -483,9 +485,14 @@ soup_form_request_new_from_multipart (const char *uri,
                                      SoupMultipart *multipart)
 {
        SoupMessage *msg;
+       GBytes *body = NULL;
 
        msg = soup_message_new ("POST", uri);
-       soup_multipart_to_message (multipart, msg->request_headers,
-                                  msg->request_body);
+       soup_multipart_to_message (multipart, msg->request_headers, &body);
+       soup_message_set_request_body_from_bytes (msg,
+                                                 soup_message_headers_get_content_type 
(msg->request_headers, NULL),
+                                                 body);
+       g_bytes_unref (body);
+
        return msg;
 }
diff --git a/libsoup/soup-message-server-io.c b/libsoup/soup-message-server-io.c
index 2c0ee91c..acd1490c 100644
--- a/libsoup/soup-message-server-io.c
+++ b/libsoup/soup-message-server-io.c
@@ -202,6 +202,7 @@ handle_partial_get (SoupMessage *msg)
                SoupMultipart *multipart;
                SoupMessageHeaders *part_headers;
                GBytes *part_body;
+               GBytes *body = NULL;
                const char *content_type;
                int i;
 
@@ -232,8 +233,9 @@ handle_partial_get (SoupMessage *msg)
                        g_bytes_unref (part_body);
                }
 
-               soup_multipart_to_message (multipart, msg->response_headers,
-                                          msg->response_body);
+               soup_multipart_to_message (multipart, msg->response_headers, &body);
+               soup_message_body_append_bytes (msg->response_body, body);
+               g_bytes_unref (body);
                soup_multipart_free (multipart);
        }
 
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index aacd8008..7053aa97 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -1157,7 +1157,8 @@ soup_message_set_request_body (SoupMessage  *msg,
         if (content_type) {
                 g_warn_if_fail (strchr (content_type, '/') != NULL);
 
-                soup_message_headers_replace (msg->request_headers, "Content-Type", content_type);
+                if (soup_message_headers_get_content_type (msg->request_headers, NULL) != content_type)
+                        soup_message_headers_replace (msg->request_headers, "Content-Type", content_type);
                 if (content_length == -1)
                         soup_message_headers_set_encoding (msg->request_headers, SOUP_ENCODING_CHUNKED);
                 else
diff --git a/libsoup/soup-multipart.c b/libsoup/soup-multipart.c
index 9ff3e62a..82a7ef52 100644
--- a/libsoup/soup-multipart.c
+++ b/libsoup/soup-multipart.c
@@ -134,13 +134,12 @@ find_boundary (const char *start, const char *end,
  **/
 SoupMultipart *
 soup_multipart_new_from_message (SoupMessageHeaders *headers,
-                                SoupMessageBody *body)
+                                GBytes             *body)
 {
        SoupMultipart *multipart;
        const char *content_type, *boundary;
        GHashTable *params;
        int boundary_len;
-       GBytes *flattened;
        const char *start, *split, *end, *body_end;
        SoupMessageHeaders *part_headers;
        GBytes *part_body;
@@ -159,19 +158,17 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers,
                g_strdup (content_type), g_strdup (boundary));
        g_hash_table_destroy (params);
 
-       flattened = soup_message_body_flatten (body);
-        gsize flattened_size;
-        const char *flattened_data = g_bytes_get_data (flattened, &flattened_size);
-       body_end = flattened_data + flattened_size;
+        gsize body_size;
+        const char *body_data = g_bytes_get_data (body, &body_size);
+       body_end = body_data + body_size;
        boundary = multipart->boundary;
        boundary_len = strlen (boundary);
 
        /* skip preamble */
-       start = find_boundary (flattened_data, body_end,
+       start = find_boundary (body_data, body_end,
                               boundary, boundary_len);
        if (!start) {
                soup_multipart_free (multipart);
-               g_bytes_unref (flattened);
                return NULL;
        }
 
@@ -180,14 +177,12 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers,
                                     boundary, boundary_len);
                if (!end) {
                        soup_multipart_free (multipart);
-                       g_bytes_unref (flattened);
                        return NULL;
                }
 
                split = strstr (start, "\r\n\r\n");
                if (!split || split > end) {
                        soup_multipart_free (multipart);
-                       g_bytes_unref (flattened);
                        return NULL;
                }
                split += 4;
@@ -206,7 +201,6 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers,
                if (!soup_headers_parse (start, split - 2 - start,
                                         part_headers)) {
                        soup_multipart_free (multipart);
-                       g_bytes_unref (flattened);
                        return NULL;
                }
 
@@ -215,15 +209,14 @@ soup_multipart_new_from_message (SoupMessageHeaders *headers,
                 * the following boundary line, which is to say 2 bytes
                 * after the end of the body.
                 */
-               part_body = g_bytes_new_from_bytes (flattened, // FIXME
-                                                   split - flattened_data,
+               part_body = g_bytes_new_from_bytes (body, // FIXME
+                                                   split - body_data,
                                                    end - 2 - split);
                g_ptr_array_add (multipart->bodies, part_body);
 
                start = end;
        }
 
-       g_bytes_unref (flattened);
        return multipart;
 }
 
@@ -394,22 +387,24 @@ soup_multipart_append_form_file (SoupMultipart *multipart,
  * soup_multipart_to_message:
  * @multipart: a #SoupMultipart
  * @dest_headers: the headers of the HTTP message to serialize @multipart to
- * @dest_body: the body of the HTTP message to serialize @multipart to
+ * @dest_body: (out): the body of the HTTP message to serialize @multipart to
  *
  * Serializes @multipart to @dest_headers and @dest_body.
  *
  * Since: 2.26
  **/
 void
-soup_multipart_to_message (SoupMultipart *multipart,
+soup_multipart_to_message (SoupMultipart      *multipart,
                           SoupMessageHeaders *dest_headers,
-                          SoupMessageBody *dest_body)
+                          GBytes            **dest_body)
 {
        SoupMessageHeaders *part_headers;
+       SoupMessageBody *body;
        GBytes *part_body;
        SoupMessageHeadersIter iter;
        const char *name, *value;
        GString *str;
+       GBytes *buffer;
        GHashTable *params;
        guint i;
 
@@ -420,6 +415,8 @@ soup_multipart_to_message (SoupMultipart *multipart,
                                               params);
        g_hash_table_destroy (params);
 
+       body = soup_message_body_new ();
+
        for (i = 0; i < multipart->bodies->len; i++) {
                part_headers = multipart->headers->pdata[i];
                part_body = multipart->bodies->pdata[i];
@@ -433,24 +430,27 @@ soup_multipart_to_message (SoupMultipart *multipart,
                        g_string_append_printf (str, "%s: %s\r\n", name, value);
                g_string_append (str, "\r\n");
 
-                GBytes *buffer = g_string_free_to_bytes (str);
-                soup_message_body_append_bytes (dest_body, buffer);
+                buffer = g_string_free_to_bytes (str);
+                soup_message_body_append_bytes (body, buffer);
                 g_bytes_unref (buffer);
 
-               soup_message_body_append_bytes (dest_body, part_body);
+               soup_message_body_append_bytes (body, part_body);
        }
 
        str = g_string_new ("\r\n--");
        g_string_append (str, multipart->boundary);
        g_string_append (str, "--\r\n");
-       soup_message_body_append (dest_body, SOUP_MEMORY_TAKE,
-                                 str->str, str->len);
-       g_string_free (str, FALSE);
+       buffer = g_string_free_to_bytes (str);
+       soup_message_body_append_bytes (body, buffer);
+       g_bytes_unref (buffer);
 
        /* (The "\r\n" after the close-delimiter seems wrong according
         * to my reading of RFCs 2046 and 2616, but that's what
         * everyone else does.)
         */
+
+       *dest_body = soup_message_body_flatten (body);
+       soup_message_body_free (body);
 }
 
 /**
diff --git a/libsoup/soup-multipart.h b/libsoup/soup-multipart.h
index 9724bdc6..25462d9b 100644
--- a/libsoup/soup-multipart.h
+++ b/libsoup/soup-multipart.h
@@ -21,7 +21,7 @@ SOUP_AVAILABLE_IN_2_26
 SoupMultipart *soup_multipart_new              (const char          *mime_type);
 SOUP_AVAILABLE_IN_2_26
 SoupMultipart *soup_multipart_new_from_message (SoupMessageHeaders  *headers,
-                                               SoupMessageBody     *body);
+                                               GBytes              *body);
 
 SOUP_AVAILABLE_IN_2_26
 int      soup_multipart_get_length         (SoupMultipart       *multipart);
@@ -50,7 +50,7 @@ void     soup_multipart_append_form_file   (SoupMultipart       *multipart,
 SOUP_AVAILABLE_IN_2_26
 void     soup_multipart_to_message         (SoupMultipart       *multipart,
                                            SoupMessageHeaders  *dest_headers,
-                                           SoupMessageBody     *dest_body);
+                                           GBytes             **dest_body);
 
 SOUP_AVAILABLE_IN_2_26
 void     soup_multipart_free               (SoupMultipart       *multipart);
diff --git a/tests/header-parsing-test.c b/tests/header-parsing-test.c
index 40b5fd37..1712105a 100644
--- a/tests/header-parsing-test.c
+++ b/tests/header-parsing-test.c
@@ -1042,7 +1042,6 @@ do_content_disposition_tests (void)
        char *disposition;
        GBytes *buffer;
        SoupMultipart *multipart;
-       SoupMessageBody *body;
 
        hdrs = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART);
        params = g_hash_table_new (g_str_hash, g_str_equal);
@@ -1112,14 +1111,10 @@ do_content_disposition_tests (void)
        g_bytes_unref (buffer);
 
        hdrs = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART);
-       body = soup_message_body_new ();
-       soup_multipart_to_message (multipart, hdrs, body);
+       soup_multipart_to_message (multipart, hdrs, &buffer);
        soup_message_headers_free (hdrs);
        soup_multipart_free (multipart);
 
-       buffer = soup_message_body_flatten (body);
-       soup_message_body_free (body);
-
        g_assert_nonnull (strstr (g_bytes_get_data (buffer, NULL), "filename=\"token\""));
 
        g_bytes_unref (buffer);
diff --git a/tests/range-test.c b/tests/range-test.c
index 3641198c..ce8a744b 100644
--- a/tests/range-test.c
+++ b/tests/range-test.c
@@ -116,24 +116,20 @@ do_multi_range (SoupSession *session, SoupMessage *msg,
        const char *content_type;
        int i, length;
        GBytes *body;
-       SoupMessageBody *message_body;
 
        debug_printf (1, "    Range: %s\n",
                      soup_message_headers_get_one (msg->request_headers, "Range"));
 
        body = soup_test_session_async_send (session, msg);
-       message_body = soup_message_body_new ();
-       soup_message_body_append_bytes (message_body, body);
-       g_bytes_unref (body);
 
        soup_test_assert_message_status (msg, SOUP_STATUS_PARTIAL_CONTENT);
 
        content_type = soup_message_headers_get_content_type (msg->response_headers, NULL);
        g_assert_cmpstr (content_type, ==, "multipart/byteranges");
 
-       multipart = soup_multipart_new_from_message (msg->response_headers,
-                                                    message_body);
-       soup_message_body_free (message_body);
+       multipart = soup_multipart_new_from_message (msg->response_headers, body);
+       g_bytes_unref (body);
+
        if (!multipart) {
                soup_test_assert (FALSE, "Could not parse multipart");
                g_object_unref (msg);


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