summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);