diff --git a/django/core/validators.py b/django/core/validators.py index 765266ea27..b1b82dbf0d 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -58,23 +58,18 @@ class URLValidator(RegexValidator): except ValidationError, e: # Trivial case failed. Try for possible IDN domain if value: - original = value value = smart_unicode(value) - splitted = urlparse.urlsplit(value) + scheme, netloc, path, query, fragment = urlparse.urlsplit(value) try: - netloc_ace = splitted[1].encode('idna') # IDN -> ACE + netloc = netloc.encode('idna') # IDN -> ACE except UnicodeError: # invalid domain part raise e - value = value.replace(splitted[1], netloc_ace) - # If no URL path given, assume / - if not splitted[2]: - value += u'/' - super(URLValidator, self).__call__(value) - # After validation revert ACE encoded domain-part to - # original (IDN) value as suggested by RFC 3490 - value = original + url = urlparse.urlunsplit((scheme, netloc, path, query, fragment)) + super(URLValidator, self).__call__(url) else: raise + else: + url = value if self.verify_exists: import urllib2 @@ -86,7 +81,7 @@ class URLValidator(RegexValidator): "User-Agent": self.user_agent, } try: - req = urllib2.Request(value, None, headers) + req = urllib2.Request(url, None, headers) u = urllib2.urlopen(req) except ValueError: raise ValidationError(_(u'Enter a valid URL.'), code='invalid') diff --git a/tests/regressiontests/forms/fields.py b/tests/regressiontests/forms/fields.py index 0c7493ee67..eb85a05d21 100644 --- a/tests/regressiontests/forms/fields.py +++ b/tests/regressiontests/forms/fields.py @@ -531,6 +531,13 @@ class FieldsTests(TestCase): f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page except ValidationError, e: self.assertEqual("[u'This URL appears to be a broken link.']", str(e)) + # Valid and existent IDN + self.assertEqual(u'http://\u05e2\u05d1\u05e8\u05d9\u05ea.idn.icann.org/', f.clean(u'http://עברית.idn.icann.org/')) + # Valid but non-existent IDN + try: + f.clean(u'http://broken.עברית.idn.icann.org/') + except ValidationError, e: + self.assertEqual("[u'This URL appears to be a broken link.']", str(e)) def test_urlfield_40(self): f = URLField(verify_exists=True, required=False)