diff --git a/bootstrap.conf b/bootstrap.conf
index 6e34c75a..d233bba9 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -60,6 +60,7 @@ gettime
gitlog-to-changelog
glob
iconv
+inet_pton
inline
inttypes
ioctl
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 807b4e35..1a832263 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -13,7 +13,8 @@ man3_MANS =\
$(builddir)/man/man3/libwget-base64.3\
$(builddir)/man/man3/libwget-parse_atom.3\
$(builddir)/man/man3/libwget-parse_sitemap.3\
- $(builddir)/man/man3/libwget-robots.3
+ $(builddir)/man/man3/libwget-robots.3\
+ $(builddir)/man/man3/libwget-ip.3
$(man3_MANS): doxy.stamp
diff --git a/include/wget/wget.h b/include/wget/wget.h
index 438bed29..25d7cfe7 100644
--- a/include/wget/wget.h
+++ b/include/wget/wget.h
@@ -829,6 +829,8 @@ typedef struct wget_iri_st {
query_allocated : 1; // if set, free query in iri_free()
unsigned int
fragment_allocated : 1; // if set, free fragment in iri_free()
+ unsigned int
+ is_ip_address : 1; // if set, the hostname part is a literal IPv4 or IPv6 address
} wget_iri_t;
void
@@ -1322,6 +1324,9 @@ ssize_t
int
wget_tcp_ready_2_transfer(wget_tcp_t *tcp, int flags) G_GNUC_WGET_NONNULL_ALL LIBWGET_EXPORT;
+int
+ wget_ip_is_family(const char *host, int family) G_GNUC_WGET_PURE LIBWGET_EXPORT;
+
/*
* SSL routines
*/
diff --git a/libwget/Makefile.am b/libwget/Makefile.am
index 87254723..1331e136 100644
--- a/libwget/Makefile.am
+++ b/libwget/Makefile.am
@@ -4,7 +4,7 @@ lib_LTLIBRARIES = libwget.la
libwget_la_SOURCES = \
atom_url.c bar.c buffer.c buffer_printf.c base64.c cookie.c\
css.c css_tokenizer.c css_tokenizer.h css_tokenizer.lex css_url.c\
- decompressor.c encoding.c hashfile.c hashmap.c io.c hsts.c html_url.c http.c init.c iri.c\
+ decompressor.c encoding.c hashfile.c hashmap.c io.c hsts.c html_url.c http.c init.c ip.c iri.c\
list.c log.c logger.c md5.c mem.c metalink.c net.c net.h netrc.c ocsp.c pipe.c printf.c random.c \
robots.c rss_url.c sitemap_url.c ssl_gnutls.c stringmap.c strlcpy.c thread.c tls_session.c utils.c \
vector.c xalloc.c xml.c private.h http_highlevel.c
diff --git a/libwget/ip.c b/libwget/ip.c
new file mode 100644
index 00000000..fed18e1a
--- /dev/null
+++ b/libwget/ip.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright(c) 2016 Free Software Foundation, Inc.
+ *
+ * This file is part of libwget.
+ *
+ * Libwget is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Libwget is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libwget. If not, see .
+ *
+ *
+ * IP address helper routines
+ *
+ */
+
+#if HAVE_CONFIG_H
+# include
+#endif
+
+#include
+#include
+
+#include
+#include "private.h"
+
+/**
+ * \file
+ * \brief IP address functions
+ * \defgroup libwget-ip IP address functions
+ * @{
+ *
+ * Routines to check IP address formats.
+ */
+
+/**
+ * \param[in] host Host/IP String
+ * \param[in] family IP address family
+ * \return
+ * 1 if \host matches is of \p family
+ * 0 if \p host does not match \p family
+ *
+ * This functions checks if \p host matches the given \p family or not.
+ */
+int wget_ip_is_family(const char *host, int family)
+{
+ struct sockaddr_storage dst;
+
+ if (!host)
+ return 0;
+
+ switch (family) {
+ case WGET_NET_FAMILY_IPV4:
+ return inet_pton(AF_INET, host, (struct in_addr *) &dst);
+ case WGET_NET_FAMILY_IPV6:
+ return inet_pton(AF_INET6, host, (struct in6_addr *) &dst);
+ default:
+ return 0;
+ }
+}
+
+/**@}*/
diff --git a/libwget/iri.c b/libwget/iri.c
index 3b156fca..ddf05c4f 100644
--- a/libwget/iri.c
+++ b/libwget/iri.c
@@ -373,6 +373,10 @@ wget_iri_t *wget_iri_parse(const char *url, const char *encoding)
iri->host = p;
iri->host_allocated = 1;
}
+
+ // Finally, if the host is a literal IPv4 or IPv6 address, mark it as so
+ if (wget_ip_is_family(iri->host, WGET_NET_FAMILY_IPV4) || wget_ip_is_family(iri->host, WGET_NET_FAMILY_IPV6))
+ iri->is_ip_address = 1;
}
else {
if (iri->scheme == WGET_IRI_SCHEME_HTTP || iri->scheme == WGET_IRI_SCHEME_HTTPS) {
diff --git a/src/wget.c b/src/wget.c
index 26f495c2..8b8faf09 100644
--- a/src/wget.c
+++ b/src/wget.c
@@ -1239,7 +1239,9 @@ static int process_response_header(wget_http_response_t *resp)
wget_cookie_store_cookies(config.cookie_db, resp->cookies); // store cookies
// care for HSTS feature
- if (config.hsts && iri->scheme == WGET_IRI_SCHEME_HTTPS && resp->hsts) {
+ if (config.hsts &&
+ iri->scheme == WGET_IRI_SCHEME_HTTPS && !iri->is_ip_address &&
+ resp->hsts) {
wget_hsts_db_add(config.hsts_db, wget_hsts_new(iri->host, atoi(iri->resolv_port), resp->hsts_maxage, resp->hsts_include_subdomains));
hsts_changed = 1;
}