[gupnp/wip/acl: 15/15] WIP



commit d135183769e4fcb953c48194b2aae956187ea328
Author: Jens Georg <mail jensge org>
Date:   Sat Feb 8 11:23:48 2014 +0100

    WIP

 configure.ac             |    2 +-
 libgupnp/gupnp-acl.c     |   38 +++++++-------
 libgupnp/gupnp-acl.h     |   20 ++++----
 libgupnp/gupnp-context.c |  125 +++++++++++++++++++++++++++++++++++++--------
 4 files changed, 131 insertions(+), 54 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 406d1fa..1856dfc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,7 +128,7 @@ AC_ARG_ENABLE(debug,
         AS_HELP_STRING([--enable-debug], [enable debugging]),,
         enable_debug=no)
 if test "x$enable_debug" = "xyes"; then
-        CFLAGS="$CFLAGS -g -Wall -Werror"
+        CFLAGS="$CFLAGS -g -Wall -Wextra -Werror"
 fi
 
 GOBJECT_INTROSPECTION_CHECK([0.6.4])
diff --git a/libgupnp/gupnp-acl.c b/libgupnp/gupnp-acl.c
index 57433fc..4a5abbf 100644
--- a/libgupnp/gupnp-acl.c
+++ b/libgupnp/gupnp-acl.c
@@ -21,7 +21,7 @@
 
 #include "gupnp-acl.h"
 
-G_DEFINE_INTERFACE(GUPnPAcl, gupnp_acl, 0)
+G_DEFINE_INTERFACE(GUPnPAcl, gupnp_acl, G_TYPE_OBJECT)
 
 static void
 gupnp_acl_default_init (GUPnPAclInterface *klass)
@@ -30,13 +30,12 @@ gupnp_acl_default_init (GUPnPAclInterface *klass)
 
 /**
  * gupnp_acl_is_allowed:
- *
- * Check whether an IP address is allowed to access this resource.
- *
  * @self: an instance of #GUPnPAcl
  * @address: IP address of the peer.
  * @returns: %TRUE if the peer is allowed, %FALSE otherwise
  *
+ * Check whether an IP address is allowed to access this resource.
+ *
  * Since: 0.21.0
  */
 gboolean
@@ -49,6 +48,12 @@ gupnp_acl_is_allowed (GUPnPAcl *self, const char *address)
 
 /**
  * gupnp_acl_is_allowed_async:
+ * @self: a #GUPnPAcl
+ * @address: IP address of the peer
+ * @cancellable: (allow-none): A #GCancellable which can be used to cancel the
+ * operation.
+ * @callback: Callback to call after the function is done.
+ * @user_data: Some user data.
  *
  * Optional. Check asynchronously whether an IP address is allowed to access
  * this resource. Use this function if the process of verifying the access right
@@ -58,21 +63,14 @@ gupnp_acl_is_allowed (GUPnPAcl *self, const char *address)
  *
  * Use gupnp_acl_is_allowed_finish() to retrieve the result.
  *
- * @self: a #GUPnPAcl
- * @address: IP address of the peer
- * @cancellable: (allow-none): A #GCancellable which can be used to cancel the
- * operation.
- * @callback: Callback to call after the function is done.
- * @user_data: Some user data.
- *
- * Since: 0.21.0
+* Since: 0.21.0
  */
 void
