[phodav: 13/18] wip: move method lock



commit ba7c6debcf5890c81395d47831717d397fda0126
Author: Marc-André Lureau <marcandre lureau gmail com>
Date:   Thu Apr 10 19:07:48 2014 +0200

    wip: move method lock

 Makefile.am                    |    1 +
 libphodav/phodav-method-lock.c |  246 ++++++++++++++++++++++++++++++++++++++++
 libphodav/phodav-priv.h        |    4 +
 libphodav/phodav-server.c      |  227 +------------------------------------
 4 files changed, 254 insertions(+), 224 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index fb90999..51c61b3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,6 +36,7 @@ libphodav_1_0_la_SOURCES =                    \
        libphodav/phodav-if.c                   \
        libphodav/phodav-method-delete.c        \
        libphodav/phodav-method-get.c           \
+       libphodav/phodav-method-lock.c          \
        libphodav/phodav-method-mkcol.c         \
        libphodav/phodav-method-movecopy.c      \
        libphodav/phodav-method-propfind.c      \
diff --git a/libphodav/phodav-method-lock.c b/libphodav/phodav-method-lock.c
new file mode 100644
index 0000000..e7e74c0
--- /dev/null
+++ b/libphodav/phodav-method-lock.c
@@ -0,0 +1,246 @@
+/* -*- 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-priv.h"
+
+#include "guuid.h"
+#include "phodav-multistatus.h"
+#include "phodav-path.h"
+#include "phodav-lock.h"
+#include "phodav-utils.h"
+
+static gboolean G_GNUC_PURE
+check_lock (const gchar *key, Path *path, gpointer data)
+{
+  DAVLock *lock = data;
+  DAVLock *other = NULL;
+  GList *l;
+
+  for (l = path->locks; l; l = l->next)
+    {
+      other = l->data;
+      if (other->scope == LOCK_SCOPE_EXCLUSIVE)
+        return FALSE;
+    }
+
+  if (other && lock->scope == LOCK_SCOPE_EXCLUSIVE)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+try_add_lock (PhodavServer *server, const gchar *path, DAVLock *lock)
+{
+  Path *p;
+
+  if (!server_foreach_parent_path (server, path, check_lock, lock))
+    return FALSE;
+
+  p = server_get_path (server, path);
+  path_add_lock (p, lock);
+
+  return TRUE;
+}
+
+static gboolean
+lock_ensure_file (PathHandler *handler, const char *path,
+                  GCancellable *cancellable, GError **err)
+{
+  GError *e = NULL;
+  GFileOutputStream *stream = NULL;
+  GFile *file = NULL;
+  gboolean created = FALSE;
+
+  file = g_file_get_child (handler_get_file (handler), path + 1);
+  stream = g_file_create (file, G_FILE_CREATE_NONE, cancellable, &e);
+  created = !!stream;
+
+  if (e)
+    {
+      if (g_error_matches (e, G_IO_ERROR, G_IO_ERROR_EXISTS))
+        g_clear_error (&e);
+      else
+        g_propagate_error (err, e);
+    }
+
+  g_clear_object (&stream);
+  g_clear_object (&file);
+
+  return created;
+}
+
+static LockScopeType
+parse_lockscope (xmlNodePtr rt)
+{
+  xmlNodePtr node;
+
+  for (node = rt->children; node; node = node->next)
+    if (xml_node_is_element (node))
+      break;
+
+  if (node == NULL)
+    return LOCK_SCOPE_NONE;
+
+  if (!g_strcmp0 ((char *) node->name, "exclusive"))
+    return LOCK_SCOPE_EXCLUSIVE;
+  else if (!g_strcmp0 ((char *) node->name, "shared"))
+    return LOCK_SCOPE_SHARED;
+  else
+    return LOCK_SCOPE_NONE;
+}
+
+static LockType
+parse_locktype (xmlNodePtr rt)
+{
+  xmlNodePtr node;
+
+  for (node = rt->children; node; node = node->next)
+    if (xml_node_is_element (node))
+      break;
+
+  if (node == NULL)
+    return LOCK_NONE;
+
+  if (!g_strcmp0 ((char *) node->name, "write"))
+    return LOCK_WRITE;
+  else
+    return LOCK_NONE;
+}
+
+gint
+phodav_method_lock (PathHandler *handler, SoupMessage *msg,
+                    const char *path, GError **err)
+{
+  GCancellable *cancellable = handler_get_cancellable (handler);
+  Path *lpath = NULL;
+  xmlChar *mem = NULL;
+  int size = 0;
+  DavDoc doc = {0, };
+  xmlNodePtr node = NULL, owner = NULL, root = NULL;
+  xmlNsPtr ns = NULL;
+  LockScopeType scope = LOCK_SCOPE_SHARED;
+  LockType type;
+  DepthType depth;
+  guint timeout;
+  gchar *ltoken = NULL, *uuid = NULL, *token = NULL;
+  DAVLock *lock = NULL;
+  gint status = SOUP_STATUS_BAD_REQUEST;
+  gboolean created;
+
+  depth = depth_from_string (soup_message_headers_get_one (msg->request_headers, "Depth"));
+  timeout = timeout_from_string (soup_message_headers_get_one (msg->request_headers, "Timeout"));
+
+  if (depth != DEPTH_ZERO && depth != DEPTH_INFINITY)
+    goto end;
+
+  if (!msg->request_body->length)
+    {
+      const gchar *hif = soup_message_headers_get_one (msg->request_headers, "If");
+      gint len = strlen (hif);
+
+      if (len <= 4 || hif[0] != '(' || hif[1] != '<' || hif[len - 2] != '>' || hif[len - 1] != ')')
+        goto end;
+
+      token = g_strndup (hif + 2, len - 4);
+
+      g_debug ("refresh token %s", token);
+      lock = server_path_get_lock (handler_get_server (handler), path, token);
+
+      if (!lock)
+        goto end;
+
+      dav_lock_refresh_timeout (lock, timeout);
+      status = SOUP_STATUS_OK;
+      goto body;
+    }
+
+  if (!davdoc_parse (&doc, msg, msg->request_body, "lockinfo"))
+    goto end;
+
+  node = doc.root;
+  for (node = node->children; node; node = node->next)
+    {
+      if (!xml_node_is_element (node))
+        continue;
+
+      if (xml_node_has_name (node, "lockscope"))
+        {
+          scope = parse_lockscope (node);
+          if (scope == LOCK_SCOPE_NONE)
+            break;
+        }
+      else if (xml_node_has_name (node, "locktype"))
+        {
+          type = parse_locktype (node);
+          if (type == LOCK_NONE)
+            break;
+        }
+      else if (xml_node_has_name (node, "owner"))
+        {
+          if (owner == NULL)
+            owner = node;
+          else
+            g_warn_if_reached ();
+        }
+    }
+
+  g_debug ("lock depth:%d scope:%d type:%d owner:%p, timeout: %u",
+           depth, scope, type, owner, timeout);
+
+  uuid = g_uuid_random ();
+  token = g_strdup_printf ("urn:uuid:%s", uuid);
+  ltoken = g_strdup_printf ("<%s>", token);
+  soup_message_headers_append (msg->response_headers, "Lock-Token", ltoken);
+
+  lpath = server_get_path (handler_get_server (handler), path);
+  lock = dav_lock_new (lpath, token, scope, type, depth, owner, timeout);
+  if (!try_add_lock (handler_get_server (handler), path, lock))
+    {
+      g_warning ("lock failed");
+      dav_lock_free (lock);
+      status = SOUP_STATUS_LOCKED;
+      goto end;
+    }
+
+  created = lock_ensure_file (handler, path, cancellable, err);
+  if (*err)
+    goto end;
+
+  status = created ? SOUP_STATUS_CREATED : SOUP_STATUS_OK;
+
+body:
+  root = xmlNewNode (NULL, BAD_CAST "prop");
+  ns = xmlNewNs (root, BAD_CAST "DAV:", BAD_CAST "D");
+  xmlSetNs (root, ns);
+
+  node = xmlNewChild (root, ns, BAD_CAST "lockdiscovery", NULL);
+  xmlAddChild (node, dav_lock_get_activelock_node (lock, ns));
+
+  xml_node_to_string (root, &mem, &size);
+  soup_message_set_response (msg, "application/xml",
+                             SOUP_MEMORY_TAKE, (gchar *) mem, size);
+
+end:
+  g_free (ltoken);
+  g_free (token);
+  g_free (uuid);
+  davdoc_free (&doc);
+
+  return status;
+}
diff --git a/libphodav/phodav-priv.h b/libphodav/phodav-priv.h
index e96f0f7..c960476 100644
--- a/libphodav/phodav-priv.h
+++ b/libphodav/phodav-priv.h
@@ -95,6 +95,8 @@ DAVLock *               server_path_get_lock                 (PhodavServer *serv
 gboolean                server_path_has_other_locks          (PhodavServer *self,
                                                               const gchar *path,
                                                               GList *locks);
+Path *                  server_get_path                      (PhodavServer *self,
+                                                              const gchar *_path);
 
 gint                    phodav_check_if                      (PathHandler *handler, SoupMessage *msg,
                                                               const gchar *path, GList **locks);
@@ -115,6 +117,8 @@ gint                    phodav_method_delete                 (PathHandler *handl
                                                               const char *path, GError **err);
 gint                    phodav_method_movecopy               (PathHandler *handler, SoupMessage *msg,
                                                               const char *path, GError **err);
+gint                    phodav_method_lock                   (PathHandler *handler, SoupMessage *msg,
+                                                              const char *path, GError **err);
 
 
 G_END_DECLS
diff --git a/libphodav/phodav-server.c b/libphodav/phodav-server.c
index 9b82120..74bdab4 100644
--- a/libphodav/phodav-server.c
+++ b/libphodav/phodav-server.c
@@ -77,8 +77,8 @@ static void request_started (SoupServer        *server,
                              SoupClientContext *client,
                              gpointer           user_data);
 
-static Path *
-get_path (PhodavServer *self, const gchar *_path)
+Path *
+server_get_path (PhodavServer *self, const gchar *_path)
 {
   Path *p;
   gchar *path = g_strdup (_path);
@@ -293,44 +293,6 @@ phodav_server_class_init (PhodavServerClass *klass)
                           G_PARAM_STATIC_STRINGS));
 }
 
-static LockScopeType
-parse_lockscope (xmlNodePtr rt)
-{
-  xmlNodePtr node;
-
-  for (node = rt->children; node; node = node->next)
-    if (xml_node_is_element (node))
-      break;
-
-  if (node == NULL)
-    return LOCK_SCOPE_NONE;
-
-  if (!g_strcmp0 ((char *) node->name, "exclusive"))
-    return LOCK_SCOPE_EXCLUSIVE;
-  else if (!g_strcmp0 ((char *) node->name, "shared"))
-    return LOCK_SCOPE_SHARED;
-  else
-    return LOCK_SCOPE_NONE;
-}
-
-static LockType
-parse_locktype (xmlNodePtr rt)
-{
-  xmlNodePtr node;
-
-  for (node = rt->children; node; node = node->next)
-    if (xml_node_is_element (node))
-      break;
-
-  if (node == NULL)
-    return LOCK_NONE;
-
-  if (!g_strcmp0 ((char *) node->name, "write"))
-    return LOCK_WRITE;
-  else
-    return LOCK_NONE;
-}
-
 gboolean
 server_foreach_parent_path (PhodavServer *self, const gchar *path, PathCb cb, gpointer data)
 {
@@ -461,189 +423,6 @@ server_path_has_other_locks (PhodavServer *self, const gchar *path, GList *locks
   return !server_foreach_parent_path (self, path, other_lock_exists, locks);
 }
 
-static gboolean G_GNUC_PURE
-check_lock (const gchar *key, Path *path, gpointer data)
-{
-  DAVLock *lock = data;
-  DAVLock *other = NULL;
-  GList *l;
-
-  for (l = path->locks; l; l = l->next)
-    {
-      other = l->data;
-      if (other->scope == LOCK_SCOPE_EXCLUSIVE)
-        return FALSE;
-    }
-
-  if (other && lock->scope == LOCK_SCOPE_EXCLUSIVE)
-    return FALSE;
-
-  return TRUE;
-}
-
-static gboolean
-try_add_lock (PhodavServer *self, const gchar *path, DAVLock *lock)
-{
-  Path *p;
-
-  if (!server_foreach_parent_path (self, path, check_lock, lock))
-    return FALSE;
-
-  p = get_path (self, path);
-  path_add_lock (p, lock);
-
-  return TRUE;
-}
-
-static gboolean
-lock_ensure_file (PathHandler *handler, const char *path,
-                  GCancellable *cancellable, GError **err)
-{
-  GError *e = NULL;
-  GFileOutputStream *stream = NULL;
-  GFile *file = NULL;
-  gboolean created = FALSE;
-
-  file = g_file_get_child (handler->file, path + 1);
-  stream = g_file_create (file, G_FILE_CREATE_NONE, cancellable, &e);
-  created = !!stream;
-
-  if (e)
-    {
-      if (g_error_matches (e, G_IO_ERROR, G_IO_ERROR_EXISTS))
-        g_clear_error (&e);
-      else
-        g_propagate_error (err, e);
-    }
-
-  g_clear_object (&stream);
-  g_clear_object (&file);
-
-  return created;
-}
-
-static gint
-method_lock (PathHandler *handler, SoupMessage *msg,
-             const char *path, GError **err)
-{
-  PhodavServer *self = handler->self;
-  Path *lpath = NULL;
-  xmlChar *mem = NULL;
-  int size = 0;
-  DavDoc doc = {0, };
-  xmlNodePtr node = NULL, owner = NULL, root = NULL;
-  xmlNsPtr ns = NULL;
-  LockScopeType scope = LOCK_SCOPE_SHARED;
-  LockType type;
-  DepthType depth;
-  guint timeout;
-  gchar *ltoken = NULL, *uuid = NULL, *token = NULL;
-  DAVLock *lock = NULL;
-  gint status = SOUP_STATUS_BAD_REQUEST;
-  gboolean created;
-
-  depth = depth_from_string (soup_message_headers_get_one (msg->request_headers, "Depth"));
-  timeout = timeout_from_string (soup_message_headers_get_one (msg->request_headers, "Timeout"));
-
-  if (depth != DEPTH_ZERO && depth != DEPTH_INFINITY)
-    goto end;
-
-  if (!msg->request_body->length)
-    {
-      const gchar *hif = soup_message_headers_get_one (msg->request_headers, "If");
-      gint len = strlen (hif);
-
-      if (len <= 4 || hif[0] != '(' || hif[1] != '<' || hif[len - 2] != '>' || hif[len - 1] != ')')
-        goto end;
-
-      token = g_strndup (hif + 2, len - 4);
-
-      g_debug ("refresh token %s", token);
-      lock = server_path_get_lock (self, path, token);
-
-      if (!lock)
-        goto end;
-
-      dav_lock_refresh_timeout (lock, timeout);
-      status = SOUP_STATUS_OK;
-      goto body;
-    }
-
-  if (!davdoc_parse (&doc, msg, msg->request_body, "lockinfo"))
-    goto end;
-
-  node = doc.root;
-  for (node = node->children; node; node = node->next)
-    {
-      if (!xml_node_is_element (node))
-        continue;
-
-      if (xml_node_has_name (node, "lockscope"))
-        {
-          scope = parse_lockscope (node);
-          if (scope == LOCK_SCOPE_NONE)
-            break;
-        }
-      else if (xml_node_has_name (node, "locktype"))
-        {
-          type = parse_locktype (node);
-          if (type == LOCK_NONE)
-            break;
-        }
-      else if (xml_node_has_name (node, "owner"))
-        {
-          if (owner == NULL)
-            owner = node;
-          else
-            g_warn_if_reached ();
-        }
-    }
-
-  g_debug ("lock depth:%d scope:%d type:%d owner:%p, timeout: %u",
-           depth, scope, type, owner, timeout);
-
-  uuid = g_uuid_random ();
-  token = g_strdup_printf ("urn:uuid:%s", uuid);
-  ltoken = g_strdup_printf ("<%s>", token);
-  soup_message_headers_append (msg->response_headers, "Lock-Token", ltoken);
-
-  lpath = get_path (self, path);
-  lock = dav_lock_new (lpath, token, scope, type, depth, owner, timeout);
-  if (!try_add_lock (self, path, lock))
-    {
-      g_warning ("lock failed");
-      dav_lock_free (lock);
-      status = SOUP_STATUS_LOCKED;
-      goto end;
-    }
-
-  created = lock_ensure_file (handler, path, self->cancellable, err);
-  if (*err)
-    goto end;
-
-  status = created ? SOUP_STATUS_CREATED : SOUP_STATUS_OK;
-
-body:
-  root = xmlNewNode (NULL, BAD_CAST "prop");
-  ns = xmlNewNs (root, BAD_CAST "DAV:", BAD_CAST "D");
-  xmlSetNs (root, ns);
-
-  node = xmlNewChild (root, ns, BAD_CAST "lockdiscovery", NULL);
-  xmlAddChild (node, dav_lock_get_activelock_node (lock, ns));
-
-  xml_node_to_string (root, &mem, &size);
-  soup_message_set_response (msg, "application/xml",
-                             SOUP_MEMORY_TAKE, (gchar *) mem, size);
-
-end:
-  g_free (ltoken);
-  g_free (token);
-  g_free (uuid);
-  davdoc_free (&doc);
-
-  return status;
-}
-
 static gchar *
 remove_brackets (const gchar *str)
 {
@@ -837,7 +616,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
            msg->method == SOUP_METHOD_COPY)
     status = phodav_method_movecopy (handler, msg, path, &err);
   else if (msg->method == SOUP_METHOD_LOCK)
-    status = method_lock (handler, msg, path, &err);
+    status = phodav_method_lock (handler, msg, path, &err);
   else if (msg->method == SOUP_METHOD_UNLOCK)
     status = method_unlock (handler, msg, path, &err);
   else


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