mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
URL parser: IPv6 zone identifiers are now supported
This commit is contained in:
parent
0bc4938eec
commit
9317eced98
@ -180,16 +180,7 @@ may have been fixed since this was written!
|
|||||||
--cflags suffers from the same effects with CFLAGS/CPPFLAGS.
|
--cflags suffers from the same effects with CFLAGS/CPPFLAGS.
|
||||||
|
|
||||||
30. You need to use -g to the command line tool in order to use RFC2732-style
|
30. You need to use -g to the command line tool in order to use RFC2732-style
|
||||||
IPv6 numerical addresses in URLs.
|
or RFC6874-style IPv6 numerical addresses in URLs.
|
||||||
|
|
||||||
29. IPv6 URLs with zone ID is not nicely supported.
|
|
||||||
http://www.ietf.org/internet-drafts/draft-fenner-literal-zone-02.txt (expired)
|
|
||||||
specifies the use of a plus sign instead of a percent when specifying zone
|
|
||||||
IDs in URLs to get around the problem of percent signs being
|
|
||||||
special. According to the reporter, Firefox deals with the URL _with_ a
|
|
||||||
percent letter (which seems like a blatant URL spec violation).
|
|
||||||
libcurl supports zone IDs where the percent sign is URL-escaped (i.e. %25):
|
|
||||||
http://curl.haxx.se/bug/view.cgi?id=555
|
|
||||||
|
|
||||||
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
||||||
"system context" will make it use wrong(?) user name - at least when compared
|
"system context" will make it use wrong(?) user name - at least when compared
|
||||||
|
@ -956,9 +956,9 @@ IPv6
|
|||||||
When this style is used, the -g option must be given to stop curl from
|
When this style is used, the -g option must be given to stop curl from
|
||||||
interpreting the square brackets as special globbing characters. Link local
|
interpreting the square brackets as special globbing characters. Link local
|
||||||
and site local addresses including a scope identifier, such as fe80::1234%1,
|
and site local addresses including a scope identifier, such as fe80::1234%1,
|
||||||
may also be used, but the scope portion must be numeric and the percent
|
may also be used, but the scope portion must be numeric or match an existing
|
||||||
character must be URL escaped. The previous example in an SFTP URL might
|
network interface on Linux and the percent character must be URL escaped. The
|
||||||
look like:
|
previous example in an SFTP URL might look like:
|
||||||
|
|
||||||
sftp://[fe80::1234%251]/
|
sftp://[fe80::1234%251]/
|
||||||
|
|
||||||
|
69
lib/url.c
69
lib/url.c
@ -3951,23 +3951,59 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
|
|||||||
if(result != CURLE_OK)
|
if(result != CURLE_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if(conn->host.name[0] == '[') {
|
if(conn->host.name[0] == '[' && !data->state.this_is_a_follow) {
|
||||||
/* This looks like an IPv6 address literal. See if there is an address
|
/* This looks like an IPv6 address literal. See if there is an address
|
||||||
scope. */
|
scope if there is no location header */
|
||||||
char *percent = strstr (conn->host.name, "%25");
|
char *percent = strchr(conn->host.name, '%');
|
||||||
if(percent) {
|
if(percent) {
|
||||||
|
unsigned int identifier_offset = 3;
|
||||||
char *endp;
|
char *endp;
|
||||||
unsigned long scope = strtoul (percent + 3, &endp, 10);
|
unsigned long scope;
|
||||||
|
if(strncmp("%25", percent, 3) != 0) {
|
||||||
|
infof(data,
|
||||||
|
"Please URL encode %% as %%25, see RFC 6874.\n");
|
||||||
|
identifier_offset = 1;
|
||||||
|
}
|
||||||
|
scope = strtoul(percent + identifier_offset, &endp, 10);
|
||||||
if(*endp == ']') {
|
if(*endp == ']') {
|
||||||
/* The address scope was well formed. Knock it out of the
|
/* The address scope was well formed. Knock it out of the
|
||||||
hostname. */
|
hostname. */
|
||||||
memmove(percent, endp, strlen(endp)+1);
|
memmove(percent, endp, strlen(endp)+1);
|
||||||
if(!data->state.this_is_a_follow)
|
conn->scope = (unsigned int)scope;
|
||||||
/* Don't honour a scope given in a Location: header */
|
}
|
||||||
conn->scope = (unsigned int)scope;
|
else {
|
||||||
|
/* Zone identifier is not numeric */
|
||||||
|
#ifdef HAVE_NET_IF_H
|
||||||
|
char ifname[IFNAMSIZ + 2];
|
||||||
|
char *square_bracket;
|
||||||
|
unsigned int scopeidx = 0;
|
||||||
|
strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
|
||||||
|
/* Ensure nullbyte termination */
|
||||||
|
ifname[IFNAMSIZ + 1] = '\0';
|
||||||
|
square_bracket = strchr(ifname, ']');
|
||||||
|
if(square_bracket) {
|
||||||
|
/* Remove ']' */
|
||||||
|
*square_bracket = '\0';
|
||||||
|
scopeidx = if_nametoindex(ifname);
|
||||||
|
if(scopeidx == 0) {
|
||||||
|
infof(data, "Invalid network interface: %s; %s\n", ifname,
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(scopeidx > 0) {
|
||||||
|
/* Remove zone identifier from hostname */
|
||||||
|
memmove(percent,
|
||||||
|
percent + identifier_offset + strlen(ifname),
|
||||||
|
identifier_offset + strlen(ifname));
|
||||||
|
conn->scope = scopeidx;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#endif /* HAVE_NET_IF_H */
|
||||||
|
infof(data, "Invalid IPv6 address format\n");
|
||||||
|
#ifdef HAVE_NET_IF_H
|
||||||
|
}
|
||||||
|
#endif /* HAVE_NET_IF_H */
|
||||||
}
|
}
|
||||||
else
|
|
||||||
infof(data, "Invalid IPv6 address format\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4350,12 +4386,21 @@ static CURLcode parse_proxy(struct SessionHandle *data,
|
|||||||
/* start scanning for port number at this point */
|
/* start scanning for port number at this point */
|
||||||
portptr = proxyptr;
|
portptr = proxyptr;
|
||||||
|
|
||||||
/* detect and extract RFC2732-style IPv6-addresses */
|
/* detect and extract RFC6874-style IPv6-addresses */
|
||||||
if(*proxyptr == '[') {
|
if(*proxyptr == '[') {
|
||||||
char *ptr = ++proxyptr; /* advance beyond the initial bracket */
|
char *ptr = ++proxyptr; /* advance beyond the initial bracket */
|
||||||
while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') ||
|
while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
|
||||||
(*ptr == '.')))
|
|
||||||
ptr++;
|
ptr++;
|
||||||
|
if(*ptr == '%') {
|
||||||
|
/* There might be a zone identifier */
|
||||||
|
if(strncmp("%25", ptr, 3))
|
||||||
|
infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
|
||||||
|
ptr++;
|
||||||
|
/* Allow unresered characters as defined in RFC 3986 */
|
||||||
|
while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
|
||||||
|
(*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
if(*ptr == ']')
|
if(*ptr == ']')
|
||||||
/* yeps, it ended nicely with a bracket as well */
|
/* yeps, it ended nicely with a bracket as well */
|
||||||
*ptr++ = 0;
|
*ptr++ = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user