Commits

Michael Manfre committed 1dd14cb

Fixed #21 - IP Address detection now uses Django's IPv4 (and IPv6 for Django >=1.4) and no longer crash on FQDN

Comments (0)

Files changed (3)

docs/changelog.txt

   the database because there will be no response.
 - Implemented DatabaseOperation ``cache_key_culling_sql``. :djangoticket:`18330`
 - Fixed ``cast_avg_to_float`` so that it only controls the cast for ``AVG`` and not mapping other aggregates.
+- Improved IP address detection of :setting:`HOST` setting. :issue:`21`
 
 v1.2
 ----

sqlserver_ado/base.py

 """Microsoft SQL Server database backend for Django."""
 from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseValidation, BaseDatabaseClient
 from django.db.backends.signals import connection_created
-from django.core.exceptions import ImproperlyConfigured
+from django.core.exceptions import ImproperlyConfigured, ValidationError
 
 import dbapi as Database
 
     
     supports_tablespaces = True
 
-# IP Address recognizer taken from:
-# http://mail.python.org/pipermail/python-list/2006-March/375505.html
-def _looks_like_ipaddress(address):
-    dots = address.split(".")
-    if len(dots) != 4:
+
+def is_ip_address(value):
+    """
+    Returns True if value is a valid IP address, otherwise False.
+    """
+    try:
+        # IPv6 added with Django 1.4
+        from django.core.validators import validate_ipv46_address as ip_validator
+    except ImportError:
+        # Fallback to only IPv4 for older Django
+        from django.core.validators import validate_ipv4_address as ip_validator
+    
+    try:
+        ip_validator(value)
+    except ValidationError:
         return False
-    for item in dots:
-        if not 0 <= int(item) <= 255:
-            return False
     return True
 
 def connection_string_from_settings():
 
     # If a port is given, force a TCP/IP connection. The host should be an IP address in this case.
     if settings.PORT:
-        if not _looks_like_ipaddress(db_host):
+        if not is_ip_address(db_host):
             raise ImproperlyConfigured("When using DATABASE PORT, DATABASE HOST must be an IP address.")
         try:
             port = int(settings.PORT)

tests/test_main/regressiontests/tests.py

         self.assertInString(conn_string, 'PWD=mypass;')
         self.assertNotInString(conn_string, 'Integrated Security=SSPI')
 
-    def test_port(self):
+    def test_port_with_host(self):
         """Test the PORT setting to make sure it properly updates the connection string"""
         self.assertRaises(ImproperlyConfigured, self.get_conn_string,
             {'HOST': 'myhost', 'PORT': 1433})
         extras = 'Some=Extra;Stuff Goes=here'
         conn_string = self.get_conn_string({'OPTIONS': {'extra_params': extras}})
         self.assertInString(conn_string, extras)
+
+    def test_host_fqdn_with_port(self):
+        """
+        Issue 21 - FQDN crashed on IP address detection.
+        """
+        with self.assertRaisesRegexp(ImproperlyConfigured, 'DATABASE HOST must be an IP address'):
+            self.get_conn_string(data={
+                'HOST': 'my.fqdn.com',
+                'PORT': '1433',
+            })
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.