Fixed #17059 -- Encode `GeoIP` query strings properly so `libGeoIP` returns results for unicode strings.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17019 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2011-10-20 20:08:33 +00:00
parent b3b9049942
commit 01f4ce4c49
2 changed files with 16 additions and 4 deletions

View File

@ -132,6 +132,9 @@ class GeoIP(object):
if not isinstance(query, basestring): if not isinstance(query, basestring):
raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__) raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__)
# GeoIP only takes ASCII-encoded strings.
query = query.encode('ascii')
# Extra checks for the existence of country and city databases. # Extra checks for the existence of country and city databases.
if city_or_country and not (self._country or self._city): if city_or_country and not (self._country or self._city):
raise GeoIPException('Invalid GeoIP country and city data files.') raise GeoIPException('Invalid GeoIP country and city data files.')
@ -140,13 +143,16 @@ class GeoIP(object):
elif city and not self._city: elif city and not self._city:
raise GeoIPException('Invalid GeoIP city data file: %s' % self._city_file) raise GeoIPException('Invalid GeoIP city data file: %s' % self._city_file)
# Return the query string back to the caller.
return query
def city(self, query): def city(self, query):
""" """
Returns a dictionary of city information for the given IP address or Returns a dictionary of city information for the given IP address or
Fully Qualified Domain Name (FQDN). Some information in the dictionary Fully Qualified Domain Name (FQDN). Some information in the dictionary
may be undefined (None). may be undefined (None).
""" """
self._check_query(query, city=True) query = self._check_query(query, city=True)
if ipv4_re.match(query): if ipv4_re.match(query):
# If an IP address was passed in # If an IP address was passed in
return GeoIP_record_by_addr(self._city, c_char_p(query)) return GeoIP_record_by_addr(self._city, c_char_p(query))
@ -156,7 +162,7 @@ class GeoIP(object):
def country_code(self, query): def country_code(self, query):
"Returns the country code for the given IP Address or FQDN." "Returns the country code for the given IP Address or FQDN."
self._check_query(query, city_or_country=True) query = self._check_query(query, city_or_country=True)
if self._country: if self._country:
if ipv4_re.match(query): if ipv4_re.match(query):
return GeoIP_country_code_by_addr(self._country, query) return GeoIP_country_code_by_addr(self._country, query)
@ -167,7 +173,7 @@ class GeoIP(object):
def country_name(self, query): def country_name(self, query):
"Returns the country name for the given IP Address or FQDN." "Returns the country name for the given IP Address or FQDN."
self._check_query(query, city_or_country=True) query = self._check_query(query, city_or_country=True)
if self._country: if self._country:
if ipv4_re.match(query): if ipv4_re.match(query):
return GeoIP_country_name_by_addr(self._country, query) return GeoIP_country_name_by_addr(self._country, query)

View File

@ -95,12 +95,18 @@ class GeoIPTest(unittest.TestCase):
self.assertAlmostEqual(lon, tup[0], 4) self.assertAlmostEqual(lon, tup[0], 4)
self.assertAlmostEqual(lat, tup[1], 4) self.assertAlmostEqual(lat, tup[1], 4)
def test05_unicode(self): def test05_unicode_response(self):
"Testing that GeoIP strings are properly encoded, see #16553." "Testing that GeoIP strings are properly encoded, see #16553."
g = GeoIP() g = GeoIP()
d = g.city('62.224.93.23') d = g.city('62.224.93.23')
self.assertEqual(u'Sch\xf6mberg', d['city']) self.assertEqual(u'Sch\xf6mberg', d['city'])
def test06_unicode_query(self):
"Testing that GeoIP accepts unicode string queries, see #17059."
g = GeoIP()
d = g.country(u'whitehouse.gov')
self.assertEqual(u'US', d['country_code'])
def suite(): def suite():
s = unittest.TestSuite() s = unittest.TestSuite()