]> granicus.if.org Git - python/commitdiff
Merged revisions 80102 via svnmerge from
authorSenthil Kumaran <orsenthil@gmail.com>
Fri, 16 Apr 2010 03:06:19 +0000 (03:06 +0000)
committerSenthil Kumaran <orsenthil@gmail.com>
Fri, 16 Apr 2010 03:06:19 +0000 (03:06 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r80102 | senthil.kumaran | 2010-04-16 08:32:13 +0530 (Fri, 16 Apr 2010) | 9 lines

  Merged revisions 80101 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk

  ........
    r80101 | senthil.kumaran | 2010-04-16 08:16:46 +0530 (Fri, 16 Apr 2010) | 3 lines

    Fix issue2987: RFC2732 support for urlparse (IPv6 addresses)
  ........
................

Lib/test/test_urlparse.py
Lib/urllib/parse.py
Misc/NEWS

index 1cac691b70e780bee1c2d89b4e1e2b3d66b22f71..14c2d2b40ea536e43bb53e96d621bcb963b79a69 100644 (file)
@@ -239,10 +239,44 @@ class UrlParseTestCase(unittest.TestCase):
         #self.checkJoin(RFC2396_BASE, '?y', 'http://a/b/c/?y')
         #self.checkJoin(RFC2396_BASE, ';x', 'http://a/b/c/;x')
 
+
     def test_RFC3986(self):
         self.checkJoin(RFC3986_BASE, '?y','http://a/b/c/d;p?y')
         self.checkJoin(RFC2396_BASE, ';x', 'http://a/b/c/;x')
 
+    def test_RFC2732(self):
+        for url, hostname, port in [
+            ('http://Test.python.org:5432/foo/', 'test.python.org', 5432),
+            ('http://12.34.56.78:5432/foo/', '12.34.56.78', 5432),
+            ('http://[::1]:5432/foo/', '::1', 5432),
+            ('http://[dead:beef::1]:5432/foo/', 'dead:beef::1', 5432),
+            ('http://[dead:beef::]:5432/foo/', 'dead:beef::', 5432),
+            ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]:5432/foo/',
+             'dead:beef:cafe:5417:affe:8fa3:deaf:feed', 5432),
+            ('http://[::12.34.56.78]:5432/foo/', '::12.34.56.78', 5432),
+            ('http://[::ffff:12.34.56.78]:5432/foo/',
+             '::ffff:12.34.56.78', 5432),
+            ('http://Test.python.org/foo/', 'test.python.org', None),
+            ('http://12.34.56.78/foo/', '12.34.56.78', None),
+            ('http://[::1]/foo/', '::1', None),
+            ('http://[dead:beef::1]/foo/', 'dead:beef::1', None),
+            ('http://[dead:beef::]/foo/', 'dead:beef::', None),
+            ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/',
+             'dead:beef:cafe:5417:affe:8fa3:deaf:feed', None),
+            ('http://[::12.34.56.78]/foo/', '::12.34.56.78', None),
+            ('http://[::ffff:12.34.56.78]/foo/',
+             '::ffff:12.34.56.78', None),
+            ]:
+            urlparsed = urllib.parse.urlparse(url)
+            self.assertEqual((urlparsed.hostname, urlparsed.port) , (hostname, port))
+
+        for invalid_url in [
+                'http://::12.34.56.78]/',
+                'http://[::1/foo/',
+                'http://[::ffff:12.34.56.78']:
+            self.assertRaises(ValueError, lambda : urllib.parse.urlparse(invalid_url).hostname)
+            self.assertRaises(ValueError, lambda : urllib.parse.urlparse(invalid_url))
+
     def test_urldefrag(self):
         for url, defrag, frag in [
             ('http://python.org#frag', 'http://python.org', 'frag'),
index c1ae5fff0e8caa04c210559fad0fb8384d507dd2..1affc6930d9298f5bf0b32fea66f922998a199d6 100644 (file)
@@ -69,22 +69,26 @@ class ResultMixin(object):
 
     @property
     def hostname(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            netloc = netloc.rsplit("@", 1)[1]
-        if ":" in netloc:
-            netloc = netloc.split(":", 1)[0]
-        return netloc.lower() or None
+        netloc = self.netloc.split('@')[-1]
+        if '[' in netloc and ']' in netloc:
+            return netloc.split(']')[0][1:].lower()
+        elif '[' in netloc or ']' in netloc:
+            raise ValueError("Invalid IPv6 hostname")
+        elif ':' in netloc:
+            return netloc.split(':')[0].lower()
+        elif netloc == '':
+            return None
+        else:
+            return netloc.lower()
 
     @property
     def port(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            netloc = netloc.rsplit("@", 1)[1]
-        if ":" in netloc:
-            port = netloc.split(":", 1)[1]
+        netloc = self.netloc.split('@')[-1].split(']')[-1]
+        if ':' in netloc:
+            port = netloc.split(':')[1]
             return int(port, 10)
-        return None
+        else:
+            return None
 
 from collections import namedtuple
 
@@ -129,6 +133,10 @@ def _splitparams(url):
 
 def _splitnetloc(url, start=0):
     delim = len(url)   # position of end of domain part of url, default is end
+    if '[' in url:     # check for invalid IPv6 URL
+        if not ']' in url: raise ValueError("Invalid IPv6 URL")
+    elif ']' in url:
+        if not '[' in url: raise ValueError("Invalid IPv6 URL")
     for c in '/?#':    # look for delimiters; the order is NOT important
         wdelim = url.find(c, start)        # find first of this delim
         if wdelim >= 0:                    # if found
index 536ea43ed5a331f8a6937515156c2dd1a414dc79..181d630452cd423badd69b97c1b56616cd886c5d 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -28,6 +28,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #2987: RFC2732 support for urlparse (IPv6 addresses). Patch by Tony
+  Locke and Hans Ulrich Niedermann.
+
 - Issue #5277: Fix quote counting when parsing RFC 2231 encoded parameters.
 
 - Issue #8383: pickle and pickletools use surrogatepass error handler when