urlapi: strip off scope id from numerical IPv6 addresses

... to make the host name "usable". Store the scope id and put it back
when extracting a URL out of it.

Also makes curl_url_set() syntax check CURLUPART_HOST.

Fixes #3817
Closes #3822
This commit is contained in:
Daniel Stenberg 2019-04-30 16:59:08 +02:00
parent 0281262819
commit bdb2dbc103
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
5 changed files with 192 additions and 12 deletions

View file

@ -31,4 +31,14 @@ lib1560
</tool>
</client>
<verify>
<stdout>
we got [fe80::20c:29ff:fe9c:409b]
we got https://[::1]/hello.html
we got https://example.com/hello.html
we got https://[fe80::20c:29ff:fe9c:409b%25eth0]/hello.html
we got [fe80::20c:29ff:fe9c:409b]
success
</stdout>
</verify>
</testcase>

View file

@ -153,7 +153,13 @@ static struct testcase get_parts_list[] ={
"http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]",
CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
{"https://[::1%252]:1234",
"https | [11] | [12] | [13] | [::1%252] | 1234 | / | [16] | [17]",
"https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]",
CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
/* here's "bad" zone id */
{"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234",
"https | [11] | [12] | [13] | [fe80::20c:29ff:fe9c:409b] | 1234 "
"| / | [16] | [17]",
CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
{"https://127.0.0.1:443",
"https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]",
@ -273,6 +279,18 @@ static struct testcase get_parts_list[] ={
};
static struct urltestcase get_url_list[] = {
{"https://[fe80::20c:29ff:fe9c:409b%]:1234",
"",
0, 0, CURLUE_MALFORMED_INPUT},
{"https://[fe80::20c:29ff:fe9c:409b%25]:1234",
"https://[fe80::20c:29ff:fe9c:409b%2525]:1234/",
0, 0, CURLUE_OK},
{"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234",
"https://[fe80::20c:29ff:fe9c:409b%25eth0]:1234/",
0, 0, CURLUE_OK},
{"https://[::%25fakeit]/moo",
"https://[::%25fakeit]/moo",
0, 0, CURLUE_OK},
{"smtp.example.com/path/html",
"smtp://smtp.example.com/path/html",
CURLU_GUESS_SCHEME, 0, CURLUE_OK},
@ -831,10 +849,111 @@ static int append(void)
return error;
}
static int scopeid(void)
{
CURLU *u;
int error = 0;
CURLUcode rc;
char *url;
u = curl_url();
rc = curl_url_set(u, CURLUPART_URL,
"https://[fe80::20c:29ff:fe9c:409b%25eth0]/hello.html", 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_set returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
rc = curl_url_get(u, CURLUPART_HOST, &url, 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
else {
printf("we got %s\n", url);
curl_free(url);
}
rc = curl_url_set(u, CURLUPART_HOST, "[::1]", 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
rc = curl_url_get(u, CURLUPART_URL, &url, 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
else {
printf("we got %s\n", url);
curl_free(url);
}
rc = curl_url_set(u, CURLUPART_HOST, "example.com", 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
rc = curl_url_get(u, CURLUPART_URL, &url, 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
else {
printf("we got %s\n", url);
curl_free(url);
}
rc = curl_url_set(u, CURLUPART_HOST,
"[fe80::20c:29ff:fe9c:409b%25eth0]", 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
rc = curl_url_get(u, CURLUPART_URL, &url, 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
else {
printf("we got %s\n", url);
curl_free(url);
}
rc = curl_url_get(u, CURLUPART_HOST, &url, 0);
if(rc != CURLUE_OK) {
fprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d\n",
__FILE__, __LINE__, (int)rc);
error++;
}
else {
printf("we got %s\n", url);
curl_free(url);
}
curl_url_cleanup(u);
return error;
}
int test(char *URL)
{
(void)URL; /* not used */
if(scopeid())
return 6;
if(append())
return 5;

View file

@ -168,7 +168,7 @@ UNITTEST_START
u = curl_url();
if(!u)
goto fail;
ipv6port = strdup("[fe80::250:56ff:fea7:da15%!25eth3]:80");
ipv6port = strdup("[fe80::250:56ff:fea7:da15!25eth3]:80");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
@ -184,7 +184,7 @@ UNITTEST_START
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
fail_unless(ret != CURLUE_OK, "Curl_parse_port returned non-error");
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
fail:
free(ipv6port);
curl_url_cleanup(u);