The zoneid can be used with IPv6 numerical addresses.
Updated test 1560 to verify.
Closes #3834
1.16 Try to URL encode given URL
1.17 Add support for IRIs
1.18 try next proxy if one doesn't work
- 1.19 add CURLUPART_SCOPEID
1.20 SRV and URI DNS records
1.21 Have the URL API offer IDN decoding
1.22 CURLINFO_PAUSE_STATE
https://github.com/curl/curl/issues/896
-1.19 add CURLUPART_SCOPEID
-
- Add support for CURLUPART_SCOPEID to curl_url_set() and curl_url_get(). It is
- only really used when the host name is an IPv6 numerical address.
-
1.20 SRV and URI DNS records
Offer support for resolving SRV and URI DNS records for libcurl to know which
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.IP CURLUPART_PASSWORD
.IP CURLUPART_OPTIONS
.IP CURLUPART_HOST
+If the host part is an IPv6 numeric address, the zoneid will not be part of
+the extracted host but is provided separately in \fICURLUPART_ZONEID\fP.
+.IP CURLUPART_ZONEID
+If the host name is a numeric IPv6 address, this field might also be set.
.IP CURLUPART_PORT
Port cannot be URL decoded on get.
.IP CURLUPART_PATH
}
.fi
.SH AVAILABILITY
-Added in curl 7.62.0
+Added in curl 7.62.0. CURLUPART_ZONEID was added in 7.65.0.
.SH "SEE ALSO"
.BR curl_url_cleanup "(3), " curl_url "(3), " curl_url_set "(3), "
.BR curl_url_dup "(3), "
.IP CURLUPART_HOST
The host name can use IDNA. The string must then be encoded as your locale
says or UTF-8 (when winidn is used).
+.IP CURLUPART_ZONEID
+If the host name is a numeric IPv6 address, this field can also be set.
.IP CURLUPART_PORT
Port cannot be URL encoded on set. The given port number is provided as a
string and the decimal number must be between 1 and 65535. Anything else will
curl_url_cleanup(url);
.fi
.SH AVAILABILITY
-Added in curl 7.62.0
+Added in curl 7.62.0. CURLUPART_ZONEID was added in 7.65.0.
.SH "SEE ALSO"
.BR curl_url_cleanup "(3), " curl_url "(3), " curl_url_get "(3), "
.BR curl_url_dup "(3), "
CURLUPART_SCHEME 7.62.0
CURLUPART_URL 7.62.0
CURLUPART_USER 7.62.0
+CURLUPART_ZONEID 7.65.0
CURLUSESSL_ALL 7.17.0
CURLUSESSL_CONTROL 7.17.0
CURLUSESSL_NONE 7.17.0
CURLUPART_PORT,
CURLUPART_PATH,
CURLUPART_QUERY,
- CURLUPART_FRAGMENT
+ CURLUPART_FRAGMENT,
+ CURLUPART_ZONEID /* added in 7.65.0 */
} CURLUPart;
#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
char *password;
char *options; /* IMAP only? */
char *host;
- char *scopeid; /* for numerical IPv6 addresses */
+ char *zoneid; /* for numerical IPv6 addresses */
char *port;
char *path;
char *query;
free(u->password);
free(u->options);
free(u->host);
- free(u->scopeid);
+ free(u->zoneid);
free(u->port);
free(u->path);
free(u->query);
len = strspn(hostname, l);
if(hlen != len) {
/* this could now be '%[zone id]' */
- char scopeid[16];
+ char zoneid[16];
if(hostname[len] == '%') {
int i = 0;
char *h = &hostname[len + 1];
if(!strncmp(h, "25", 2) && h[2] && (h[2] != ']'))
h += 2;
while(*h && (*h != ']') && (i < 15))
- scopeid[i++] = *h++;
+ zoneid[i++] = *h++;
if(!i || (']' != *h))
return CURLUE_MALFORMED_INPUT;
- scopeid[i] = 0;
- u->scopeid = strdup(scopeid);
- if(!u->scopeid)
+ zoneid[i] = 0;
+ u->zoneid = strdup(zoneid);
+ if(!u->zoneid)
return CURLUE_OUT_OF_MEMORY;
hostname[len] = ']'; /* insert end bracket */
hostname[len + 1] = 0; /* terminate the hostname */
ptr = u->host;
ifmissing = CURLUE_NO_HOST;
break;
+ case CURLUPART_ZONEID:
+ ptr = u->zoneid;
+ break;
case CURLUPART_PORT:
ptr = u->port;
ifmissing = CURLUE_NO_PORT;
if(h && !(h->flags & PROTOPT_URLOPTIONS))
options = NULL;
- if((u->host[0] == '[') && u->scopeid) {
- /* make it '[ host %25 scopeid ]' */
+ if((u->host[0] == '[') && u->zoneid) {
+ /* make it '[ host %25 zoneid ]' */
size_t hostlen = strlen(u->host);
- size_t alen = hostlen + 3 + strlen(u->scopeid) + 1;
+ size_t alen = hostlen + 3 + strlen(u->zoneid) + 1;
allochost = malloc(alen);
if(!allochost)
return CURLUE_OUT_OF_MEMORY;
memcpy(allochost, u->host, hostlen - 1);
msnprintf(&allochost[hostlen - 1], alen - hostlen + 1,
- "%%25%s]", u->scopeid);
+ "%%25%s]", u->zoneid);
}
url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
case CURLUPART_HOST:
storep = &u->host;
break;
+ case CURLUPART_ZONEID:
+ storep = &u->zoneid;
+ break;
case CURLUPART_PORT:
u->portnum = 0;
storep = &u->port;
break;
case CURLUPART_HOST:
storep = &u->host;
- free(u->scopeid);
- u->scopeid = NULL;
+ free(u->zoneid);
+ u->zoneid = NULL;
+ break;
+ case CURLUPART_ZONEID:
+ storep = &u->zoneid;
break;
case CURLUPART_PORT:
{
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]
+we got eth0
+we got https://[fe80::20c:29ff:fe9c:409b%25clown]/hello.html
success
</stdout>
</verify>
/* !checksrc! disable SPACEBEFORECOMMA 1 */
static struct setcase set_parts_list[] = {
+ {"https://[::1%25fake]:1234/",
+ "zoneid=NULL,",
+ "https://[::1]:1234/",
+ 0, 0, CURLUE_OK, CURLUE_OK},
{"https://host:1234/",
"port=NULL,",
"https://host/",
return CURLUPART_QUERY;
if(!strcmp("fragment", part))
return CURLUPART_FRAGMENT;
+ if(!strcmp("zoneid", part))
+ return CURLUPART_ZONEID;
return 9999; /* bad input => bad output */
}
/* for debugging this */
fprintf(stderr, "%s = %s [%d]\n", part, value, (int)what);
#endif
+ if(what > CURLUPART_ZONEID)
+ fprintf(stderr, "UNKNOWN part '%s'\n", part);
+
if(!strcmp("NULL", value))
uc = curl_url_set(u, what, NULL, setflags);
else if(!strcmp("\"\"", value))
curl_free(url);
}
+ rc = curl_url_get(u, CURLUPART_ZONEID, &url, 0);
+ if(rc != CURLUE_OK) {
+ fprintf(stderr, "%s:%d curl_url_get CURLUPART_ZONEID returned %d\n",
+ __FILE__, __LINE__, (int)rc);
+ error++;
+ }
+ else {
+ printf("we got %s\n", url);
+ curl_free(url);
+ }
+
+ rc = curl_url_set(u, CURLUPART_ZONEID, "clown", 0);
+ if(rc != CURLUE_OK) {
+ fprintf(stderr, "%s:%d curl_url_set CURLUPART_ZONEID 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);
+ }
+
curl_url_cleanup(u);
return error;