[gnome-software/wip/temp/ubuntu-xenial-rebased: 249/329] Split out snapd-specific utilities



commit b63ac638111bc3a5bc6e0ae7373ca9b73a6fd631
Author: William Hua <william hua canonical com>
Date:   Fri Apr 15 19:11:31 2016 -0400

    Split out snapd-specific utilities

 src/plugins/Makefile.am        |    9 +-
 src/plugins/gs-plugin-snappy.c |  179 +-----------------------------------
 src/plugins/gs-ubuntu-snapd.c  |  198 ++++++++++++++++++++++++++++++++++++++++
 src/plugins/gs-ubuntu-snapd.h  |   40 ++++++++
 4 files changed, 246 insertions(+), 180 deletions(-)
---
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 9398e66..8cf7e21 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -188,10 +188,13 @@ libgs_plugin_ubuntu_reviews_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
 endif
 
 libgs_plugin_ubuntu_reviews_la_SOURCES =               \
-       gs-ubuntuone.c                                  \
-       gs-ubuntuone.h                                  \
        gs-plugin-ubuntu-reviews.c                      \
-       gs-ubuntuone-dialog.c
+       gs-ubuntuone.h                                  \
+       gs-ubuntuone.c                                  \
+       gs-ubuntuone-dialog.h                           \
+       gs-ubuntuone-dialog.c                           \
+       gs-ubuntu-snapd.h                               \
+       gs-ubuntu-snapd.c
 libgs_plugin_ubuntu_reviews_la_LIBADD =                        \
        $(GS_PLUGIN_LIBS)                               \
        $(SOUP_LIBS)                                    \
diff --git a/src/plugins/gs-plugin-snappy.c b/src/plugins/gs-plugin-snappy.c
index 605c8df..28d9393 100644
--- a/src/plugins/gs-plugin-snappy.c
+++ b/src/plugins/gs-plugin-snappy.c
@@ -19,24 +19,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <config.h>
-#include <glib/gi18n.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
 #include <gs-plugin.h>
-#include <gio/gunixsocketaddress.h>
-#include <libsoup/soup.h>
+#include <glib/gi18n.h>
 #include <json-glib/json-glib.h>
+#include "gs-ubuntu-snapd.h"
 
 // snapd API documentation is at https://github.com/ubuntu-core/snappy/blob/master/docs/rest.md
 
 struct GsPluginPrivate {
 };
 
-#define SNAPD_SOCKET_PATH "/run/snapd.socket"
-
 typedef gboolean (*AppFilterFunc)(const gchar *id, JsonObject *object, gpointer data);
 
 const gchar *
@@ -52,173 +44,6 @@ gs_plugin_initialize (GsPlugin *plugin)
        plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
 }
 
