[gnome-software/wip/temp/ubuntu-xenial-rebased: 249/329] Split out snapd-specific utilities
- From: Iain Lane <iainl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/temp/ubuntu-xenial-rebased: 249/329] Split out snapd-specific utilities
- Date: Fri, 29 Apr 2016 14:06:16 +0000 (UTC)
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]