[phodav: 2/18] wip
- From: Marc-Andre Lureau <malureau src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [phodav: 2/18] wip
- Date: Thu, 10 Apr 2014 17:51:15 +0000 (UTC)
commit dc672a5e161fb9ca5f3aa95f15fd306fc4edcb2c
Author: Marc-André Lureau <marcandre lureau gmail com>
Date: Thu Apr 10 16:08:53 2014 +0200
wip
Makefile.am | 4 +
libphodav/phodav-multistatus.c | 135 +++++++++++++++++++++++++++++++++++++
libphodav/phodav-multistatus.h | 40 +++++++++++
libphodav/phodav-server.c | 144 ++--------------------------------------
libphodav/phodav-utils.c | 33 +++++++++
libphodav/phodav-utils.h | 29 ++++++++
6 files changed, 246 insertions(+), 139 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 0296ab9..0e15c78 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,8 +33,12 @@ libphodav_1_0_la_SOURCES = \
libphodav/phodav-path.h \
libphodav/phodav-lock.c \
libphodav/phodav-lock.h \
+ libphodav/phodav-multistatus.c \
+ libphodav/phodav-multistatus.h \
libphodav/phodav-server.c \
libphodav/phodav-server.h \
+ libphodav/phodav-utils.c \
+ libphodav/phodav-utils.h \
$(NULL)
libphodav_1_0_la_CFLAGS = \
diff --git a/libphodav/phodav-multistatus.c b/libphodav/phodav-multistatus.c
new file mode 100644
index 0000000..f9ecd44
--- /dev/null
+++ b/libphodav/phodav-multistatus.c
@@ -0,0 +1,135 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "phodav-utils.h"
+#include "phodav-multistatus.h"
+
+Response *
+response_new (GList *props, gint status)
+{
+ Response *r;
+
+ g_return_val_if_fail (props != NULL || status > 0, NULL);
+
+ r = g_slice_new0 (Response);
+ r->status = status;
+ r->props = props;
+
+ return r;
+}
+
+void
+response_free (Response *h)
+{
+ g_list_free_full (h->props, (GDestroyNotify) xmlFreeNode);
+ g_slice_free (Response, h);
+}
+
+static gchar*
+status_to_string (gint status)
+{
+ return g_strdup_printf ("HTTP/1.1 %d %s",
+ status, soup_status_get_phrase (status));
+}
+
+static xmlNodePtr
+status_node_new (xmlNsPtr ns, gint status)
+{
+ xmlNodePtr node;
+ gchar *text;
+
+ text = status_to_string (status);
+ node = xmlNewNode (ns, BAD_CAST "status");
+ xmlAddChild (node, xmlNewText (BAD_CAST text));
+ g_free (text);
+
+ return node;
+}
+
+static void
+add_propstat (xmlNodePtr parent, xmlNsPtr ns, SoupMessage *msg,
+ const gchar *path, GList *props)
+{
+ xmlNodePtr node, propstat, prop = NULL, stnode = NULL;
+ GList *s;
+ gint status = -1;
+
+ /* better if sorted by status */
+ for (s = props; s != NULL; s = s->next)
+ {
+ node = s->data;
+ if (GPOINTER_TO_INT (node->_private) != status)
+ {
+ status = GPOINTER_TO_INT (node->_private);
+ if (stnode)
+ xmlAddChild (propstat, stnode);
+
+ stnode = status_node_new (ns, status);
+ propstat = xmlNewChild (parent, ns, BAD_CAST "propstat", NULL);
+ prop = xmlNewChild (propstat, ns, BAD_CAST "prop", NULL);
+ }
+ g_return_if_fail (prop != NULL);
+ xmlAddChild (prop, node);
+ s->data = NULL;
+ }
+
+ if (stnode)
+ xmlAddChild (propstat, stnode);
+}
+
+gint
+set_response_multistatus (SoupMessage *msg,
+ GHashTable *mstatus)
+{
+ xmlChar *mem = NULL;
+ int size;
+ xmlNodePtr root;
+ GHashTableIter iter;
+ Response *resp;
+ gchar *path, *text;
+ xmlNsPtr ns;
+
+ root = xmlNewNode (NULL, BAD_CAST "multistatus");
+ ns = xmlNewNs (root, BAD_CAST "DAV:", BAD_CAST "D");
+ xmlSetNs (root, ns);
+
+ g_hash_table_iter_init (&iter, mstatus);
+ while (g_hash_table_iter_next (&iter, (gpointer *) &path, (gpointer *) &resp))
+ {
+ xmlNodePtr response;
+ SoupURI *new_uri;
+
+ response = xmlNewChild (root, ns, BAD_CAST "response", NULL);
+ new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), path);
+ text = soup_uri_to_string (new_uri, FALSE);
+ xmlNewChild (response, ns, BAD_CAST "href", BAD_CAST text);
+ g_free (text);
+ soup_uri_free (new_uri);
+
+ if (resp->props)
+ add_propstat (response, ns, msg, path, resp->props);
+ else if (resp->status)
+ xmlAddChild (response, status_node_new (ns, resp->status));
+ }
+
+ xml_node_to_string (root, &mem, &size);
+ soup_message_set_response (msg, "application/xml",
+ SOUP_MEMORY_TAKE, (gchar *) mem, size);
+
+ return SOUP_STATUS_MULTI_STATUS;
+}
diff --git a/libphodav/phodav-multistatus.h b/libphodav/phodav-multistatus.h
new file mode 100644
index 0000000..480f8ac
--- /dev/null
+++ b/libphodav/phodav-multistatus.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __PHODAV_MULTISTATUS_H__
+#define __PHODAV_MULTISTATUS_H__
+
+#include <libsoup/soup.h>
+#include "phodav-priv.h"
+
+G_BEGIN_DECLS
+
+typedef struct _Response
+{
+ GList *props;
+ gint status;
+} Response;
+
+Response * response_new (GList *props,
+ gint status);
+void response_free (Response *h);
+
+gint set_response_multistatus (SoupMessage *msg,
+ GHashTable *mstatus);
+G_END_DECLS
+
+#endif /* __PHODAV_MULTISTATUS_H__ */
diff --git a/libphodav/phodav-server.c b/libphodav/phodav-server.c
index 9bea109..fc6dc84 100644
--- a/libphodav/phodav-server.c
+++ b/libphodav/phodav-server.c
@@ -25,6 +25,7 @@
#include "guuid.h"
#include "phodav-server.h"
+#include "phodav-multistatus.h"
#include "phodav-path.h"
#include "phodav-lock.h"
@@ -134,33 +135,6 @@ path_handler_free (PathHandler *h)
g_slice_free (PathHandler, h);
}
-typedef struct _Response
-{
- GList *props;
- gint status;
-} Response;
-
-static Response*
-response_new (GList *props, gint status)
-{
- Response *r;
-
- g_return_val_if_fail (props != NULL || status > 0, NULL);
-
- r = g_slice_new0 (Response);
- r->status = status;
- r->props = props;
-
- return r;
-}
-
-static void
-response_free (Response *h)
-{
- g_list_free_full (h->props, (GDestroyNotify) xmlFreeNode);
- g_slice_free (Response, h);
-}
-
static void
phodav_server_init (PhodavServer *self)
{
@@ -762,20 +736,6 @@ end:
return pf;
}
-static void
-node_to_string (xmlNodePtr root, xmlChar **mem, int *size)
-{
- xmlDocPtr doc;
-
- doc = xmlNewDoc (BAD_CAST "1.0");
- xmlDocSetRootElement (doc, root);
- // xmlReconciliateNs
- xmlDocDumpMemoryEnc (doc, mem, size, "utf-8");
- /* FIXME: validate document? */
- /*FIXME, pretty print?*/
- xmlFreeDoc (doc);
-}
-
#define PROP_SET_STATUS(Node, Status) G_STMT_START { \
(Node)->_private = GINT_TO_POINTER (Status); \
} G_STMT_END
@@ -803,13 +763,6 @@ end:
return node;
}
-static gchar*
-status_to_string (gint status)
-{
- return g_strdup_printf ("HTTP/1.1 %d %s",
- status, soup_status_get_phrase (status));
-}
-
static gint
node_compare_int (xmlNodePtr a,
xmlNodePtr b)
@@ -1538,93 +1491,6 @@ end:
return status;
}
-static xmlNodePtr
-status_node_new (xmlNsPtr ns, gint status)
-{
- xmlNodePtr node;
- gchar *text;
-
- text = status_to_string (status);
- node = xmlNewNode (ns, BAD_CAST "status");
- xmlAddChild (node, xmlNewText (BAD_CAST text));
- g_free (text);
-
- return node;
-}
-
-static void
-add_propstat (xmlNodePtr parent, xmlNsPtr ns, SoupMessage *msg,
- const gchar *path, GList *props)
-{
- xmlNodePtr node, propstat, prop = NULL, stnode = NULL;
- GList *s;
- gint status = -1;
-
- /* better if sorted by status */
- for (s = props; s != NULL; s = s->next)
- {
- node = s->data;
- if (GPOINTER_TO_INT (node->_private) != status)
- {
- status = GPOINTER_TO_INT (node->_private);
- if (stnode)
- xmlAddChild (propstat, stnode);
-
- stnode = status_node_new (ns, status);
- propstat = xmlNewChild (parent, ns, BAD_CAST "propstat", NULL);
- prop = xmlNewChild (propstat, ns, BAD_CAST "prop", NULL);
- }
- g_return_if_fail (prop != NULL);
- xmlAddChild (prop, node);
- s->data = NULL;
- }
-
- if (stnode)
- xmlAddChild (propstat, stnode);
-}
-
-static gint
-response_multistatus (SoupMessage *msg,
- GHashTable *mstatus)
-{
- xmlChar *mem = NULL;
- int size;
- xmlNodePtr root;
- GHashTableIter iter;
- Response *resp;
- gchar *path, *text;
- xmlNsPtr ns;
-
- root = xmlNewNode (NULL, BAD_CAST "multistatus");
- ns = xmlNewNs (root, BAD_CAST "DAV:", BAD_CAST "D");
- xmlSetNs (root, ns);
-
- g_hash_table_iter_init (&iter, mstatus);
- while (g_hash_table_iter_next (&iter, (gpointer *) &path, (gpointer *) &resp))
- {
- xmlNodePtr response;
- SoupURI *new_uri;
-
- response = xmlNewChild (root, ns, BAD_CAST "response", NULL);
- new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), path);
- text = soup_uri_to_string (new_uri, FALSE);
- xmlNewChild (response, ns, BAD_CAST "href", BAD_CAST text);
- g_free (text);
- soup_uri_free (new_uri);
-
- if (resp->props)
- add_propstat (response, ns, msg, path, resp->props);
- else if (resp->status)
- xmlAddChild (response, status_node_new (ns, resp->status));
- }
-
- node_to_string (root, &mem, &size);
- soup_message_set_response (msg, "application/xml",
- SOUP_MEMORY_TAKE, (gchar *) mem, size);
-
- return SOUP_STATUS_MULTI_STATUS;
-}
-
static gint
method_propfind (PathHandler *handler, SoupMessage *msg,
const char *path, GError **err)
@@ -1679,7 +1545,7 @@ method_propfind (PathHandler *handler, SoupMessage *msg,
if (status != SOUP_STATUS_OK)
goto end;
- status = response_multistatus (msg, mstatus);
+ status = set_response_multistatus (msg, mstatus);
end:
davdoc_free (&doc);
@@ -2236,7 +2102,7 @@ method_proppatch (PathHandler *handler, SoupMessage *msg,
response_new (props, 0));
if (g_hash_table_size (mstatus) > 0)
- status = response_multistatus (msg, mstatus);
+ status = set_response_multistatus (msg, mstatus);
end:
davdoc_free (&doc);
@@ -2384,7 +2250,7 @@ method_delete (PathHandler *handler, SoupMessage *msg,
status = do_delete_file (path, file, mstatus, self->cancellable);
if (status == SOUP_STATUS_NO_CONTENT)
if (g_hash_table_size (mstatus) > 0)
- status = response_multistatus (msg, mstatus);
+ status = set_response_multistatus (msg, mstatus);
end:
if (mstatus)
@@ -2740,7 +2606,7 @@ body:
node = xmlNewChild (root, ns, BAD_CAST "lockdiscovery", NULL);
xmlAddChild (node, get_activelock_node (lock, ns));
- node_to_string (root, &mem, &size);
+ xml_node_to_string (root, &mem, &size);
soup_message_set_response (msg, "application/xml",
SOUP_MEMORY_TAKE, (gchar *) mem, size);
diff --git a/libphodav/phodav-utils.c b/libphodav/phodav-utils.c
new file mode 100644
index 0000000..afab913
--- /dev/null
+++ b/libphodav/phodav-utils.c
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "phodav-utils.h"
+
+void
+xml_node_to_string (xmlNodePtr root, xmlChar **mem, int *size)
+{
+ xmlDocPtr doc;
+
+ doc = xmlNewDoc (BAD_CAST "1.0");
+ xmlDocSetRootElement (doc, root);
+ // xmlReconciliateNs
+ xmlDocDumpMemoryEnc (doc, mem, size, "utf-8");
+ /* FIXME: validate document? */
+ /*FIXME, pretty print?*/
+ xmlFreeDoc (doc);
+}
diff --git a/libphodav/phodav-utils.h b/libphodav/phodav-utils.h
new file mode 100644
index 0000000..f9c7c5d
--- /dev/null
+++ b/libphodav/phodav-utils.h
@@ -0,0 +1,29 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __PHODAV_UTILS_H__
+#define __PHODAV_UTILS_H__
+
+#include "phodav-priv.h"
+
+G_BEGIN_DECLS
+
+void xml_node_to_string (xmlNodePtr root, xmlChar **mem, int *size);
+
+G_END_DECLS
+
+#endif /* __PHODAV_UTILS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]