@@ -20,6 +20,7 @@
#include "config.h"
#endif
+#include <arpa/inet.h>
#include <assert.h>
#include <string.h>
@@ -197,19 +198,35 @@ struct pb_url *pb_url_parse(void *ctx, const char *url_str)
goto fail;
}
- col = strchr(p, ':');
+ col = strrchr(p, ':');
+ if (col <= p)
+ col = NULL;
+ if (col && strchr(col , ']')) {
+ /*
+ * This is likely an IPv6 address with no port.
+ * See https://www.ietf.org/rfc/rfc2732.txt
+ */
+ col = NULL;
+ }
if (col) {
len = path - col - 1;
url->port = len ? talloc_strndup(url, col + 1, len)
: NULL;
len = col - p;
- url->host = len ? talloc_strndup(url, p, len) : NULL;
} else {
url->port = NULL;
- url->host = talloc_strndup(url, p, path - p);
+ len = path - p;
}
+ if (p[0] == '[' && p[len - 1] == ']')
+ /* IPv6 */
+ url->host = talloc_strndup(url, p + 1, len - 2);
+ else
+ /* IPv4 */
+ url->host = talloc_strndup(url, p, len);
+
+
/* remove multiple leading slashes */
for (; *path && *(path+1) == '/'; path++)
;
@@ -234,10 +251,15 @@ bool is_url(const char *str)
char *pb_url_to_string(struct pb_url *url)
{
const struct pb_scheme_info *scheme = pb_url_scheme_info(url->scheme);
+ uint8_t addr[INET6_ADDRSTRLEN];
assert(scheme);
- return talloc_asprintf(url, "%s://%s%s", scheme->str,
- scheme->has_host ? url->host : "", url->path);
+ if (scheme->has_host && inet_pton(AF_INET6, url->host, addr) == 1)
+ return talloc_asprintf(url, "%s://[%s]%s", scheme->str,
+ url->host, url->path);
+ else
+ return talloc_asprintf(url, "%s://%s%s", scheme->str,
+ scheme->has_host ? url->host : "", url->path);
}
static void pb_url_update_full(struct pb_url *url)
@@ -20,6 +20,9 @@ test_urls_parse_url_LDADD = $(core_lib)
url_TESTS = \
test/urls/data/double-slash.test \
test/urls/data/http-simple.test \
+ test/urls/data/ipv6-full.test \
+ test/urls/data/ipv6-multidirs.test \
+ test/urls/data/ipv6-noport.test \
test/urls/data/join-full.test \
test/urls/data/join-absolute.test \
test/urls/data/join-relative.test \
new file mode 100644
@@ -0,0 +1,7 @@
+http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
+scheme http
+host FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
+port 80
+path /index.html
+dir /
+file index.html
new file mode 100644
@@ -0,0 +1,7 @@
+tftp://[fd69:d65f:b8b5:61::1]/installers/ubuntu-18.04/vmlinux
+scheme tftp
+host fd69:d65f:b8b5:61::1
+port (null)
+path /installers/ubuntu-18.04/vmlinux
+dir /installers/ubuntu-18.04/
+file vmlinux
new file mode 100644
@@ -0,0 +1,7 @@
+http://[1080:0:0:0:8:800:200C:417A]/index.html
+scheme http
+host 1080:0:0:0:8:800:200C:417A
+port (null)
+path /index.html
+dir /
+file index.html
Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com> --- lib/url/url.c | 32 +++++++++++++++++++++++++----- test/urls/Makefile.am | 3 +++ test/urls/data/ipv6-full.test | 7 +++++++ test/urls/data/ipv6-multidirs.test | 7 +++++++ test/urls/data/ipv6-noport.test | 7 +++++++ 5 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 test/urls/data/ipv6-full.test create mode 100644 test/urls/data/ipv6-multidirs.test create mode 100644 test/urls/data/ipv6-noport.test