Add initial support for libsoup backend
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Mon, 27 Oct 2008 02:43:49 +0000 (00:43 -0200)
committerThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Mon, 27 Oct 2008 02:48:07 +0000 (00:48 -0200)
backend/Makefile.am
backend/soup/Makefile.am [new file with mode: 0644]
backend/soup/soup.c [new file with mode: 0644]
configure.ac

index 0f36893..e54ffc1 100644 (file)
@@ -1 +1 @@
-SUBDIRS = files gio
+SUBDIRS = files gio soup
diff --git a/backend/soup/Makefile.am b/backend/soup/Makefile.am
new file mode 100644 (file)
index 0000000..4792c35
--- /dev/null
@@ -0,0 +1,3 @@
+noinst_LTLIBRARIES = libsoup.la
+libsoup_la_SOURCES = soup.c
+libsoup_la_CFLAGS = -I$(top_srcdir)/include $(GLIB_CFLAGS) $(SOUP_CFLAGS)
diff --git a/backend/soup/soup.c b/backend/soup/soup.c
new file mode 100644 (file)
index 0000000..2e70307
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *  Copyright (C) 2008  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *
+ *  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 <glib.h>
+#include <libsoup/soup.h>
+#include <atompub/atom.h>
+#include <atompub/atom-glib.h>
+#include <string.h>
+
+SoupSession *session;
+
+static SoupMessage *
+soup_req_to_message (AtomCtx *ctx, char *req, char *method)
+{
+  gchar *root = atom_config_get_str (ctx, "soup", "root");
+  gchar *uri = g_build_filename (root, req, NULL);
+  SoupMessage *message = soup_message_new (method, uri);
+  g_free (root);
+  g_free (uri);
+  return message;
+}
+
+static AtomEntry *
+soup_message_to_atom (AtomCtx *ctx, SoupMessage *message)
+{
+  AtomEntry *atom;
+  if (message->status_code != 200)
+    {
+      AtomError *aerr = atom_error_new ();
+      atom_error_set_code (aerr, message->status_code);
+      atom_error_set_message (aerr, message->reason_phrase);
+      atom_error_set (ctx, aerr);
+      return NULL;
+    }
+  atom = atom_entry_new_data_len (message->response_body->data,
+                                  message->response_body->length);
+  return atom;
+}
+
+static void
+soup_atom_to_message (AtomCtx *ctx, AtomEntry *entry, SoupMessage *message)
+{
+  gchar *data = NULL;
+  gsize len = 0;
+  atom_entry_string (entry, &data, &len);
+  soup_message_set_request (message, "application/atom+xml",
+                            SOUP_MEMORY_COPY, data, len);
+  g_free (data);
+}
+
+static AtomEntry *
+soup_atom_retrieve_entry (AtomCtx *ctx, char *req)
+{
+  SoupMessage *message;
+  AtomEntry *atom;
+  message = soup_req_to_message (ctx, req, "GET");
+  soup_session_send_message (session, message);
+  atom = soup_message_to_atom (ctx, message);
+  g_object_unref (message);
+  return atom;
+}
+
+static void
+soup_atom_publish_entry (AtomCtx *ctx, char *req, AtomEntry *entry)
+{
+  SoupMessage *message;
+  /* TODO: Create a function to map from an Entry ID to a new filename */
+  if (req == NULL)
+    req = atom_entry_id (entry);
+  message = soup_req_to_message (ctx, req, "POST");
+  soup_atom_to_message (ctx, entry, message);
+  soup_message_headers_append (message->request_headers, "Slug", req);
+  soup_session_send_message (session, message);
+  if (message->status_code != 201)
+    {
+      AtomError *aerr = atom_error_new ();
+      atom_error_set_code (aerr, message->status_code);
+      atom_error_set_message (aerr, message->reason_phrase);
+      atom_error_set (ctx, aerr);
+    }
+  g_object_unref (message);
+}
+
+AtomBackend *
+soup_backend (void)
+{
+  AtomBackend *backend;
+  session = soup_session_sync_new ();
+  backend = atom_backend_new ();
+  atom_backend_retrieve_entry_set (backend, soup_atom_retrieve_entry);
+  atom_backend_publish_entry_set (backend, soup_atom_publish_entry);
+  return backend;
+}
index d2ad06d..2721da2 100644 (file)
@@ -7,6 +7,7 @@ AC_PROG_LIBTOOL
 PKG_CHECK_MODULES(XML, libxml-2.0, , AC_MSG_ERROR(Could not find libxml2))
 AM_PATH_GLIB_2_0(2.14.0, , AC_MSG_ERROR(Could not find GLib))
 PKG_CHECK_MODULES(GIO, gio-2.0, , AC_MSG_ERROR(Could not find GIO))
+PKG_CHECK_MODULES(SOUP, libsoup-2.4, , AC_MSG_ERROR(Could not find libsoup))
 AC_OUTPUT(Makefile
        src/Makefile
        include/Makefile
@@ -15,6 +16,7 @@ AC_OUTPUT(Makefile
        backend/Makefile
        backend/files/Makefile
        backend/gio/Makefile
+       backend/soup/Makefile
        frontend/Makefile
        frontend/cgi/Makefile
        atom/Makefile