[gupnp] all: Use proper address for link-local



commit b8a5d47f9f0c406d5550d4fc2061b439410c1fb8
Author: Jens Georg <mail jensge org>
Date:   Tue Nov 20 00:21:00 2018 +0100

    all: Use proper address for link-local

 libgupnp/gupnp-context.c       | 42 ++++++++++++++++++++++++++++++++++++++++++
 libgupnp/gupnp-context.h       |  4 ++++
 libgupnp/gupnp-control-point.c |  7 ++++++-
 libgupnp/gupnp-service-info.c  | 12 +++++++++++-
 libgupnp/gupnp-service-proxy.c | 37 +++++++++++++++++++++++++++----------
 libgupnp/gupnp-service.c       | 10 +++++++++-
 libgupnp/http-headers.c        |  2 ++
 7 files changed, 101 insertions(+), 13 deletions(-)
---
diff --git a/libgupnp/gupnp-context.c b/libgupnp/gupnp-context.c
index ab9187c..aad034f 100644
--- a/libgupnp/gupnp-context.c
+++ b/libgupnp/gupnp-context.c
@@ -1597,3 +1597,45 @@ gupnp_context_remove_server_handler (GUPnPContext *context, const char *path)
         priv = gupnp_context_get_instance_private (context);
         soup_server_remove_handler (priv->server, path);
 }
