summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libgupnp/gupnp-context.c42
-rw-r--r--libgupnp/gupnp-context.h4
-rw-r--r--libgupnp/gupnp-control-point.c7
-rw-r--r--libgupnp/gupnp-service-info.c12
-rw-r--r--libgupnp/gupnp-service-proxy.c37
-rw-r--r--libgupnp/gupnp-service.c10
-rw-r--r--libgupnp/http-headers.c2
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.