[WebUI] Log correct http address if listening on IPv6

This commit is contained in:
bendikro 2016-04-29 22:42:34 +02:00 committed by Calum Lind
parent 7283e8b668
commit 0edebda1c7
5 changed files with 88 additions and 30 deletions

View File

@ -11,8 +11,10 @@
* geoip-database (optional)
* setproctitle (optional)
* pillow (optional)
* py2-ipaddress (optional, required for Windows IPv6)
* rencode >= 1.0.2 (optional), python port bundled.
=== Gtk UI ===
* pygtk >= 2.16
* librsvg

View File

@ -721,44 +721,84 @@ def free_space(path):
def is_ip(ip):
"""
A simple test to see if 'ip' is valid
"""A test to see if 'ip' is a valid IPv4 or IPv6 address.
:param ip: the ip to check
:type ip: string
:returns: True or False
:rtype: bool
Args:
ip (str): The IP to test.
:Example:
Returns:
bool: Whether IP is valid is not.
>>> is_ip('127.0.0.1')
True
Examples:
>>> is_ip("192.0.2.0")
True
>>> is_ip("2001:db8::")
True
"""
return is_ipv4(ip) or is_ipv6(ip)
def is_ipv4(ip):
"""A test to see if 'ip' is a valid IPv4 address.
Args:
ip (str): The IP to test.
Returns:
bool: Whether IP is valid is not.
Examples:
>>> is_ipv4("192.0.2.0")
True
"""
import socket
# first we test ipv4
try:
if windows_check():
if socket.inet_aton(ip):
return True
return socket.inet_aton(ip)
else:
if socket.inet_pton(socket.AF_INET, ip):
return True
except socket.error:
if not socket.has_ipv6:
return False
# now test ipv6
try:
if windows_check():
log.warning('ipv6 check unavailable on windows')
return True
else:
if socket.inet_pton(socket.AF_INET6, ip):
return True
return socket.inet_pton(socket.AF_INET, ip)
except socket.error:
return False
def is_ipv6(ip):
"""A test to see if 'ip' is a valid IPv6 address.
Args:
ip (str): The IP to test.
Returns:
bool: Whether IP is valid is not.
Examples:
>>> is_ipv6("2001:db8::")
True
"""
try:
import ipaddress
except ImportError:
import socket
try:
return socket.inet_pton(socket.AF_INET6, ip)
except (socket.error, AttributeError):
if windows_check():
log.warning('Unable to verify IPv6 Address on Windows.')
return True
else:
try:
return ipaddress.IPv6Address(ip)
except ipaddress.AddressValueError:
pass
return False
def decode_string(s, encoding='utf8'):
"""
Decodes a string and return unicode. If it cannot decode using

View File

@ -68,8 +68,18 @@ class CommonTestCase(unittest.TestCase):
self.failUnless(get_path_size('non-existant.file') == -1)
def test_is_ip(self):
self.failUnless(is_ip('127.0.0.1'))
self.failIf(is_ip('127..0.0'))
self.failUnless(is_ip('192.0.2.0'))
self.failIf(is_ip('192..0.0'))
self.failUnless(is_ip('2001:db8::'))
self.failIf(is_ip('2001:db8:'))
def test_is_ipv4(self):
self.failUnless(is_ip('192.0.2.0'))
self.failIf(is_ip('192..0.0'))
def test_is_ipv6(self):
self.failUnless(is_ip('2001:db8::'))
self.failIf(is_ip('2001:db8:'))
def test_version_split(self):
self.failUnless(VersionSplit('1.2.2') == VersionSplit('1.2.2'))

View File

@ -21,6 +21,7 @@ from twisted.internet.ssl import SSL, Certificate, CertificateOptions, KeyPair
from twisted.web import http, resource, server, static
from deluge import common, component, configmanager
from deluge.common import is_ipv6
from deluge.core.rpcserver import check_ssl_keys
from deluge.ui.tracker_icons import TrackerIcons
from deluge.ui.util import lang
@ -568,7 +569,7 @@ class DelugeWeb(component.Component):
self.base = self.config['base']
if options:
self.interface = options.interface if options.interface else self.interface
self.interface = options.interface if options.interface is not None else self.interface
self.port = options.port if options.port else self.port
self.base = options.base if options.base else self.base
if options.ssl:
@ -635,7 +636,9 @@ class DelugeWeb(component.Component):
def start_normal(self):
self.socket = reactor.listenTCP(self.port, self.site, interface=self.interface)
log.info('Serving at http://%s:%s%s', self.interface, self.port, self.base)
ip = self.socket.getHost().host
ip = '[%s]' % ip if is_ipv6(ip) else ip
log.info('Serving at http://%s:%s%s', ip, self.port, self.base)
def start_ssl(self):
check_ssl_keys()
@ -649,7 +652,9 @@ class DelugeWeb(component.Component):
options.getContext().set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)
self.socket = reactor.listenSSL(self.port, self.site, options, interface=self.interface)
log.info('Serving at https://%s:%s%s', self.interface, self.port, self.base)
ip = self.socket.getHost().host
ip = '[%s]' % ip if is_ipv6(ip) else ip
log.info('Serving at https://%s:%s%s', ip, self.port, self.base)
def stop(self):
log.info('Shutting down webserver')

View File

@ -31,6 +31,7 @@ deps =
mock
slimit
pillow
py2-ipaddress
whitelist_externals = py.test
commands = {envpython} setup.py test