summaryrefslogtreecommitdiff
path: root/gdata/gdata-upload-stream.c
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2015-04-19 18:34:16 +0100
committerPhilip Withnall <philip@tecnocode.co.uk>2015-04-20 00:13:34 +0100
commitd8a40c6e4172ba26f57e65041667b5266f88fed1 (patch)
treee02b028f478ce25e93078e4917076ab49db9066d /gdata/gdata-upload-stream.c
parentde74263ff38a9d3e9672b833e5883393b3a9854c (diff)
downloadlibgdata-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.c79
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 */