diff options
author | Dan Winship <danw@gnome.org> | 2013-08-19 15:44:12 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2013-08-19 16:04:06 -0400 |
commit | e43eef9705634317a7af7d1217793925b1b13ab9 (patch) | |
tree | b1891198f93da6778fbc5c2633a98cefd2f0abf3 | |
parent | fe3735f81a8e1bfa5242904a94c30217a5101cbc (diff) | |
download | libsoup-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.c | 2 | ||||
-rw-r--r-- | libsoup/soup-uri.c | 21 | ||||
-rw-r--r-- | tests/uri-parsing.c | 8 |
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); |