summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2013-08-19 15:44:12 -0400
committerDan Winship <danw@gnome.org>2013-08-19 16:04:06 -0400
commite43eef9705634317a7af7d1217793925b1b13ab9 (patch)
treeb1891198f93da6778fbc5c2633a98cefd2f0abf3
parentfe3735f81a8e1bfa5242904a94c30217a5101cbc (diff)
downloadlibsoup-e43eef9705634317a7af7d1217793925b1b13ab9.tar.gz
More IPv6 scope ID fixes
Don't include the scope ID in the "Host" header. Make SoupURI correctly parse both correct and incorrect scope IDs, and add checks for that in tests/uri-parsing.
-rw-r--r--libsoup/soup-message-client-io.c2
-rw-r--r--libsoup/soup-uri.c21
-rw-r--r--tests/uri-parsing.c8
3 files changed, 27 insertions, 4 deletions
diff --git a/libsoup/soup-message-client-io.c b/libsoup/soup-message-client-io.c
index 0d3df282..1d96729d 100644
--- a/libsoup/soup-message-client-io.c
+++ b/libsoup/soup-message-client-io.c
@@ -83,7 +83,7 @@ get_request_headers (SoupMessage *msg, GString *header,
const char *name, *value;
if (strchr (uri->host, ':'))
- uri_host = g_strdup_printf ("[%s]", uri->host);
+ uri_host = g_strdup_printf ("[%.*s]", (int) strcspn (uri->host, "%"), uri->host);
else if (g_hostname_is_non_ascii (uri->host))
uri_host = g_hostname_to_ascii (uri->host);
else
diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c
index 16098f69..6e3d220b 100644
--- a/libsoup/soup-uri.c
+++ b/libsoup/soup-uri.c
@@ -308,6 +308,8 @@ soup_uri_new_with_base (SoupURI *base, const char *uri_string)
/* Find host and port. */
if (*uri_string == '[') {
+ const char *pct;
+
uri_string++;
hostend = strchr (uri_string, ']');
if (!hostend || hostend > path) {
@@ -318,13 +320,18 @@ soup_uri_new_with_base (SoupURI *base, const char *uri_string)
colon = hostend + 1;
else
colon = NULL;
+
+ pct = memchr (uri_string, '%', hostend - uri_string);
+ if (!pct || (pct[1] == '2' && pct[2] == '5'))
+ uri->host = uri_decoded_copy (uri_string, hostend - uri_string, NULL);
+ else
+ uri->host = g_strndup (uri_string, hostend - uri_string);
} else {
colon = memchr (uri_string, ':', path - uri_string);
hostend = colon ? colon : path;
+ uri->host = uri_decoded_copy (uri_string, hostend - uri_string, NULL);
}
- uri->host = uri_decoded_copy (uri_string, hostend - uri_string, NULL);
-
if (colon && colon != path - 1) {
char *portend;
uri->port = strtoul (colon + 1, &portend, 10);
@@ -513,8 +520,16 @@ soup_uri_to_string_internal (SoupURI *uri, gboolean just_path_and_query,
g_string_append_c (str, '@');
}
if (strchr (uri->host, ':')) {
+ const char *pct;
+
g_string_append_c (str, '[');
- g_string_append (str, uri->host);
+ pct = strchr (uri->host, '%');
+ if (pct) {
+ g_string_append_printf (str, "%.*s%%25%s",
+ (int) (pct - uri->host),
+ uri->host, pct + 1);
+ } else
+ g_string_append (str, uri->host);
g_string_append_c (str, ']');
} else
append_uri_encoded (str, uri->host, ":/");
diff --git a/tests/uri-parsing.c b/tests/uri-parsing.c
index d1bba4e1..b4f495b6 100644
--- a/tests/uri-parsing.c
+++ b/tests/uri-parsing.c
@@ -144,6 +144,14 @@ static struct {
{ NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL } },
{ "+http://host/path", NULL,
{ NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL } },
+
+ /* IPv6 scope ID parsing (both correct and incorrect) */
+ { "http://[fe80::dead:beef%em1]/", "http://[fe80::dead:beef%25em1]/",
+ { "http", NULL, NULL, "fe80::dead:beef%em1", 80, "/", NULL, NULL } },
+ { "http://[fe80::dead:beef%25em1]/", "http://[fe80::dead:beef%25em1]/",
+ { "http", NULL, NULL, "fe80::dead:beef%em1", 80, "/", NULL, NULL } },
+ { "http://[fe80::dead:beef%10]/", "http://[fe80::dead:beef%2510]/",
+ { "http", NULL, NULL, "fe80::dead:beef%10", 80, "/", NULL, NULL } }
};
static int num_abs_tests = G_N_ELEMENTS(abs_tests);