i = 0;
while (uris[i] != NULL)
{
- #ifdef HAVE_LIBSOUP_2_27_90
- gchar* path;
- gchar* hostname = sokoke_hostname_from_uri (uris[i], &path);
- gchar* encoded = g_hostname_to_ascii (hostname);
-
- if (encoded)
- {
- gchar* res = g_strconcat ("http://", encoded, path, NULL);
- g_free (uris[i]);
- g_free (encoded);
- uris[i] = res;
- }
- g_free (hostname);
- #else
- uris[i] = sokoke_idn_to_punycode (uris[i]);
- #endif
+ gchar* new_uri = sokoke_uri_to_ascii (uris[i]);
+ katze_assign (uris[i], new_uri);
i++;
}
result = midori_app_instance_send_uris (app, uris);
return TRUE;
}
-#if defined (HAVE_LIBSOUP_2_27_90) || HAVE_LIBIDN
/**
* sokoke_hostname_from_uri:
* @uri: an URI string
hostname = g_strdup (uri);
return hostname;
}
-#endif
/**
- * sokoke_idn_to_punycode:
+ * sokoke_hostname_to_ascii:
+ * @uri: an URI string
+ *
+ * The specified hostname is encoded if it is not ASCII.
+ *
+ * If no IDN support is available at compile time,
+ * the hostname will be returned unaltered.
+ *
+ * Return value: a newly allocated hostname
+ **/
+static gchar*
+sokoke_hostname_to_ascii (const gchar* hostname)
+{
+ #ifdef HAVE_LIBSOUP_2_27_90
+ return g_hostname_to_ascii (hostname);
+ #elif HAVE_LIBIDN
+ uint32_t* q;
+ char* encoded;
+ int rc;
+
+ if ((q = stringprep_utf8_to_ucs4 (hostname, -1, NULL)))
+ {
+ rc = idna_to_ascii_4z (q, &encoded, IDNA_ALLOW_UNASSIGNED);
+ free (q);
+ if (rc == IDNA_SUCCESS)
+ return encoded;
+ }
+ #endif
+ return g_strdup (hostname);
+}
+
+/**
+ * sokoke_uri_to_ascii:
* @uri: an URI string
*
* The specified URI is parsed and the hostname
* part of it is encoded if it is not ASCII.
*
- * If libIDN is not available at compile time,
- * this code will pass the string unaltered.
- *
- * The called function owns the passed string.
+ * If no IDN support is available at compile time,
+ * the URI will be returned unaltered.
*
- * Return value: a newly allocated ASCII URI
+ * Return value: a newly allocated URI
**/
gchar*
-sokoke_idn_to_punycode (gchar* uri)
+sokoke_uri_to_ascii (const gchar* uri)
{
- #if HAVE_LIBIDN
gchar* proto;
- gchar* hostname;
- gchar* path;
- char *s;
- uint32_t *q;
- int rc;
- gchar *result;
if ((proto = g_utf8_strchr (uri, -1, ':')))
{
gulong offset;
gchar* buffer;
- /* 'file' URIs don't have a hostname */
- if (!strcmp (proto, "file"))
- return uri;
-
offset = g_utf8_pointer_to_offset (uri, proto);
buffer = g_malloc0 (offset + 1);
g_utf8_strncpy (buffer, uri, offset);
proto = buffer;
}
- hostname = sokoke_hostname_from_uri (uri, &path);
-
- if (!(q = stringprep_utf8_to_ucs4 (hostname, -1, NULL)))
- {
- g_free (proto);
- g_free (hostname);
- return uri;
- }
+ gchar* path;
+ gchar* hostname = sokoke_hostname_from_uri (uri, &path);
+ gchar* encoded = sokoke_hostname_to_ascii (hostname);
- rc = idna_to_ascii_4z (q, &s, IDNA_ALLOW_UNASSIGNED);
- free (q);
- if (rc != IDNA_SUCCESS)
+ if (encoded)
{
- g_free (proto);
- g_free (hostname);
- return uri;
+ gchar* res = g_strconcat (proto ? proto : "", proto ? "://" : "",
+ encoded, path, NULL);
+ g_free (encoded);
+ return res;
}
+ g_free (hostname);
+ return g_strdup (uri);
+}
- if (proto)
- {
- result = g_strconcat (proto, "://", s, path ? path : "", NULL);
- g_free (proto);
- if (path)
- g_free (hostname);
- }
- else
- result = g_strdup (s);
+static gchar*
+sokoke_idn_to_punycode (gchar* uri)
+{
+ #if HAVE_LIBIDN
+ gchar* result = sokoke_uri_to_ascii (uri);
g_free (uri);
- free (s);
-
return result;
#else
return uri;
gchar** path);
gchar*
-sokoke_idn_to_punycode (gchar* uri);
+sokoke_uri_to_ascii (const gchar* uri);
gchar*
sokoke_magic_uri (const gchar* uri,
static void
magic_uri_idn (void)
{
+ typedef struct
+ {
+ const gchar* before;
+ const gchar* after;
+ } URIItem;
+
+ static const URIItem items[] = {
+ #if HAVE_LIBIDN || defined (HAVE_LIBSOUP_2_27_90)
+ { "http://www.münchhausen.at", "http://www.xn--mnchhausen-9db.at" },
+ { "http://www.خداوند.com/", "http://www.xn--mgbndb8il.com/" },
+ { "айкидо.com", "xn--80aildf0a.com" },
+ { "http://東京理科大学.jp", "http://xn--1lq68wkwbj6ugkpigi.jp" },
+ { "https://青のネコ", "https://xn--u9jthzcs263c" },
+ #else
+ { "http://www.münchhausen.at", NULL },
+ { "http://www.خداوند.com/", NULL },
+ { "айкидо.com", NULL },
+ { "http://東京理科大学.jp", NULL },
+ { "https://青のネコ.co.jp", NULL },
+ #endif
+ { "http://en.wikipedia.org/wiki/Kölsch_language", NULL },
+ { "file:///home/mark/frühstück", NULL },
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (items); i++)
+ {
+ gchar* result = sokoke_uri_to_ascii (items[i].before);
+ const gchar* after = items[i].after ? items[i].after : items[i].before;
+ sokoke_assert_str_equal (items[i].before, result, after);
+ g_free (result);
+ }
+
#if HAVE_LIBIDN
- test_input ("http://www.münchhausen.at", "http://www.xn--mnchhausen-9db.at");
- test_input ("http://www.خداوند.com/", "http://www.xn--mgbndb8il.com/");
test_input ("айкидо.com", "http://xn--80aildf0a.com");
- test_input ("http://東京理科大学.jp", "http://xn--1lq68wkwbj6ugkpigi.jp");
- test_input ("https://青のネコ", "https://xn--u9jthzcs263c");
#else
- test_input ("http://www.münchhausen.at", "http://www.münchhausen.at");
- test_input ("http://www.خداوند.com/", "http://www.خداوند.com/");
test_input ("айкидо.com", "http://айкидо.com");
- test_input ("http://東京理科大学.jp", "http://東京理科大学.jp");
- test_input ("https://青のネコ.co.jp", "https://青のネコ.co.jp");
#endif
- test_input ("http://en.wikipedia.org/wiki/Kölsch_language",
- "http://en.wikipedia.org/wiki/Kölsch_language");
- test_input ("en.wikipedia.org/wiki/Kölsch_language",
- "http://en.wikipedia.org/wiki/Kölsch_language");
test_input ("sm Küchenzubehör", SM "Küchenzubehör");
test_input ("sm 東京理科大学", SM "東京理科大学");
- test_input ("file:///home/mark/frühstück",
- "file:///home/mark/frühstück");
}
static void