diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c index 80a3e31a6..11bda8ca8 100644 --- a/gio/gnetworkaddress.c +++ b/gio/gnetworkaddress.c @@ -526,6 +526,8 @@ _g_uri_parse_authority (const char *uri, /* If IPv6 or IPvFuture */ if (*p == '[') { + start++; + p++; while (1) { c = *p++; @@ -625,6 +627,46 @@ error: return FALSE; } +gchar * +_g_uri_from_authority (const gchar *protocol, + const gchar *host, + guint port, + const gchar *userinfo) +{ + GString *uri; + + uri = g_string_new (protocol); + g_string_append (uri, "://"); + + if (userinfo) + { + g_string_append_uri_escaped (uri, userinfo, G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, FALSE); + g_string_append_c (uri, '@'); + } + + if (g_hostname_is_non_ascii (host)) + { + gchar *ace_encoded = g_hostname_to_ascii (host); + + if (!ace_encoded) + { + g_string_free (uri, TRUE); + return NULL; + } + g_string_append (uri, ace_encoded); + g_free (ace_encoded); + } + else if (strchr (host, ':')) + g_string_append_printf (uri, "[%s]", host); + else + g_string_append (uri, host); + + if (port != 0) + g_string_append_printf (uri, ":%u", port); + + return g_string_free (uri, FALSE); +} + /** * g_network_address_parse_uri: * @uri: the hostname and optionally a port @@ -920,9 +962,10 @@ g_network_address_connectable_proxy_enumerate (GSocketConnectable *connectable) GSocketAddressEnumerator *proxy_enum; gchar *uri; - uri = g_strdup_printf ("%s://%s:%u", - self->priv->scheme ? self->priv->scheme : "none", - self->priv->hostname, self->priv->port); + uri = _g_uri_from_authority (self->priv->scheme ? self->priv->scheme : "none", + self->priv->hostname, + self->priv->port, + NULL); proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, "connectable", connectable, diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h index 9434adf14..92d2645b0 100644 --- a/gio/gnetworkingprivate.h +++ b/gio/gnetworkingprivate.h @@ -124,6 +124,10 @@ gboolean _g_uri_parse_authority (const char *uri, char **host, guint16 *port, char **userinfo); +gchar * _g_uri_from_authority (const gchar *protocol, + const gchar *host, + guint port, + const gchar *userinfo); G_END_DECLS diff --git a/gio/gnetworkservice.c b/gio/gnetworkservice.c index e46126a8a..b1d934d5f 100644 --- a/gio/gnetworkservice.c +++ b/gio/gnetworkservice.c @@ -31,6 +31,7 @@ #include "ginetsocketaddress.h" #include "gioerror.h" #include "gnetworkaddress.h" +#include "gnetworkingprivate.h" #include "gresolver.h" #include "gsimpleasyncresult.h" #include "gsocketaddressenumerator.h" @@ -438,10 +439,10 @@ g_network_service_address_enumerator_next (GSocketAddressEnumerator *enumerator continue; } - uri = g_strdup_printf ("%s://%s:%u", - g_network_service_get_scheme (srv_enum->srv), - hostname, - g_srv_target_get_port (target)); + uri = _g_uri_from_authority (g_network_service_get_scheme (srv_enum->srv), + hostname, + g_srv_target_get_port (target), + NULL); g_free (hostname); addr = g_network_address_parse_uri (uri, diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c index 49220b457..d4dcbb047 100644 --- a/gio/gsocketaddress.c +++ b/gio/gsocketaddress.c @@ -372,7 +372,7 @@ g_socket_address_connectable_proxy_enumerate (GSocketConnectable *connectable) g_object_get (connectable, "address", &addr, "port", &port, NULL); ip = g_inet_address_to_string (addr); - uri = g_strdup_printf ("none://%s:%u", ip, port); + uri = _g_uri_from_authority ("none", ip, port, NULL); addr_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, "connectable", connectable,