diff options
-rw-r--r-- | libgupnp/gupnp-context.c | 42 | ||||
-rw-r--r-- | libgupnp/gupnp-context.h | 4 | ||||
-rw-r--r-- | libgupnp/gupnp-control-point.c | 7 | ||||
-rw-r--r-- | libgupnp/gupnp-service-info.c | 12 | ||||
-rw-r--r-- | libgupnp/gupnp-service-proxy.c | 37 | ||||
-rw-r--r-- | libgupnp/gupnp-service.c | 10 | ||||
-rw-r--r-- | 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. |