[Jython-checkins] jython: Issue 2078: Fix tuple creation for inet6 addresses, and work around for bound
jim.baker
jython-checkins at python.org
Thu May 22 23:17:20 CEST 2014
http://hg.python.org/jython/rev/0e62bf96c773
changeset: 7271:0e62bf96c773
parent: 7264:06161ebf74ee
user: Santoso Wijaya <santoso.wijaya at gmail.com>
date: Wed May 21 18:40:34 2014 -0700
summary:
Issue 2078: Fix tuple creation for inet6 addresses, and work around for bound inet4 socket local address.
files:
Lib/_socket.py | 21 +++++++++++++++++----
Lib/test/test_socket.py | 16 ++++++++++++++++
2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/Lib/_socket.py b/Lib/_socket.py
--- a/Lib/_socket.py
+++ b/Lib/_socket.py
@@ -605,6 +605,14 @@
}
}
+def _socktuple(addr):
+ port = addr.getPort()
+ inet_addr = addr.getAddress()
+ if isinstance(inet_addr, java.net.Inet6Address):
+ return str(inet_addr.getHostAddress()), port, 0, inet_addr.getScopeId()
+ else:
+ return str(inet_addr.getHostAddress()), port
+
# actual socket support
#######################
@@ -826,7 +834,7 @@
self.child_handler = ChildSocketHandler(self)
b.childHandler(self.child_handler)
- future = b.bind(self.bind_addr)
+ future = b.bind(self.bind_addr.getAddress(), self.bind_addr.getPort())
self._handle_channel_future(future, "listen")
self.bind_timestamp = time.time()
self.channel = future.channel()
@@ -1103,7 +1111,7 @@
if self.bind_addr == _EPHEMERAL_ADDRESS:
raise error(errno.ENOTCONN, "Socket is not connected")
else:
- return self.bind_addr.getHostString(), self.bind_addr.getPort()
+ return _socktuple(self.bind_addr)
# Netty 4 currently races between bind to ephemeral port and the availability
# of the local address for the channel. Workaround for now is to poll.
while True:
@@ -1116,14 +1124,19 @@
raise error(errno.ENOTCONN, "Socket is not connected")
log.debug("Poll for local address", extra={"sock": self})
time.sleep(0.1) # completely arbitrary
- return local_addr.getHostString(), local_addr.getPort()
+ if local_addr.getAddress().isAnyLocalAddress():
+ # Netty 4 will default to an IPv6 "any" address from a channel even if it was originally bound to an IPv4 "any" address
+ # so, as a workaround, let's construct a new "any" address using the port information gathered above
+ if type(self.bind_addr.getAddress()) != type(local_addr.getAddress()):
+ return _socktuple(java.net.InetSocketAddress(self.bind_addr.getAddress(), local_addr.getPort()))
+ return _socktuple(local_addr)
def getpeername(self):
self._verify_channel()
remote_addr = self.channel.remoteAddress()
if remote_addr is None:
raise error(errno.ENOTCONN, "Socket is not connected")
- return remote_addr.getHostString(), remote_addr.getPort()
+ return _socktuple(remote_addr)
_socketmethods = (
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -577,6 +577,22 @@
name = sock.getsockname()
self.assertEqual(name, ("0.0.0.0", PORT+1))
+ def testSockNameEphemeralV4(self):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.bind(('', 0))
+ sock.listen(1)
+ name = sock.getsockname()
+ self.assertEqual(len(name), 2)
+ self.assertNotEqual(name[1], 0)
+
+ def testSockNameEphemeralV6(self):
+ sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+ sock.bind(('', 0, 0, 0))
+ sock.listen(1)
+ name = sock.getsockname()
+ self.assertEqual(len(name), 4)
+ self.assertNotEqual(name[1], 0)
+
def testSockAttributes(self):
# Testing required attributes
for family in [socket.AF_INET, socket.AF_INET6]:
--
Repository URL: http://hg.python.org/jython
More information about the Jython-checkins
mailing list