-gupnp_acl_is_allowed_async (GUPnPAcl            *self,
-                            const char          *address,
-                            GCancellable        *cancellable,
-                            GAsyncReadyCallback *callback,
-                            gpointer             user_data)
+gupnp_acl_is_allowed_async (GUPnPAcl           *self,
+                            const char         *address,
+                            GCancellable       *cancellable,
+                            GAsyncReadyCallback callback,
+                            gpointer            user_data)
 {
         g_return_if_fail (GUPNP_IS_ACL (self));
 
@@ -88,7 +86,7 @@ gupnp_acl_is_allowed_async (GUPnPAcl            *self,
  * @self: An instance of #GUPnPAcl
  * @res: %GAsyncResult obtained from the callback in gupnp_acl_is_allowed_async()
  * @error: (allow-none): A return location for a #GError describing the failure
- * @returns: %TRUE if the authentication was successful, %FALSE otherwise and on
+ * @returns %TRUE if the authentication was successful, %FALSE otherwise and on
  * error. Check @error for details.
  *
  * Since: 0.21.0
@@ -107,12 +105,12 @@ gupnp_acl_is_allowed_finish (GUPnPAcl      *self,
 
 /**
  * gupnp_acl_can_sync:
- * Check whether gupnp_acl_is_allowed_async() is supported.
- *
  * @self: A #GUPnPAcl
  * @returns: %TRUE, if gupnp_acl_is_allowed_async() is supported, %FALSE
  * otherwise.
  *
+ * Check whether gupnp_acl_is_allowed_async() is supported.
+ *
  * Since: 0.21.0
  */
 gboolean
diff --git a/libgupnp/gupnp-acl.h b/libgupnp/gupnp-acl.h
index 42bfc05..619b22d 100644
--- a/libgupnp/gupnp-acl.h
+++ b/libgupnp/gupnp-acl.h
@@ -55,11 +55,11 @@ struct _GUPnPAclInterface {
     gboolean (*is_allowed) (GUPnPAcl   *self,
                             const char *address);
 
-    void     (*is_allowed_async) (GUPnPAcl            *self,
-                                  const char          *address,
-                                  GCancellable        *cancellable,
-                                  GAsyncReadyCallback *callback,
-                                  gpointer             user_data);
+    void     (*is_allowed_async) (GUPnPAcl           *self,
+                                  const char         *address,
+                                  GCancellable       *cancellable,
+                                  GAsyncReadyCallback callback,
+                                  gpointer            user_data);
 
     gboolean (*is_allowed_finish) (GUPnPAcl      *self,
                                    GAsyncResult  *res,
@@ -79,11 +79,11 @@ gupnp_acl_is_allowed (GUPnPAcl   *self,
                       const char *address);
 
 void
-gupnp_acl_is_allowed_async (GUPnPAcl            *self,
-                            const char          *address,
-                            GCancellable        *cancellable,
-                            GAsyncReadyCallback *callback,
-                            gpointer             user_data);
+gupnp_acl_is_allowed_async (GUPnPAcl           *self,
+                            const char         *address,
+                            GCancellable       *cancellable,
+                            GAsyncReadyCallback callback,
+                            gpointer            user_data);
 
 gboolean
 gupnp_acl_is_allowed_finish (GUPnPAcl      *self,
diff --git a/libgupnp/gupnp-context.c b/libgupnp/gupnp-context.c
index 2919aa3..c906175 100644
--- a/libgupnp/gupnp-context.c
+++ b/libgupnp/gupnp-context.c
@@ -61,10 +61,10 @@
 
 typedef struct _GUPnPContextAclServerHandler
 {
-    GUPnPContext *context;
-    SoupServerCallback callback;
-    gpointer user_data;
-    GDestroyNotify notify;
+        GUPnPContext *context;
+        SoupServerCallback callback;
+        gpointer user_data;
+        GDestroyNotify notify;
 } GUPnPContextAclServerHandler;
 
 static GUPnPContextAclServerHandler *
@@ -73,25 +73,25 @@ gupnp_acl_server_handler_new (GUPnPContext *context,
                               gpointer user_data,
                               GDestroyNotify notify)
 {
-    GUPnPContextAclServerHandler *handler = g_new0 (GUPnPContextAclServerHandler, 1);
+        GUPnPContextAclServerHandler *handler = g_new0 (GUPnPContextAclServerHandler, 1);
 
-    handler->context = g_object_ref (context);
-    handler->callback = callback;
-    handler->user_data = user_data;
-    handler->notify = notify;
+        handler->context = g_object_ref (context);
+        handler->callback = callback;
+        handler->user_data = user_data;
+        handler->notify = notify;
 
-    return handler;
+        return handler;
 }
 
 static void
 gupnp_acl_server_handler_free (GUPnPContextAclServerHandler *handler)
 {
-    g_clear_object (&handler->context);
+        g_clear_object (&handler->context);
 
-    if (handler->notify != NULL)
-        handler->notify (handler->user_data);
+        if (handler->notify != NULL)
+                handler->notify (handler->user_data);
 
-    g_free (handler);
+        g_free (handler);
 }
 
 static void
@@ -556,6 +556,7 @@ gupnp_context_class_init (GUPnPContextClass *klass)
                                       "Access control list",
                                       GUPNP_TYPE_ACL,
                                       G_PARAM_CONSTRUCT |
+                                      G_PARAM_READWRITE |
                                       G_PARAM_STATIC_STRINGS));
 }
 
@@ -1372,14 +1373,84 @@ gupnp_context_set_acl (GUPnPContext *context, GUPnPAcl *acl)
 {
         g_return_if_fail (GUPNP_IS_CONTEXT (context));
 
-        if (context->priv->acl != NULL)
+        if (context->priv->acl != NULL) {
                 g_object_unref (context->priv->acl);
+                context->priv->acl = NULL;
+        }
 
-        context->priv->acl = g_object_ref (acl);
+        if (acl != NULL)
+                context->priv->acl = g_object_ref (acl);
 
         g_object_notify (G_OBJECT (context), "acl");
 }
 
+typedef struct _AsyncAclHandler
+{
+        SoupServer *server;
+        SoupMessage *message;
+        char *path;
+        GHashTable *query;
+        SoupClientContext *client;
+        GUPnPContextAclServerHandler *handler;
+} AsyncAclHandler;
+
+static AsyncAclHandler *
+async_acl_handler_new (SoupServer *server,
+                       SoupMessage *message,
+                       const char *path,
+                       GHashTable *query,
+                       SoupClientContext *client,
+                       GUPnPContextAclServerHandler *handler)
+{
+        AsyncAclHandler *data = g_slice_new0 (AsyncAclHandler);
+
+        data->server = g_object_ref (server);
+        data->message = g_object_ref (message);
+        data->path = g_strdup (path);
+        if (query != NULL)
+                data->query = g_hash_table_ref (query);
+        data->client = g_boxed_copy (SOUP_TYPE_CLIENT_CONTEXT, client);
+        data->handler = handler;
+
+        return data;
+}
+
+void
+async_acl_handler_free (AsyncAclHandler *handler)
+{
+        g_object_unref (handler->server);
+        g_object_unref (handler->message);
+        g_free (handler->path);
+        if (handler->query != NULL)
+                g_hash_table_unref (handler->query);
+        g_boxed_free (SOUP_TYPE_CLIENT_CONTEXT, handler->client);
+
+        g_slice_free (AsyncAclHandler, handler);
+}
+
+static void
+gupnp_acl_async_callback (GUPnPAcl *acl,
+                          GAsyncResult *res,
+                          AsyncAclHandler *data)
+{
+        gboolean allowed;
+        GError *error = NULL;
+
+        allowed = gupnp_acl_is_allowed_finish (acl, res, &error);
+        soup_server_unpause_message (data->server, data->message);
+        if (!allowed)
+                soup_message_set_status (data->message, SOUP_STATUS_FORBIDDEN);
+        else
+                data->handler->callback (data->server,
+                                         data->message,
+                                         data->path,
+                                         data->query,
+                                         data->client,
+                                         data->handler->user_data);
+
+        async_acl_handler_free (data);
+}
+
 static void
 gupnp_acl_server_handler (SoupServer *server,
                           SoupMessage *msg,
@@ -1398,8 +1469,16 @@ gupnp_acl_server_handler (SoupServer *server,
                         return;
                 }
         } else {
-                g_warning ("TBD: Handle async ACL");
-                soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
+                AsyncAclHandler *data;
+
+                data = async_acl_handler_new (server, msg, path, query, client, handler);
+
+                soup_server_pause_message (server, msg);
+                gupnp_acl_is_allowed_async (handler->context->priv->acl,
+                                            soup_client_context_get_host (client),
+                                            NULL,
+                                            (GAsyncReadyCallback) gupnp_acl_async_callback,
+                                            data);
 
                 return;
         }
@@ -1410,9 +1489,6 @@ gupnp_acl_server_handler (SoupServer *server,
 
 /**
  * gupnp_context_add_server_handler:
- *
- * Add a #SoupServerCallback to the #GUPnPContext<!-- -->'s #SoupServer.
- *
  * @context: a #GUPnPContext
  * @use_acl: %TRUE, if the path should query the GUPnPContext::acl before
  * serving the resource, %FALSE otherwise.
@@ -1420,6 +1496,9 @@ gupnp_acl_server_handler (SoupServer *server,
  * @callback: callback to invoke for requests under @path
  * @user_data:
  * @destroy:
+ *
+ * Add a #SoupServerCallback to the #GUPnPContext<!-- -->'s #SoupServer.
+ *
  */
 void
 gupnp_context_add_server_handler (GUPnPContext *context,
@@ -1455,7 +1534,7 @@ gupnp_context_add_server_handler (GUPnPContext *context,
 void
 gupnp_context_remove_server_handler (GUPnPContext *context, const char *path)
 {
-    g_return_if_fail (GUPNP_IS_CONTEXT (context));
+        g_return_if_fail (GUPNP_IS_CONTEXT (context));
 
-    soup_server_remove_handler (context->priv->server, path);
+        soup_server_remove_handler (context->priv->server, path);
 }


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