summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Petrov <shazow@gmail.com>2015-05-12 09:59:25 -0700
committerAndrey Petrov <shazow@gmail.com>2015-05-12 09:59:25 -0700
commit4180af1870f9fdc4f7ef1f5f8056ff82f6faac3a (patch)
tree9a6157c10a9a6f1a4c5485320a7c4400b2eb2ef7
parente9aa367f791967df3c3884b1b8707e432ee7b6bb (diff)
parentcf1dd49a285f5467c7629291aad7e1ccbc76fede (diff)
downloadurllib3-4180af1870f9fdc4f7ef1f5f8056ff82f6faac3a.tar.gz
Merge pull request #611 from ddriddle/issue_610
Tests fallback to IPv4 if IPv6 fails
-rw-r--r--CONTRIBUTORS.txt3
-rwxr-xr-xdummyserver/server.py33
-rw-r--r--test/with_dummyserver/test_connectionpool.py4
-rw-r--r--test/with_dummyserver/test_poolmanager.py5
4 files changed, 41 insertions, 4 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 58073075..9ce382e6 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -148,6 +148,9 @@ In chronological order:
* tlynn <https://github.com/tlynn>
* Respect the warning preferences at import.
+* David D. Riddle <ddriddle@illinois.edu>
+ * IPv6 bugfixes in testsuite
+
* [Your name or handle] <[email or website]>
* [Brief summary of your changes]
diff --git a/dummyserver/server.py b/dummyserver/server.py
index 63124d35..19994749 100755
--- a/dummyserver/server.py
+++ b/dummyserver/server.py
@@ -38,6 +38,35 @@ DEFAULT_CA = os.path.join(CERTS_PATH, 'cacert.pem')
DEFAULT_CA_BAD = os.path.join(CERTS_PATH, 'client_bad.pem')
NO_SAN_CA = os.path.join(CERTS_PATH, 'cacert.no_san.pem')
+def _has_ipv6(host):
+ """ Returns True if the system can bind an IPv6 address. """
+ sock = None
+ has_ipv6 = False
+
+ if socket.has_ipv6:
+ # has_ipv6 returns true if cPython was compiled with IPv6 support.
+ # It does not tell us if the system has IPv6 support enabled. To
+ # determine that we must bind to an IPv6 address.
+ # https://github.com/shazow/urllib3/pull/611
+ # https://bugs.python.org/issue658327
+ try:
+ sock = socket.socket(socket.AF_INET6)
+ sock.bind((host, 0))
+ has_ipv6 = True
+ except:
+ pass
+
+ if sock:
+ sock.close()
+ return has_ipv6
+
+# Some systems may have IPv6 support but DNS may not be configured
+# properly. We can not count that localhost will resolve to ::1 on all
+# systems. See https://github.com/shazow/urllib3/pull/611 and
+# https://bugs.python.org/issue18792
+HAS_IPV6_AND_DNS = _has_ipv6('localhost')
+HAS_IPV6 = _has_ipv6('::1')
+
# Different types of servers we have:
@@ -64,7 +93,7 @@ class SocketServerThread(threading.Thread):
self.ready_event = ready_event
def _start_server(self):
- if socket.has_ipv6:
+ if HAS_IPV6_AND_DNS:
sock = socket.socket(socket.AF_INET6)
else:
warnings.warn("No IPv6 support. Falling back to IPv4.",
@@ -117,7 +146,7 @@ def bind_sockets(port, address=None, family=socket.AF_UNSPEC, backlog=128,
sockets = []
if address == "":
address = None
- if not socket.has_ipv6 and family == socket.AF_UNSPEC:
+ if not HAS_IPV6 and family == socket.AF_UNSPEC:
# Python can be compiled with --disable-ipv6, which causes
# operations on AF_INET6 sockets to fail, but does not
# automatically exclude those results from getaddrinfo
diff --git a/test/with_dummyserver/test_connectionpool.py b/test/with_dummyserver/test_connectionpool.py
index d6cb1622..943db2ee 100644
--- a/test/with_dummyserver/test_connectionpool.py
+++ b/test/with_dummyserver/test_connectionpool.py
@@ -36,7 +36,7 @@ from urllib3.util.timeout import Timeout
import tornado
from dummyserver.testcase import HTTPDummyServerTestCase
-from dummyserver.server import NoIPv6Warning
+from dummyserver.server import NoIPv6Warning, HAS_IPV6_AND_DNS
from nose.tools import timed
@@ -600,7 +600,7 @@ class TestConnectionPool(HTTPDummyServerTestCase):
def test_source_address(self):
for addr, is_ipv6 in VALID_SOURCE_ADDRESSES:
- if is_ipv6 and not socket.has_ipv6:
+ if is_ipv6 and not HAS_IPV6_AND_DNS:
warnings.warn("No IPv6 support: skipping.",
NoIPv6Warning)
continue
diff --git a/test/with_dummyserver/test_poolmanager.py b/test/with_dummyserver/test_poolmanager.py
index 7e51c730..7553e70a 100644
--- a/test/with_dummyserver/test_poolmanager.py
+++ b/test/with_dummyserver/test_poolmanager.py
@@ -1,6 +1,8 @@
import unittest
import json
+from nose.plugins.skip import SkipTest
+from dummyserver.server import HAS_IPV6
from dummyserver.testcase import (HTTPDummyServerTestCase,
IPv6HTTPDummyServerTestCase)
from urllib3.poolmanager import PoolManager
@@ -154,6 +156,9 @@ class TestPoolManager(HTTPDummyServerTestCase):
class TestIPv6PoolManager(IPv6HTTPDummyServerTestCase):
+ if not HAS_IPV6:
+ raise SkipTest("IPv6 is not supported on this system.")
+
def setUp(self):
self.base_url = 'http://[%s]:%d' % (self.host, self.port)