[vlc-devel] [PATCH] demux: adaptive: fix http request with IPv6 reference
Xie Zhigang
zighouse at hotmail.com
Sat Dec 19 09:53:48 UTC 2020
VLC doesn't play hls streams over IPv6 addresses, and here is my patch.
To test it, provide an hls stream on your pC, for example of mine:
(IPv4 version) http://127.0.0.1/hls/1_1080p.m3u8
It is happy to play this url with VLC, but fails on IPv6 url:
(IPv6 version) http://[::1]/hls/1_1080p.m3u8
For here, "::1" is IPv6 local loopback address. And according to RFC2732,
it should use IPv6 reference as host in URLs, as "[::1]".
IPv6 referenced URLs are ok for other players: gst-player-1.0, ffplay, etc.
---
modules/demux/adaptive/http/ConnectionParams.cpp | 62 +++++++++++++++++++++++-
modules/demux/adaptive/http/ConnectionParams.hpp | 2 +
modules/demux/adaptive/http/HTTPConnection.cpp | 14 +++++-
3 files changed, 75 insertions(+), 3 deletions(-)
diff --git a/modules/demux/adaptive/http/ConnectionParams.cpp b/modules/demux/adaptive/http/ConnectionParams.cpp
index 6e3f221..9a632a8 100644
--- a/modules/demux/adaptive/http/ConnectionParams.cpp
+++ b/modules/demux/adaptive/http/ConnectionParams.cpp
@@ -69,7 +69,10 @@ void ConnectionParams::setPath(const std::string &path_)
os << scheme << "://";
if(!hostname.empty())
{
- os << hostname;
+ if (ipv6)
+ os << '[' << hostname << ']';
+ else
+ os << hostname;
if( (port != 80 && scheme != "http") ||
(port != 443 && scheme != "https") )
os << ":" << port;
@@ -88,6 +91,60 @@ bool ConnectionParams::isLocal() const
return scheme != "http" && scheme != "https";
}
+bool isIPv6() const;
+{
+ return ipv6;
+}
+
+static int is_ipv6_addr (const char * host)
+{
+ const char * p;
+ unsigned colons = 0, nums = 0, decs = 0, dots = 0;
+ if (!host)
+ {
+ return 0;
+ }
+ for (p = host; *p; p++)
+ {
+ char c = *p;
+ if (c == ':')
+ {
+ colons ++;
+ if (nums > 4)
+ {
+ return 0;
+ }
+ nums = 0;
+ decs = 0;
+ }
+ else if (('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'))
+ {
+ if ('0' <= c && c <= '9')
+ {
+ decs ++;
+ }
+ nums ++;
+ }
+ else if (c == '.')
+ {
+ dots ++;
+ if (nums != decs)
+ {
+ return 0;
+ }
+ if (nums == 0 || 3 < nums)
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ return 2 <= colons && colons <= 7 && (dots == 0 || dots == 3);
+}
+
void ConnectionParams::parse()
{
vlc_url_t url_components;
@@ -108,7 +165,10 @@ void ConnectionParams::parse()
port = url_components.i_port ? url_components.i_port :
((scheme == "https") ? 443 : 80);
if(url_components.psz_host)
+ {
hostname = url_components.psz_host;
+ ipv6 = is_ipv6_addr(url_components.psz_host);
+ }
vlc_UrlClean(&url_components);
}
diff --git a/modules/demux/adaptive/http/ConnectionParams.hpp b/modules/demux/adaptive/http/ConnectionParams.hpp
index fb9f9d9..868bd97 100644
--- a/modules/demux/adaptive/http/ConnectionParams.hpp
+++ b/modules/demux/adaptive/http/ConnectionParams.hpp
@@ -62,6 +62,7 @@ namespace adaptive
bool isLocal() const;
void setPath(const std::string &);
uint16_t getPort() const;
+ bool isIPv6() const;
private:
void parse();
@@ -70,6 +71,7 @@ namespace adaptive
std::string hostname;
std::string path;
uint16_t port;
+ bool ipv6;
};
}
}
diff --git a/modules/demux/adaptive/http/HTTPConnection.cpp b/modules/demux/adaptive/http/HTTPConnection.cpp
index 36354c5..e103440 100644
--- a/modules/demux/adaptive/http/HTTPConnection.cpp
+++ b/modules/demux/adaptive/http/HTTPConnection.cpp
@@ -432,11 +432,21 @@ std::string HTTPConnection::buildRequestHeader(const std::string &path) const
if((params.getScheme() == "http" && params.getPort() != 80) ||
(params.getScheme() == "https" && params.getPort() != 443))
{
- req << "Host: " << params.getHostname() << ":" << params.getPort() << "\r\n";
+ req << "Host: ";
+ if (params.isIPv6())
+ req << '[' << params.getHostname() << ']';
+ else
+ req << params.getHostname();
+ req << ":" << params.getPort() << "\r\n";
}
else
{
- req << "Host: " << params.getHostname() << "\r\n";
+ req << "Host: ";
+ if (params.isIPv6())
+ req << '[' << params.getHostname() << ']';
+ else
+ req << params.getHostname();
+ req << "\r\n";
}
if(authStorage)
{
--
2.7.4
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20201219/eb89a627/attachment.html>
More information about the vlc-devel
mailing list