[gupnp/wip/acl: 15/15] wip: Add helper function to register acl-protected soup handler
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gupnp/wip/acl: 15/15] wip: Add helper function to register acl-protected soup handler
- Date: Sun, 19 Jan 2014 12:44:55 +0000 (UTC)
commit 945815fae1945218aeb633a01665a483fd018b55
Author: Jens Georg <mail jensge org>
Date: Sun Jan 19 13:44:16 2014 +0100
wip: Add helper function to register acl-protected soup handler
Signed-off-by: Jens Georg <mail jensge org>
libgupnp/gupnp-context.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++
libgupnp/gupnp-context.h | 8 +++
libgupnp/gupnp-service.c | 54 ++++++---------------
3 files changed, 145 insertions(+), 39 deletions(-)
---
diff --git a/libgupnp/gupnp-context.c b/libgupnp/gupnp-context.c
index 3046c84..fa66f26 100644
--- a/libgupnp/gupnp-context.c
+++ b/libgupnp/gupnp-context.c
@@ -59,6 +59,49 @@
#define GUPNP_CONTEXT_DEFAULT_LANGUAGE "en"
+typedef struct _GUPnPContextAclServerHandler
+{
+ GUPnPContext *context;
+ SoupServerHandler callback;
+ gpointer user_data;
+ GDestroyNotify notify;
+} GUPnPContextAclServerHandler;
+
+static GUPnPAclServerHandler *
+gupnp_acl_server_handler_new (GUPnPContext *context,
+ SoupServerHandler callback,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GUPnPAclServerHandler *handler = g_new0 (GUPnPContextAclServerHandler);
+
+ handler->context = g_object_ref (context);
+ handler->callback = callback;
+ handler->user_data = user_data;
+ handler->notify = notify;
+
+ return handler;
+}
+
+static void
+gupnp_acl_server_handler_free (GUPnPAclServerHandler *handler)
+{
+ g_clear_object (handler->context);
+
+ if (handler->notify != NULL)
+ handler->notify (handler->user_data);
+
+ g_free (handler);
+}
+
+static void
+gupnp_acl_server_handler (SoupServer *server,
+ SoupMessage *msg,
+ const char *path,
+ GHashTable *query,
+ SoupClientContext *client,
+ gpointer user_data);
+
static void
gupnp_context_initable_iface_init (gpointer g_iface,
gpointer iface_data);
@@ -1336,3 +1379,82 @@ gupnp_context_set_acl (GUPnPContext *context, GUPnPAcl *acl)
g_object_notify (G_OBJECT (context), "acl");
}
+
+static void
+gupnp_acl_server_handler (SoupServer *server,
+ SoupMessage *msg,
+ const char *path,
+ GHashTable *query,
+ SoupClientContext *client,
+ gpointer user_data)
+{
+ GUPnPContextAclServerHandler *handler = (GUPnPContextAclServerHandler *) user_data;
+
+ if (gupnp_acl_can_sync (handler->context->priv->acl)) {
+ if (!gupnp_acl_is_allowed (acl, soup_client_context_get_host (client))) {
+ soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
+
+ return;
+ }
+ } else {
+ g_warning ("TBD: Handle async ACL");
+ soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
+
+ return;
+ }
+
+ /* Delegate to orignal callback */
+ handler->callback (server, msg, path, query, client, handler->user_data);
+}
+
+/**
+ * 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.
+ * @path: the toplevel path for the handler.
+ * @callback: callback to invoke for requests under @path
+ * @user_data:
+ * @destroy:
+ */
+void
+gupnp_context_add_server_handler (GUPnPContext *context,
+ gboolean use_acl,
+ const char *path,
+ SoupServerCallback callback,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ g_return_if_fail (GUPNP_IS_CONTEXT (context));
+
+ if (use_acl) {
+ GUPnPContextAclServerHandler *handler;
+ handler = gupnp_acl_server_handler_new (callback, user_data, destroy);
+ soup_server_add_handler (self->priv->server,
+ path,
+ gupnp_acl_server_handler,
+ handler,
+ (GDestroyNotify) gupnp_acl_server_handler_free);
+ } else
+ soup_server_add_handler (self->priv->server,
+ path,
+ callback,
+ user_data,
+ destroy);
+}
+
+/**
+ * gupnp_context_remove_server_handler:
+ * @context:
+ * @path:
+ */
+void
+gupnp_context_remove_server_handler (GUPnPContext *context, const char *path)
+{
+ g_return_if_fail (GUPNP_IS_CONTEXT (context));
+
+ soup_server_remove_handler (context->priv->server, path);
+}
diff --git a/libgupnp/gupnp-context.h b/libgupnp/gupnp-context.h
index d0556e9..233d2fa 100644
--- a/libgupnp/gupnp-context.h
+++ b/libgupnp/gupnp-context.h
@@ -137,6 +137,14 @@ gupnp_context_get_acl (GUPnPContext *context);
void
gupnp_context_set_acl (GUPnPContext *context,
GUPnPAcl *acl);
+
+void
+gupnp_context_add_server_handler (GUPnPContext *context,
+ gboolean use_acl,
+ const char *path,
+ SoupServerCallback callback,
+ gpointer user_data,
+ GDestroyNotify destroy);
G_END_DECLS
#endif /* __GUPNP_CONTEXT_H__ */
diff --git a/libgupnp/gupnp-service.c b/libgupnp/gupnp-service.c
index faacc37..22e3cd6 100644
--- a/libgupnp/gupnp-service.c
+++ b/libgupnp/gupnp-service.c
@@ -941,20 +941,6 @@ control_server_handler (SoupServer *server,
context = gupnp_service_info_get_context (GUPNP_SERVICE_INFO (service));
- acl = gupnp_context_get_acl (context);
-
- if (acl) {
- if (gupnp_acl_can_sync (acl)) {
- if (!gupnp_acl_is_allowed (acl, "127.0.0.1")) {
- soup_message_set_status (msg, SOUP_STATUS_PROXY_UNAUTHORIZED);
-
- return;
- } else {
- g_warning ("TBD: Handle async ACL");
- }
- }
- }
-
/* Get action name */
soap_action = soup_message_headers_get_one (msg->request_headers,
"SOAPAction");
@@ -1324,20 +1310,6 @@ subscription_server_handler (G_GNUC_UNUSED SoupServer *server,
service = GUPNP_SERVICE (user_data);
- context = gupnp_service_info_get_context (GUPNP_SERVICE_INFO (service));
- acl = gupnp_context_get_acl (context);
- if (acl) {
- if (gupnp_acl_can_sync (acl)) {
- if (!gupnp_acl_is_allowed (acl, "127.0.0.1")) {
- soup_message_set_status (msg, SOUP_STATUS_PROXY_UNAUTHORIZED);
-
- return;
- } else {
- g_warning ("TBD: Handle async ACL");
- }
- }
- }
-
callback = soup_message_headers_get_one (msg->request_headers,
"Callback");
nt = soup_message_headers_get_one (msg->request_headers, "NT");
@@ -1464,7 +1436,6 @@ gupnp_service_constructor (GType type,
GObject *object;
GUPnPServiceInfo *info;
GUPnPContext *context;
- SoupServer *server;
char *url;
char *path;
@@ -1475,7 +1446,7 @@ gupnp_service_constructor (GType type,
n_construct_params,
construct_params);
- info = GUPNP_SERVICE_INFO (object);
+ info = GUPNP_SERVICE_INFO (object);
/* Get introspection and save state variable names */
gupnp_service_info_get_introspection_async (info,
@@ -1484,21 +1455,28 @@ gupnp_service_constructor (GType type,
/* Get server */
context = gupnp_service_info_get_context (info);
- server = gupnp_context_get_server (context);
/* Run listener on controlURL */
url = gupnp_service_info_get_control_url (info);
path = path_from_url (url);
- soup_server_add_handler (server, path,
- control_server_handler, object, NULL);
+ gupnp_context_add_server_handler (context,
+ TRUE,
+ path,
+ control_server_handler,
+ object,
+ NULL);
g_free (path);
g_free (url);
/* Run listener on eventSubscriptionURL */
url = gupnp_service_info_get_event_subscription_url (info);
path = path_from_url (url);
- soup_server_add_handler (server, path,
- subscription_server_handler, object, NULL);
+ gupnp_context_add_server_handler (context,
+ TRUE,
+ path,
+ subscription_server_handler,
+ object,
+ NULL);
g_free (path);
g_free (url);
@@ -1585,7 +1563,6 @@ gupnp_service_dispose (GObject *object)
GObjectClass *object_class;
GUPnPServiceInfo *info;
GUPnPContext *context;
- SoupServer *server;
char *url;
char *path;
@@ -1594,19 +1571,18 @@ gupnp_service_dispose (GObject *object)
/* Get server */
info = GUPNP_SERVICE_INFO (service);
context = gupnp_service_info_get_context (info);
- server = gupnp_context_get_server (context);
/* Remove listener on controlURL */
url = gupnp_service_info_get_control_url (info);
path = path_from_url (url);
- soup_server_remove_handler (server, path);
+ gupnp_context_remove_server_handler (server, path);
g_free (path);
g_free (url);
/* Remove listener on eventSubscriptionURL */
url = gupnp_service_info_get_event_subscription_url (info);
path = path_from_url (url);
- soup_server_remove_handler (server, path);
+ gupnp_context_remove_server_handler (server, path);
g_free (path);
g_free (url);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]