Author: russellm
Date: 2011-01-15 00:31:38 -0600 (Sat, 15 Jan 2011)
New Revision: 15215
Modified:
django/trunk/django/core/management/commands/runserver.py
django/trunk/docs/ref/django-admin.txt
django/trunk/tests/regressiontests/admin_scripts/tests.py
Log:
Fixed #14928 -- Ensure that a fully qualified domain name can be used for
runserver. Thanks to Karmel Allison for the report, ?\197?\129ukasz Rekucki for
the patch, and claudep for the tests.
Modified: django/trunk/django/core/management/commands/runserver.py
===================================================================
--- django/trunk/django/core/management/commands/runserver.py 2011-01-15
06:12:56 UTC (rev 15214)
+++ django/trunk/django/core/management/commands/runserver.py 2011-01-15
06:31:38 UTC (rev 15215)
@@ -9,7 +9,12 @@
from django.core.servers.basehttp import AdminMediaHandler, run,
WSGIServerException
from django.utils import autoreload
-naiveip_re =
r'^(?:(?P<addr>\d{1,3}(?:\.\d{1,3}){3}|\[[a-fA-F0-9:]+\]):)?(?P<port>\d+)$'
+naiveip_re = re.compile(r"""^(?:
+(?P<addr>
+ (?P<ipv4>\d{1,3}(?:\.\d{1,3}){3}) | # IPv4 address
+ (?P<ipv6>\[[a-fA-F0-9:]+\]) | # IPv6 address
+ (?P<fqdn>[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*) # FQDN
+):)?(?P<port>\d+)$""", re.X)
DEFAULT_PORT = "8000"
class BaseRunserverCommand(BaseCommand):
@@ -33,28 +38,29 @@
def handle(self, addrport='', *args, **options):
self.use_ipv6 = options.get('use_ipv6')
- if self.use_ipv6 and not hasattr(socket, 'AF_INET6'):
+ if self.use_ipv6 and not socket.has_ipv6:
raise CommandError('Your Python does not support IPv6.')
if args:
raise CommandError('Usage is runserver %s' % self.args)
+ self._raw_ipv6 = False
if not addrport:
self.addr = ''
self.port = DEFAULT_PORT
else:
m = re.match(naiveip_re, addrport)
if m is None:
- raise CommandError('%r is not a valid port number'
+ raise CommandError('"%s" is not a valid port number '
'or address:port pair.' % addrport)
- self.addr, self.port = m.groups()
+ self.addr, _ipv4, _ipv6, _fqdn, self.port = m.groups()
if not self.port.isdigit():
raise CommandError("%r is not a valid port number." %
self.port)
if self.addr:
- if self.addr.startswith('[') and self.addr.endswith(']'):
+ if _ipv6:
self.addr = self.addr[1:-1]
self.use_ipv6 = True
- elif self.use_ipv6:
- raise CommandError('IPv6 addresses must be surrounded '
- 'with brackets, e.g. [::1].')
+ self._raw_ipv6 = True
+ elif self.use_ipv6 and not _fqdn:
+ raise CommandError('"%s" is not a valid IPv6 address.' %
self.addr)
if not self.addr:
self.addr = self.use_ipv6 and '::1' or '127.0.0.1'
self.run(*args, **options)
@@ -86,7 +92,7 @@
) % {
"version": self.get_version(),
"settings": settings.SETTINGS_MODULE,
- "addr": self.use_ipv6 and '[%s]' % self.addr or self.addr,
+ "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr,
"port": self.port,
"quit_command": quit_command,
})
Modified: django/trunk/docs/ref/django-admin.txt
===================================================================
--- django/trunk/docs/ref/django-admin.txt 2011-01-15 06:12:56 UTC (rev
15214)
+++ django/trunk/docs/ref/django-admin.txt 2011-01-15 06:31:38 UTC (rev
15215)
@@ -616,7 +616,7 @@
Run a FastCGI server as a daemon and write the spawned PID in a file.
-runserver [port or ipaddr:port]
+runserver [port or address:port]
-------------------------------
.. django-admin:: runserver
@@ -653,9 +653,11 @@
.. versionchanged:: 1.3
-You can also provide an IPv6 address surrounded by brackets
-(eg. ``[200a::1]:8000``). This will automaticaly enable IPv6 support.
+You can provide an IPv6 address surrounded by brackets
+(e.g. ``[200a::1]:8000``). This will automatically enable IPv6 support.
+A hostname containing ASCII-only characters can also be used.
+
.. django-admin-option:: --adminmedia
Use the ``--adminmedia`` option to tell Django where to find the various CSS
@@ -721,6 +723,14 @@
django-admin.py runserver [2001:0db8:1234:5678::9]:7000
+Port 8000 on IPv4 address of host ``localhost``::
+
+ django-admin.py runserver localhost:8000
+
+Port 8000 on IPv6 address of host ``localhost``::
+
+ django-admin.py runserver -6 localhost:8000
+
Serving static files with the development server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: django/trunk/tests/regressiontests/admin_scripts/tests.py
===================================================================
--- django/trunk/tests/regressiontests/admin_scripts/tests.py 2011-01-15
06:12:56 UTC (rev 15214)
+++ django/trunk/tests/regressiontests/admin_scripts/tests.py 2011-01-15
06:31:38 UTC (rev 15215)
@@ -999,6 +999,61 @@
self.assertNoOutput(err)
self.assertOutput(out, '0 errors found')
+class ManageRunserver(AdminScriptTestCase):
+ def setUp(self):
+ from django.core.management.commands.runserver import
BaseRunserverCommand
+ def monkey_run(*args, **options): return
+
+ self.cmd = BaseRunserverCommand()
+ self.cmd.run = monkey_run
+
+ def assertServerSettings(self, addr, port, ipv6=None, raw_ipv6=False):
+ self.assertEqual(self.cmd.addr, addr)
+ self.assertEqual(self.cmd.port, port)
+ self.assertEqual(self.cmd.use_ipv6, ipv6)
+ self.assertEqual(self.cmd._raw_ipv6, raw_ipv6)
+
+ def test_runserver_addrport(self):
+ self.cmd.handle()
+ self.assertServerSettings('127.0.0.1', '8000')
+
+ self.cmd.handle(addrport="1.2.3.4:8000")
+ self.assertServerSettings('1.2.3.4', '8000')
+
+ self.cmd.handle(addrport="7000")
+ self.assertServerSettings('127.0.0.1', '7000')
+
+ # IPv6
+ self.cmd.handle(addrport="", use_ipv6=True)
+ self.assertServerSettings('::1', '8000', ipv6=True)
+
+ self.cmd.handle(addrport="7000", use_ipv6=True)
+ self.assertServerSettings('::1', '7000', ipv6=True)
+
+ self.cmd.handle(addrport="[2001:0db8:1234:5678::9]:7000")
+ self.assertServerSettings('2001:0db8:1234:5678::9', '7000', ipv6=True,
raw_ipv6=True)
+
+ # Hostname
+ self.cmd.handle(addrport="localhost:8000")
+ self.assertServerSettings('localhost', '8000')
+
+ self.cmd.handle(addrport="test.domain.local:7000")
+ self.assertServerSettings('test.domain.local', '7000')
+
+ self.cmd.handle(addrport="test.domain.local:7000", use_ipv6=True)
+ self.assertServerSettings('test.domain.local', '7000', ipv6=True)
+
+ # Potentially ambiguous
+
+ # Only 4 characters, all of which coudl be in an ipv6 address
+ self.cmd.handle(addrport="beef:7654")
+ self.assertServerSettings('beef', '7654')
+
+ # Uses only characters that could be in an ipv6 address
+ self.cmd.handle(addrport="deadbeef:7654")
+ self.assertServerSettings('deadbeef', '7654')
+
+
##########################################################################
# COMMAND PROCESSING TESTS
# Check that user-space commands are correctly handled - in particular,
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.