Fixed #12989 - Fixed verification of IDN URLs. Thanks to Fraser Nevett for the report and patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12620 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d7abb33e70
commit
68f216a692
|
@ -58,23 +58,18 @@ class URLValidator(RegexValidator):
|
||||||
except ValidationError, e:
|
except ValidationError, e:
|
||||||
# Trivial case failed. Try for possible IDN domain
|
# Trivial case failed. Try for possible IDN domain
|
||||||
if value:
|
if value:
|
||||||
original = value
|
|
||||||
value = smart_unicode(value)
|
value = smart_unicode(value)
|
||||||
splitted = urlparse.urlsplit(value)
|
scheme, netloc, path, query, fragment = urlparse.urlsplit(value)
|
||||||
try:
|
try:
|
||||||
netloc_ace = splitted[1].encode('idna') # IDN -> ACE
|
netloc = netloc.encode('idna') # IDN -> ACE
|
||||||
except UnicodeError: # invalid domain part
|
except UnicodeError: # invalid domain part
|
||||||
raise e
|
raise e
|
||||||
value = value.replace(splitted[1], netloc_ace)
|
url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
|
||||||
# If no URL path given, assume /
|
super(URLValidator, self).__call__(url)
|
||||||
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
|
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
else:
|
||||||
|
url = value
|
||||||
|
|
||||||
if self.verify_exists:
|
if self.verify_exists:
|
||||||
import urllib2
|
import urllib2
|
||||||
|
@ -86,7 +81,7 @@ class URLValidator(RegexValidator):
|
||||||
"User-Agent": self.user_agent,
|
"User-Agent": self.user_agent,
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
req = urllib2.Request(value, None, headers)
|
req = urllib2.Request(url, None, headers)
|
||||||
u = urllib2.urlopen(req)
|
u = urllib2.urlopen(req)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValidationError(_(u'Enter a valid URL.'), code='invalid')
|
raise ValidationError(_(u'Enter a valid URL.'), code='invalid')
|
||||||
|
|
|
@ -531,6 +531,13 @@ class FieldsTests(TestCase):
|
||||||
f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page
|
f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page
|
||||||
except ValidationError, e:
|
except ValidationError, e:
|
||||||
self.assertEqual("[u'This URL appears to be a broken link.']", str(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):
|
def test_urlfield_40(self):
|
||||||
f = URLField(verify_exists=True, required=False)
|
f = URLField(verify_exists=True, required=False)
|
||||||
|
|
Loading…
Reference in New Issue