Ticket #14955: urllib2_head_request_2.diff

File urllib2_head_request_2.diff, 2.9 KB (added by Claude Paroz, 14 years ago)

Add fallback to GET

  • django/core/validators.py

    commit 3268f33d6d6af9af63e81b3c04aa8192e7e42d50
    Author: Claude Paroz <claude@2xlibre.net>
    Date:   Wed Dec 29 15:15:57 2010 +0100
    
        Use custom urllib2 Request to use HEAD instead of GET request to validate url
    
    diff --git a/django/core/validators.py b/django/core/validators.py
    index b1b82db..d0af452 100644
    a b class URLValidator(RegexValidator):  
    7373
    7474        if self.verify_exists:
    7575            import urllib2
     76            class HeadRequest(urllib2.Request):
     77                def get_method(self):
     78                    return "HEAD"
    7679            headers = {
    7780                "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
    7881                "Accept-Language": "en-us,en;q=0.5",
    class URLValidator(RegexValidator):  
    8083                "Connection": "close",
    8184                "User-Agent": self.user_agent,
    8285            }
     86            broken_error = ValidationError(_(u'This URL appears to be a broken link.'), code='invalid_link')
    8387            try:
    84                 req = urllib2.Request(url, None, headers)
     88                req = HeadRequest(url, None, headers)
    8589                u = urllib2.urlopen(req)
    8690            except ValueError:
    8791                raise ValidationError(_(u'Enter a valid URL.'), code='invalid')
     92            except urllib2.HTTPError, e:
     93                if e.code in (405, 501):
     94                    # Try a GET request (HEAD refused)
     95                    # See also: http://www.w3.org/Protocols/rfc2616/rfc2616.html
     96                    try:
     97                        req = urllib2.Request(url, None, headers)
     98                        u = urllib2.urlopen(req)
     99                    except:
     100                        raise broken_error
     101                else:
     102                    raise broken_error
    88103            except: # urllib2.URLError, httplib.InvalidURL, etc.
    89                 raise ValidationError(_(u'This URL appears to be a broken link.'), code='invalid_link')
     104                raise broken_error
    90105
    91106
    92107def validate_integer(value):
  • tests/regressiontests/forms/tests/fields.py

    diff --git a/tests/regressiontests/forms/tests/fields.py b/tests/regressiontests/forms/tests/fields.py
    index 93ca5c1..9bf5bb0 100644
    a b class FieldsTests(TestCase):  
    523523        self.assertEqual(u'http://www.google.com/', f.clean('http://www.google.com')) # This will fail if there's no Internet connection
    524524        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example')
    525525        self.assertRaises(ValidationError, f.clean, 'http://www.broken.djangoproject.com') # bad domain
     526        self.assertRaises(ValidationError, f.clean, 'http://qa-dev.w3.org/link-testsuite/http.php?code=405') # Method not allowed
    526527        try:
    527528            f.clean('http://www.broken.djangoproject.com') # bad domain
    528529        except ValidationError, e:
Back to Top