[vlc-devel] [PATCH] demux: adaptive: fix http request with IPv6 reference

Xie Zhigang zighouse at hotmail.com
Mon Dec 21 14:00:32 UTC 2020


雷米:你好!

I send my first email with mobile phone client, and it makes indent 
spaces changed :(

inet_pton() is better than my ugly code, and I have revised my patch:

---

  .../demux/adaptive/http/ConnectionParams.cpp  | 24 ++++++++++++++++++-
  .../demux/adaptive/http/ConnectionParams.hpp  |  2 ++
  .../demux/adaptive/http/HTTPConnection.cpp    | 14 +++++++++--
  3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/modules/demux/adaptive/http/ConnectionParams.cpp 
b/modules/demux/adaptive/http/ConnectionParams.cpp
index 6e3f221b66..3833e3a5e1 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,22 @@ bool ConnectionParams::isLocal() const
      return scheme != "http" && scheme != "https";
  }

+bool isIPv6() const;
+{
+    return ipv6;
+}
+
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
+#include <arpa/inet.h>
+#endif
+static inline int is_ipv6_addr (const char * host)
+{
+    unsigned char buf[sizeof(struct in6_addr)];
+    return inet_pton(AF_INET6, host, buf) == 1;
+}
+
  void ConnectionParams::parse()
  {
      vlc_url_t url_components;
@@ -108,7 +127,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 fb9f9d9af1..868bd97ac6 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 36354c5b90..e10344012f 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.17.1

On 2020/12/20 下午4:13, Rémi Denis-Courmont wrote:
> 	Nihao,
>
> Comments inline...
>
> Le lauantaina 19. joulukuuta 2020, 11.53.48 EET Xie Zhigang a écrit :
>> +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);
>> +}
>> +
> This does not need so much complexity. If you really want to check for IPv6,
> there's inet_pton(), but you could just check if the string contains as colon.
>
> Also please try to stick to the same indentation style as the rest of the
> code.
>
>>   void ConnectionParams::parse()
>>   {
>>       vlc_url_t url_components;


More information about the vlc-devel mailing list