-static GSocket *
-open_snapd_socket (GError **error)
-{
-       GSocket *socket;
-       g_autoptr(GSocketAddress) address = NULL;
-       g_autoptr(GError) sub_error = NULL;
-
-       socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, 
&sub_error);
-       if (!socket) {
-               g_set_error (error,
-                            GS_PLUGIN_ERROR,
-                            GS_PLUGIN_ERROR_FAILED,
-                            "Unable to open snapd socket: %s", sub_error->message);
-               return NULL;
-       }
-       address = g_unix_socket_address_new (SNAPD_SOCKET_PATH);
-       if (!g_socket_connect (socket, address, NULL, &sub_error)) {
-               g_set_error (error,
-                            GS_PLUGIN_ERROR,
-                            GS_PLUGIN_ERROR_FAILED,
-                            "Unable to connect snapd socket: %s", sub_error->message);
-               g_object_unref (socket);
-               return NULL;
-       }
-
-       return socket;
-}
-
-static gboolean
-read_from_snapd (GSocket *socket, gchar *buffer, gsize buffer_length, gsize *read_offset, GError **error)
-{
-       gssize n_read;
-       n_read = g_socket_receive (socket, buffer + *read_offset, buffer_length - *read_offset, NULL, error);
-       if (n_read < 0)
-               return FALSE;
-       *read_offset += n_read;
-       buffer[*read_offset] = '\0';
-
-       return TRUE;
-}
-
-static gboolean
-send_snapd_request (GSocket *socket,
-                   const gchar *method,
-                   const gchar *path,
-                   const gchar *content,
-                   guint *status_code,
-                   gchar **reason_phrase,
-                   gchar **response_type,
-                   gchar **response,
-                   gsize *response_length,
-                   GError **error)
-{
-       g_autoptr (GString) request = NULL;
-       gssize n_written;
-       gsize max_data_length = 65535, data_length = 0, header_length;
-       gchar data[max_data_length + 1], *body = NULL;
-       g_autoptr (SoupMessageHeaders) headers = NULL;
-       gsize chunk_length, n_required;
-       gchar *chunk_start = NULL;
-
-       // NOTE: Would love to use libsoup but it doesn't support unix sockets
-       // https://bugzilla.gnome.org/show_bug.cgi?id=727563
-
-       request = g_string_new ("");
-       g_string_append_printf (request, "%s %s HTTP/1.1\r\n", method, path);
-       g_string_append (request, "Host:\r\n");
-       if (content)
-               g_string_append_printf (request, "Content-Length: %zi\r\n", strlen (content));
-       g_string_append (request, "\r\n");
-       if (content)
-               g_string_append (request, content);
-
-       /* Send HTTP request */
-       n_written = g_socket_send (socket, request->str, request->len, NULL, error);
-       if (n_written < 0)
-               return FALSE;
-
-       /* Read HTTP headers */
-       while (data_length < max_data_length && !body) {
-               if (!read_from_snapd (socket, data, max_data_length, &data_length, error))
-                       return FALSE;
-               body = strstr (data, "\r\n\r\n");
-       }
-       if (!body) {
-               g_set_error_literal (error,
-                                    GS_PLUGIN_ERROR,
-                                    GS_PLUGIN_ERROR_FAILED,
-                                    "Unable to find header separator in snapd response");
-               return FALSE;
-       }
-
-       /* Body starts after header divider */
-       body += 4;
-       header_length = body - data;
-
-       /* Parse headers */
-       headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
-       if (!soup_headers_parse_response (data, header_length, headers, NULL, status_code, reason_phrase)) {
-               g_set_error_literal (error,
-                                    GS_PLUGIN_ERROR,
-                                    GS_PLUGIN_ERROR_FAILED,
-                                    "snapd response HTTP headers not parseable");
-               return FALSE;
-       }
-
-       /* Work out how much data to follow */
-       if (g_strcmp0 (soup_message_headers_get_one (headers, "Transfer-Encoding"), "chunked") == 0) {
-               while (data_length < max_data_length) {
-                       chunk_start = strstr (body, "\r\n");
-                       if (chunk_start)
-                               break;
-                       if (!read_from_snapd (socket, data, max_data_length, &data_length, error))
-                               return FALSE;
-               }
-               if (!chunk_start) {
-                       g_set_error_literal (error,
-                                            GS_PLUGIN_ERROR,
-                                            GS_PLUGIN_ERROR_FAILED,
-                                            "Unable to find chunk header in snapd response");
-                       return FALSE;
-               }
-               chunk_length = strtoul (body, NULL, 16);
-               chunk_start += 2;
-               // FIXME: Support multiple chunks
-       }
-       else {
-               const gchar *value;
-               value = soup_message_headers_get_one (headers, "Content-Length");
-               if (!value) {
-                       g_set_error_literal (error,
-                                            GS_PLUGIN_ERROR,
-                                            GS_PLUGIN_ERROR_FAILED,
-                                            "Unable to determine content length of snapd response");
-                       return FALSE;
-               }
-               chunk_length = strtoul (value, NULL, 10);
-               chunk_start = body;
-       }
-
-       /* Check if enough space to read chunk */
-       n_required = (chunk_start - data) + chunk_length;
-       if (n_required > max_data_length) {
-               g_set_error (error,
-                            GS_PLUGIN_ERROR,
-                            GS_PLUGIN_ERROR_FAILED,
-                            "Not enough space for snapd response, require %zi octets, have %zi", n_required, 
max_data_length);
-               return FALSE;
-       }
-
-       /* Read chunk content */
-       while (data_length < n_required)
-               if (!read_from_snapd (socket, data, n_required - data_length, &data_length, error))
-                       return FALSE;
-
-       if (response_type)
-               *response_type = g_strdup (soup_message_headers_get_one (headers, "Content-Type"));
-       if (response) {
-               *response = g_malloc (chunk_length + 1);
-               memcpy (*response, chunk_start, chunk_length + 1);
-       }
-       if (response_length)
-               *response_length = chunk_length;
-
-       return TRUE;
-}
-
 static JsonParser *
 parse_result (const gchar *response, const gchar *response_type, GError **error)
 {
diff --git a/src/plugins/gs-ubuntu-snapd.c b/src/plugins/gs-ubuntu-snapd.c
new file mode 100644
index 0000000..d8dfef5
--- /dev/null
+++ b/src/plugins/gs-ubuntu-snapd.c
@@ -0,0 +1,198 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2016 Canonical Ltd
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <gs-plugin.h>
+#include <libsoup/soup.h>
+#include <gio/gunixsocketaddress.h>
+#include "gs-ubuntu-snapd.h"
+
+#define SNAPD_SOCKET_PATH "/run/snapd.socket"
+
+// snapd API documentation is at https://github.com/ubuntu-core/snappy/blob/master/docs/rest.md
+
+GSocket *
+open_snapd_socket (GError **error)
+{
+       GSocket *socket;
+       g_autoptr(GSocketAddress) address = NULL;
+       g_autoptr(GError) sub_error = NULL;
+
+       socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, 
&sub_error);
+       if (!socket) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "Unable to open snapd socket: %s", sub_error->message);
+               return NULL;
+       }
+       address = g_unix_socket_address_new (SNAPD_SOCKET_PATH);
+       if (!g_socket_connect (socket, address, NULL, &sub_error)) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "Unable to connect snapd socket: %s", sub_error->message);
+               g_object_unref (socket);
+               return NULL;
+       }
+
+       return socket;
+}
+
+static gboolean
+read_from_snapd (GSocket *socket, gchar *buffer, gsize buffer_length, gsize *read_offset, GError **error)
+{
+       gssize n_read;
+       n_read = g_socket_receive (socket, buffer + *read_offset, buffer_length - *read_offset, NULL, error);
+       if (n_read < 0)
+               return FALSE;
+       *read_offset += n_read;
+       buffer[*read_offset] = '\0';
+
+       return TRUE;
+}
+
+gboolean
+send_snapd_request (GSocket      *socket,
+                   const gchar  *method,
+                   const gchar  *path,
+                   const gchar  *content,
+                   guint        *status_code,
+                   gchar       **reason_phrase,
+                   gchar       **response_type,
+                   gchar       **response,
+                   gsize        *response_length,
+                   GError      **error)
+{
+       g_autoptr (GString) request = NULL;
+       gssize n_written;
+       gsize max_data_length = 65535, data_length = 0, header_length;
+       gchar data[max_data_length + 1], *body = NULL;
+       g_autoptr (SoupMessageHeaders) headers = NULL;
+       gsize chunk_length, n_required;
+       gchar *chunk_start = NULL;
+
+       // NOTE: Would love to use libsoup but it doesn't support unix sockets
+       // https://bugzilla.gnome.org/show_bug.cgi?id=727563
+
+       request = g_string_new ("");
+       g_string_append_printf (request, "%s %s HTTP/1.1\r\n", method, path);
+       g_string_append (request, "Host:\r\n");
+       if (content)
+               g_string_append_printf (request, "Content-Length: %zi\r\n", strlen (content));
+       g_string_append (request, "\r\n");
+       if (content)
+               g_string_append (request, content);
+
+       /* Send HTTP request */
+       n_written = g_socket_send (socket, request->str, request->len, NULL, error);
+       if (n_written < 0)
+               return FALSE;
+
+       /* Read HTTP headers */
+       while (data_length < max_data_length && !body) {
+               if (!read_from_snapd (socket, data, max_data_length, &data_length, error))
+                       return FALSE;
+               body = strstr (data, "\r\n\r\n");
+       }
+       if (!body) {
+               g_set_error_literal (error,
+                                    GS_PLUGIN_ERROR,
+                                    GS_PLUGIN_ERROR_FAILED,
+                                    "Unable to find header separator in snapd response");
+               return FALSE;
+       }
+
+       /* Body starts after header divider */
+       body += 4;
+       header_length = body - data;
+
+       /* Parse headers */
+       headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
+       if (!soup_headers_parse_response (data, header_length, headers, NULL, status_code, reason_phrase)) {
+               g_set_error_literal (error,
+                                    GS_PLUGIN_ERROR,
+                                    GS_PLUGIN_ERROR_FAILED,
+                                    "snapd response HTTP headers not parseable");
+               return FALSE;
+       }
+
+       /* Work out how much data to follow */
+       if (g_strcmp0 (soup_message_headers_get_one (headers, "Transfer-Encoding"), "chunked") == 0) {
+               while (data_length < max_data_length) {
+                       chunk_start = strstr (body, "\r\n");
+                       if (chunk_start)
+                               break;
+                       if (!read_from_snapd (socket, data, max_data_length, &data_length, error))
+                               return FALSE;
+               }
+               if (!chunk_start) {
+                       g_set_error_literal (error,
+                                            GS_PLUGIN_ERROR,
+                                            GS_PLUGIN_ERROR_FAILED,
+                                            "Unable to find chunk header in snapd response");
+                       return FALSE;
+               }
+               chunk_length = strtoul (body, NULL, 16);
+               chunk_start += 2;
+               // FIXME: Support multiple chunks
+       }
+       else {
+               const gchar *value;
+               value = soup_message_headers_get_one (headers, "Content-Length");
+               if (!value) {
+                       g_set_error_literal (error,
+                                            GS_PLUGIN_ERROR,
+                                            GS_PLUGIN_ERROR_FAILED,
+                                            "Unable to determine content length of snapd response");
+                       return FALSE;
+               }
+               chunk_length = strtoul (value, NULL, 10);
+               chunk_start = body;
+       }
+
+       /* Check if enough space to read chunk */
+       n_required = (chunk_start - data) + chunk_length;
+       if (n_required > max_data_length) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "Not enough space for snapd response, require %zi octets, have %zi", n_required, 
max_data_length);
+               return FALSE;
+       }
+
+       /* Read chunk content */
+       while (data_length < n_required)
+               if (!read_from_snapd (socket, data, n_required - data_length, &data_length, error))
+                       return FALSE;
+
+       if (response_type)
+               *response_type = g_strdup (soup_message_headers_get_one (headers, "Content-Type"));
+       if (response) {
+               *response = g_malloc (chunk_length + 1);
+               memcpy (*response, chunk_start, chunk_length + 1);
+       }
+       if (response_length)
+               *response_length = chunk_length;
+
+       return TRUE;
+}
diff --git a/src/plugins/gs-ubuntu-snapd.h b/src/plugins/gs-ubuntu-snapd.h
new file mode 100644
index 0000000..d2211b7
--- /dev/null
+++ b/src/plugins/gs-ubuntu-snapd.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2016 Canonical Ltd
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GS_UBUNTU_SNAPD_H__
+#define __GS_UBUNTU_SNAPD_H__
+
+#include <gio/gio.h>
+
+GSocket * open_snapd_socket  (GError      **error);
+
+gboolean  send_snapd_request (GSocket      *socket,
+                             const gchar  *method,
+                             const gchar  *path,
+                             const gchar  *content,
+                             guint        *status_code,
+                             gchar       **reason_phrase,
+                             gchar       **response_type,
+                             gchar       **response,
+                             gsize        *response_length,
+                             GError      **error);
+
+#endif /* __GS_UBUNTU_SNAPD_H__ */


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