diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2015-04-19 18:34:16 +0100 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2015-04-20 00:13:34 +0100 |
commit | d8a40c6e4172ba26f57e65041667b5266f88fed1 (patch) | |
tree | e02b028f478ce25e93078e4917076ab49db9066d /gdata/gdata-upload-stream.c | |
parent | de74263ff38a9d3e9672b833e5883393b3a9854c (diff) | |
download | libgdata-d8a40c6e4172ba26f57e65041667b5266f88fed1.tar.gz |
core: Add JSON support to GDataUploadStream
Add support for JSON to the non-resumable and resumable code paths, so
that GDataEntrys which specify application/json as their content type
have JSON generated and uploaded, rather than XML.
This will be useful for the upcoming port to v3 of the YouTube API.
https://bugzilla.gnome.org/show_bug.cgi?id=687597
Diffstat (limited to 'gdata/gdata-upload-stream.c')
-rw-r--r-- | gdata/gdata-upload-stream.c | 79 |
1 files changed, 61 insertions, 18 deletions
diff --git a/gdata/gdata-upload-stream.c b/gdata/gdata-upload-stream.c index 87d8a319..0fe054e3 100644 --- a/gdata/gdata-upload-stream.c +++ b/gdata/gdata-upload-stream.c @@ -427,7 +427,7 @@ static GObject * gdata_upload_stream_constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params) { GDataUploadStreamPrivate *priv; - GDataServiceClass *klass; + GDataServiceClass *service_klass; GObject *object; /* Chain up to the parent class */ @@ -451,22 +451,47 @@ gdata_upload_stream_constructor (GType type, guint n_construct_params, GObjectCo /* The Content-Type should be multipart/related if we're also uploading the metadata (entry != NULL), * and the given content_type otherwise. */ if (priv->entry != NULL) { - const gchar *first_part_header; - gchar *entry_xml, *second_part_header; + gchar *first_part_header, *upload_data; + gchar *second_part_header; + GDataParsableClass *parsable_klass; + + parsable_klass = GDATA_PARSABLE_GET_CLASS (priv->entry); + g_assert (parsable_klass->get_content_type != NULL); soup_message_headers_set_content_type (priv->message->request_headers, "multipart/related; boundary=" BOUNDARY_STRING, NULL); + if (g_strcmp0 (parsable_klass->get_content_type (), "application/json") == 0) { + upload_data = gdata_parsable_get_json (GDATA_PARSABLE (priv->entry)); + } else { + upload_data = gdata_parsable_get_xml (GDATA_PARSABLE (priv->entry)); + } + /* Start by writing out the entry; then the thread has something to write to the network when it's created */ - first_part_header = "--" BOUNDARY_STRING "\nContent-Type: application/atom+xml; charset=UTF-8\n\n"; - entry_xml = gdata_parsable_get_xml (GDATA_PARSABLE (priv->entry)); - second_part_header = g_strdup_printf ("\n--" BOUNDARY_STRING "\nContent-Type: %s\nContent-Transfer-Encoding: binary\n\n", + first_part_header = g_strdup_printf ("--" BOUNDARY_STRING "\n" + "Content-Type: %s; charset=UTF-8\n\n", + parsable_klass->get_content_type ()); + second_part_header = g_strdup_printf ("\n--" BOUNDARY_STRING "\n" + "Content-Type: %s\n" + "Content-Transfer-Encoding: binary\n\n", priv->content_type); /* Push the message parts onto the message body; we can skip the buffer, since the network thread hasn't yet been created, * so we're the sole thread accessing the SoupMessage. */ - soup_message_body_append (priv->message->request_body, SOUP_MEMORY_STATIC, first_part_header, strlen (first_part_header)); - soup_message_body_append (priv->message->request_body, SOUP_MEMORY_TAKE, entry_xml, strlen (entry_xml)); - soup_message_body_append (priv->message->request_body, SOUP_MEMORY_TAKE, second_part_header, strlen (second_part_header)); + soup_message_body_append (priv->message->request_body, + SOUP_MEMORY_TAKE, + first_part_header, + strlen (first_part_header)); + soup_message_body_append (priv->message->request_body, + SOUP_MEMORY_TAKE, upload_data, + strlen (upload_data)); + soup_message_body_append (priv->message->request_body, + SOUP_MEMORY_TAKE, + second_part_header, + strlen (second_part_header)); + + first_part_header = NULL; + upload_data = NULL; + second_part_header = NULL; priv->network_bytes_outstanding = priv->message->request_body->length; } else { @@ -487,12 +512,30 @@ gdata_upload_stream_constructor (GType type, guint n_construct_params, GObjectCo g_free (content_length_str); if (priv->entry != NULL) { - const gchar *entry_xml; - - soup_message_headers_set_content_type (priv->message->request_headers, "application/atom+xml; charset=UTF-8", NULL); - - entry_xml = gdata_parsable_get_xml (GDATA_PARSABLE (priv->entry)); - soup_message_body_append (priv->message->request_body, SOUP_MEMORY_TAKE, entry_xml, strlen (entry_xml)); + GDataParsableClass *parsable_klass; + gchar *content_type, *upload_data; + + parsable_klass = GDATA_PARSABLE_GET_CLASS (priv->entry); + g_assert (parsable_klass->get_content_type != NULL); + + if (g_strcmp0 (parsable_klass->get_content_type (), "application/json") == 0) { + upload_data = gdata_parsable_get_json (GDATA_PARSABLE (priv->entry)); + } else { + upload_data = gdata_parsable_get_xml (GDATA_PARSABLE (priv->entry)); + } + + content_type = g_strdup_printf ("%s; charset=UTF-8", + parsable_klass->get_content_type ()); + soup_message_headers_set_content_type (priv->message->request_headers, + content_type, + NULL); + g_free (content_type); + + soup_message_body_append (priv->message->request_body, + SOUP_MEMORY_TAKE, + upload_data, + strlen (upload_data)); + upload_data = NULL; priv->network_bytes_outstanding = priv->message->request_body->length; } else { @@ -506,9 +549,9 @@ gdata_upload_stream_constructor (GType type, guint n_construct_params, GObjectCo /* Make sure the headers are set. HACK: This should actually be in build_message(), but we have to work around * http://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=3033 in GDataDocumentsService's append_query_headers(). */ - klass = GDATA_SERVICE_GET_CLASS (priv->service); - if (klass->append_query_headers != NULL) { - klass->append_query_headers (priv->service, priv->authorization_domain, priv->message); + service_klass = GDATA_SERVICE_GET_CLASS (priv->service); + if (service_klass->append_query_headers != NULL) { + service_klass->append_query_headers (priv->service, priv->authorization_domain, priv->message); } /* If the entry exists and has an ETag, we assume we're updating the entry, so we can set the If-Match header */ |