+
+/**
+ * gupnp_context_rewrite_uri:
+ * @context: a #GUPnPContext
+ * @uri: an uri to rewrite if necessary
+ *
+ * Returns: A re-written version of the @uri if the context is on a link-local
+ * IPv6 address, a copy of the @uri otherwise.
+ *
+ * Since: 1.11.1
+ */
+char *
+gupnp_context_rewrite_uri (GUPnPContext *context, const char *plain_uri)
+{
+        const char *host = NULL;
+        SoupURI *uri = NULL;
+        GInetAddress *addr = NULL;
+        char *retval = NULL;
+        int index = -1;
+
+        uri = soup_uri_new (plain_uri);
+        host = soup_uri_get_host (uri);
+        addr = g_inet_address_new_from_string (host);
+        index = gssdp_client_get_index (GSSDP_CLIENT (context));
+
+        if (g_inet_address_get_is_link_local (addr) &&
+            g_inet_address_get_family (addr) == G_SOCKET_FAMILY_IPV6) {
+                char *new_host;
+
+                new_host = g_strdup_printf ("%s%%%d",
+                                            host,
+                                            index);
+                soup_uri_set_host (uri, new_host);
+                g_free (new_host);
+        }
+
+        g_object_unref (addr);
+        retval = soup_uri_to_string (uri, FALSE);
+        soup_uri_free (uri);
+
+        return retval;
+}
diff --git a/libgupnp/gupnp-context.h b/libgupnp/gupnp-context.h
index ab56d62..db9a173 100644
--- a/libgupnp/gupnp-context.h
+++ b/libgupnp/gupnp-context.h
@@ -106,6 +106,10 @@ gupnp_context_add_server_handler       (GUPnPContext *context,
 void
 gupnp_context_remove_server_handler    (GUPnPContext *context,
                                         const char *path);
+
+char *
+gupnp_context_rewrite_uri              (GUPnPContext *context,
+                                        const char *uri);
 G_END_DECLS
 
 #endif /* GUPNP_CONTEXT_H */
diff --git a/libgupnp/gupnp-control-point.c b/libgupnp/gupnp-control-point.c
index eb93c8c..44f20a2 100644
--- a/libgupnp/gupnp-control-point.c
+++ b/libgupnp/gupnp-control-point.c
@@ -709,6 +709,7 @@ load_description (GUPnPControlPoint *control_point,
                 GUPnPContext *context;
                 SoupSession *session;
                 GetDescriptionURLData *data;
+                char *local_description = NULL;
 
                 context = gupnp_control_point_get_context (control_point);
 
@@ -718,8 +719,12 @@ load_description (GUPnPControlPoint *control_point,
 
                 data->tries = max_tries;
                 data->timeout = timeout;
+                local_description = gupnp_context_rewrite_uri (context,
+                                                               description_url);
                 data->message = soup_message_new (SOUP_METHOD_GET,
-                                                  description_url);
+                                                  local_description);
+                g_free (local_description);
+
                 if (data->message == NULL) {
                         g_warning ("Invalid description URL: %s",
                                    description_url);
diff --git a/libgupnp/gupnp-service-info.c b/libgupnp/gupnp-service-info.c
index 69d711f..2733ec4 100644
--- a/libgupnp/gupnp-service-info.c
+++ b/libgupnp/gupnp-service-info.c
@@ -27,6 +27,8 @@
  * service information.
  */
 
+#define G_LOG_DOMAIN "GUPnPServiceInfo"
+
 #include <libsoup/soup.h>
 #include <string.h>
 
@@ -729,9 +731,17 @@ gupnp_service_info_get_introspection_async_full
 
         data->message = NULL;
         if (scpd_url != NULL) {
-                data->message = soup_message_new (SOUP_METHOD_GET, scpd_url);
+                GUPnPContext *context = NULL;
+                char *local_scpd_url = NULL;
+
+                context = gupnp_service_info_get_context (info);
 
+                local_scpd_url = gupnp_context_rewrite_uri (context, scpd_url);
                 g_free (scpd_url);
+
+                data->message = soup_message_new (SOUP_METHOD_GET,
+                                                  local_scpd_url);
+                g_free (local_scpd_url);
         }
 
         if (data->message == NULL) {
diff --git a/libgupnp/gupnp-service-proxy.c b/libgupnp/gupnp-service-proxy.c
index 9c262e5..58b8b1e 100644
--- a/libgupnp/gupnp-service-proxy.c
+++ b/libgupnp/gupnp-service-proxy.c
@@ -842,9 +842,18 @@ begin_action_msg (GUPnPServiceProxy              *proxy,
                                         (GUPNP_SERVICE_INFO (proxy));
 
         if (control_url != NULL) {
-                ret->msg = soup_message_new (SOUP_METHOD_POST, control_url);
+                GUPnPContext *context = NULL;
+                char *local_control_url = NULL;
 
+                context = gupnp_service_info_get_context
+                                        (GUPNP_SERVICE_INFO (proxy));
+
+                local_control_url = gupnp_context_rewrite_uri (context,
+                                                               control_url);
                 g_free (control_url);
+
+                ret->msg = soup_message_new (SOUP_METHOD_POST, local_control_url);
+                g_free (local_control_url);
         }
 
         if (ret->msg == NULL) {
@@ -2065,7 +2074,7 @@ subscription_expire (gpointer user_data)
         GUPnPContext *context;
         SoupMessage *msg;
         SoupSession *session;
-        char *sub_url, *timeout;
+        char *sub_url, *timeout, *local_sub_url;
 
         proxy = GUPNP_SERVICE_PROXY (user_data);
         priv = gupnp_service_proxy_get_instance_private (proxy);
@@ -2082,10 +2091,12 @@ subscription_expire (gpointer user_data)
         sub_url = gupnp_service_info_get_event_subscription_url
                                                 (GUPNP_SERVICE_INFO (proxy));
 
-        msg = soup_message_new (GENA_METHOD_SUBSCRIBE, sub_url);
-
+        local_sub_url = gupnp_context_rewrite_uri (context, sub_url);
         g_free (sub_url);
 
+        msg = soup_message_new (GENA_METHOD_SUBSCRIBE, local_sub_url);
+        g_free (local_sub_url);
+
         g_return_val_if_fail (msg != NULL, FALSE);
 
         /* Add headers */
@@ -2258,7 +2269,7 @@ subscribe (GUPnPServiceProxy *proxy)
                 priv->subscription_timeout_src = NULL;
         }
 
-       context = gupnp_service_info_get_context (GUPNP_SERVICE_INFO (proxy));
+        context = gupnp_service_info_get_context (GUPNP_SERVICE_INFO (proxy));
 
         /* Create subscription message */
         sub_url = gupnp_service_info_get_event_subscription_url
@@ -2266,9 +2277,13 @@ subscribe (GUPnPServiceProxy *proxy)
 
         msg = NULL;
         if (sub_url != NULL) {
-                msg = soup_message_new (GENA_METHOD_SUBSCRIBE, sub_url);
+                char *local_sub_url = NULL;
 
+                local_sub_url = gupnp_context_rewrite_uri (context, sub_url);
                 g_free (sub_url);
+
+                msg = soup_message_new (GENA_METHOD_SUBSCRIBE, local_sub_url);
+                g_free (local_sub_url);
         }
 
         if (msg == NULL) {
@@ -2359,16 +2374,18 @@ unsubscribe (GUPnPServiceProxy *proxy)
 
         if (priv->sid != NULL) {
                 SoupMessage *msg;
-                char *sub_url;
+                char *sub_url, *local_sub_url;
 
                 /* Create unsubscription message */
                 sub_url = gupnp_service_info_get_event_subscription_url
-                                                   (GUPNP_SERVICE_INFO (proxy));
-
-                msg = soup_message_new (GENA_METHOD_UNSUBSCRIBE, sub_url);
+                                                (GUPNP_SERVICE_INFO (proxy));
 
+                local_sub_url = gupnp_context_rewrite_uri (context, sub_url);
                 g_free (sub_url);
 
+                msg = soup_message_new (GENA_METHOD_UNSUBSCRIBE, local_sub_url);
+                g_free (local_sub_url);
+
                 if (msg != NULL) {
                         /* Add headers */
                         soup_message_headers_append (msg->request_headers,
diff --git a/libgupnp/gupnp-service.c b/libgupnp/gupnp-service.c
index 70e1a48..db04ae6 100644
--- a/libgupnp/gupnp-service.c
+++ b/libgupnp/gupnp-service.c
@@ -1209,8 +1209,11 @@ subscribe (GUPnPService *service,
         SubscriptionData *data;
         char *start, *end, *uri;
         GUPnPServicePrivate *priv;
+        GUPnPContext *context;
 
         priv = gupnp_service_get_instance_private (service);
+        context = gupnp_service_info_get_context
+                                        (GUPNP_SERVICE_INFO (service));
 
         data = g_slice_new0 (SubscriptionData);
 
@@ -1226,8 +1229,13 @@ subscribe (GUPnPService *service,
                         break;
 
                 if (strncmp (start, "http://";, strlen ("http://";)) == 0) {
+                        char *local_uri;
+
                         uri = g_strndup (start, end - start);
-                        data->callbacks = g_list_append (data->callbacks, uri);
+                        local_uri = gupnp_context_rewrite_uri (context, uri);
+                        g_free (uri);
+
+                        data->callbacks = g_list_append (data->callbacks, local_uri);
                 }
 
                 start = end;
diff --git a/libgupnp/http-headers.c b/libgupnp/http-headers.c
index ffaa36a..120aa87 100644
--- a/libgupnp/http-headers.c
+++ b/libgupnp/http-headers.c
@@ -26,6 +26,8 @@
 #include <string.h>
 #include <gio/gio.h>
 
+#include <libsoup/soup.h>
+
 #include "http-headers.h"
 
 /* Converts @lang from HTTP language tag format into locale format.


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