PageRenderTime 224ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/socket.py

https://bitbucket.org/shashank/jython
Python | 1923 lines | 1762 code | 93 blank | 68 comment | 88 complexity | a078b219f931826a6be23f9d533fce2f MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. """
  2. This is an updated socket module for use on JVMs >= 1.5; it is derived from the old jython socket module.
  3. It is documented, along with known issues and workarounds, on the jython wiki.
  4. http://wiki.python.org/jython/NewSocketModule
  5. """
  6. _defaulttimeout = None
  7. import errno
  8. import jarray
  9. import string
  10. import struct
  11. import sys
  12. import threading
  13. import time
  14. import types
  15. # Java.io classes
  16. import java.io.BufferedInputStream
  17. import java.io.BufferedOutputStream
  18. # Java.io exceptions
  19. import java.io.InterruptedIOException
  20. import java.io.IOException
  21. # Java.lang classes
  22. import java.lang.String
  23. # Java.lang exceptions
  24. import java.lang.Exception
  25. # Java.net classes
  26. import java.net.DatagramPacket
  27. import java.net.InetAddress
  28. import java.net.InetSocketAddress
  29. import java.net.Socket
  30. # Java.net exceptions
  31. import java.net.BindException
  32. import java.net.ConnectException
  33. import java.net.NoRouteToHostException
  34. import java.net.PortUnreachableException
  35. import java.net.ProtocolException
  36. import java.net.SocketException
  37. import java.net.SocketTimeoutException
  38. import java.net.UnknownHostException
  39. # Java.nio classes
  40. import java.nio.ByteBuffer
  41. import java.nio.channels.DatagramChannel
  42. import java.nio.channels.ServerSocketChannel
  43. import java.nio.channels.SocketChannel
  44. # Java.nio exceptions
  45. import java.nio.channels.AlreadyConnectedException
  46. import java.nio.channels.AsynchronousCloseException
  47. import java.nio.channels.CancelledKeyException
  48. import java.nio.channels.ClosedByInterruptException
  49. import java.nio.channels.ClosedChannelException
  50. import java.nio.channels.ClosedSelectorException
  51. import java.nio.channels.ConnectionPendingException
  52. import java.nio.channels.IllegalBlockingModeException
  53. import java.nio.channels.IllegalSelectorException
  54. import java.nio.channels.NoConnectionPendingException
  55. import java.nio.channels.NonReadableChannelException
  56. import java.nio.channels.NonWritableChannelException
  57. import java.nio.channels.NotYetBoundException
  58. import java.nio.channels.NotYetConnectedException
  59. import java.nio.channels.UnresolvedAddressException
  60. import java.nio.channels.UnsupportedAddressTypeException
  61. # Javax.net.ssl classes
  62. import javax.net.ssl.SSLSocketFactory
  63. # Javax.net.ssl exceptions
  64. javax.net.ssl.SSLException
  65. javax.net.ssl.SSLHandshakeException
  66. javax.net.ssl.SSLKeyException
  67. javax.net.ssl.SSLPeerUnverifiedException
  68. javax.net.ssl.SSLProtocolException
  69. import org.python.core.io.DatagramSocketIO
  70. import org.python.core.io.ServerSocketIO
  71. import org.python.core.io.SocketIO
  72. from org.python.core.Py import newString as asPyString
  73. class error(IOError): pass
  74. class herror(error): pass
  75. class gaierror(error): pass
  76. class timeout(error): pass
  77. class sslerror(error): pass
  78. def _add_exception_attrs(exc):
  79. setattr(exc, 'errno', exc[0])
  80. setattr(exc, 'strerror', exc[1])
  81. return exc
  82. def _unmapped_exception(exc):
  83. return _add_exception_attrs(error(-1, 'Unmapped exception: %s' % exc))
  84. def java_net_socketexception_handler(exc):
  85. if exc.message.startswith("Address family not supported by protocol family"):
  86. return _add_exception_attrs(error(errno.EAFNOSUPPORT,
  87. 'Address family not supported by protocol family: See http://wiki.python.org/jython/NewSocketModule#IPV6_address_support'))
  88. return _unmapped_exception(exc)
  89. def would_block_error(exc=None):
  90. return _add_exception_attrs(error(errno.EWOULDBLOCK, 'The socket operation could not complete without blocking'))
  91. ALL = None
  92. _ssl_message = ": Differences between the SSL socket behaviour of cpython vs. jython are explained on the wiki: http://wiki.python.org/jython/NewSocketModule#SSL_Support"
  93. _exception_map = {
  94. # (<javaexception>, <circumstance>) : callable that raises the python equivalent exception, or None to stub out as unmapped
  95. (java.io.IOException, ALL) : lambda x: error(errno.ECONNRESET, 'Software caused connection abort'),
  96. (java.io.InterruptedIOException, ALL) : lambda x: timeout(None, 'timed out'),
  97. (java.net.BindException, ALL) : lambda x: error(errno.EADDRINUSE, 'Address already in use'),
  98. (java.net.ConnectException, ALL) : lambda x: error(errno.ECONNREFUSED, 'Connection refused'),
  99. (java.net.NoRouteToHostException, ALL) : lambda x: error(errno.EHOSTUNREACH, 'No route to host'),
  100. (java.net.PortUnreachableException, ALL) : None,
  101. (java.net.ProtocolException, ALL) : None,
  102. (java.net.SocketException, ALL) : java_net_socketexception_handler,
  103. (java.net.SocketTimeoutException, ALL) : lambda x: timeout(None, 'timed out'),
  104. (java.net.UnknownHostException, ALL) : lambda x: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'),
  105. (java.nio.channels.AlreadyConnectedException, ALL) : lambda x: error(errno.EISCONN, 'Socket is already connected'),
  106. (java.nio.channels.AsynchronousCloseException, ALL) : None,
  107. (java.nio.channels.CancelledKeyException, ALL) : None,
  108. (java.nio.channels.ClosedByInterruptException, ALL) : None,
  109. (java.nio.channels.ClosedChannelException, ALL) : lambda x: error(errno.EPIPE, 'Socket closed'),
  110. (java.nio.channels.ClosedSelectorException, ALL) : None,
  111. (java.nio.channels.ConnectionPendingException, ALL) : None,
  112. (java.nio.channels.IllegalBlockingModeException, ALL) : None,
  113. (java.nio.channels.IllegalSelectorException, ALL) : None,
  114. (java.nio.channels.NoConnectionPendingException, ALL) : None,
  115. (java.nio.channels.NonReadableChannelException, ALL) : None,
  116. (java.nio.channels.NonWritableChannelException, ALL) : None,
  117. (java.nio.channels.NotYetBoundException, ALL) : None,
  118. (java.nio.channels.NotYetConnectedException, ALL) : None,
  119. (java.nio.channels.UnresolvedAddressException, ALL) : lambda x: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'),
  120. (java.nio.channels.UnsupportedAddressTypeException, ALL) : None,
  121. # These error codes are currently wrong: getting them correct is going to require
  122. # some investigation. Cpython 2.6 introduced extensive SSL support.
  123. (javax.net.ssl.SSLException, ALL) : lambda x: sslerror(-1, 'SSL exception'+_ssl_message),
  124. (javax.net.ssl.SSLHandshakeException, ALL) : lambda x: sslerror(-1, 'SSL handshake exception'+_ssl_message),
  125. (javax.net.ssl.SSLKeyException, ALL) : lambda x: sslerror(-1, 'SSL key exception'+_ssl_message),
  126. (javax.net.ssl.SSLPeerUnverifiedException, ALL) : lambda x: sslerror(-1, 'SSL peer unverified exception'+_ssl_message),
  127. (javax.net.ssl.SSLProtocolException, ALL) : lambda x: sslerror(-1, 'SSL protocol exception'+_ssl_message),
  128. }
  129. def _map_exception(java_exception, circumstance=ALL):
  130. mapped_exception = _exception_map.get((java_exception.__class__, circumstance))
  131. if mapped_exception:
  132. py_exception = mapped_exception(java_exception)
  133. else:
  134. py_exception = error(-1, 'Unmapped exception: %s' % java_exception)
  135. setattr(py_exception, 'java_exception', java_exception)
  136. return _add_exception_attrs(py_exception)
  137. _feature_support_map = {
  138. 'ipv6': True,
  139. 'idna': False,
  140. 'tipc': False,
  141. }
  142. def supports(feature, *args):
  143. if len(args) == 1:
  144. _feature_support_map[feature] = args[0]
  145. return _feature_support_map.get(feature, False)
  146. MODE_BLOCKING = 'block'
  147. MODE_NONBLOCKING = 'nonblock'
  148. MODE_TIMEOUT = 'timeout'
  149. _permitted_modes = (MODE_BLOCKING, MODE_NONBLOCKING, MODE_TIMEOUT)
  150. SHUT_RD = 0
  151. SHUT_WR = 1
  152. SHUT_RDWR = 2
  153. AF_UNSPEC = 0
  154. AF_INET = 2
  155. AF_INET6 = 23
  156. AI_PASSIVE = 1
  157. AI_CANONNAME = 2
  158. AI_NUMERICHOST = 4
  159. AI_V4MAPPED = 8
  160. AI_ALL = 16
  161. AI_ADDRCONFIG = 32
  162. AI_NUMERICSERV = 1024
  163. EAI_NONAME = -2
  164. EAI_SERVICE = -8
  165. EAI_ADDRFAMILY = -9
  166. NI_NUMERICHOST = 1
  167. NI_NUMERICSERV = 2
  168. NI_NOFQDN = 4
  169. NI_NAMEREQD = 8
  170. NI_DGRAM = 16
  171. NI_MAXSERV = 32
  172. NI_IDN = 64
  173. NI_IDN_ALLOW_UNASSIGNED = 128
  174. NI_IDN_USE_STD3_ASCII_RULES = 256
  175. NI_MAXHOST = 1025
  176. # For some reason, probably historical, SOCK_DGRAM and SOCK_STREAM are opposite values of what they are on cpython.
  177. # I.E. The following is the way they are on cpython
  178. # SOCK_STREAM = 1
  179. # SOCK_DGRAM = 2
  180. # At some point, we should probably switch them around, which *should* not affect anybody
  181. SOCK_DGRAM = 1
  182. SOCK_STREAM = 2
  183. SOCK_RAW = 3 # not supported
  184. SOCK_RDM = 4 # not supported
  185. SOCK_SEQPACKET = 5 # not supported
  186. SOL_SOCKET = 0xFFFF
  187. IPPROTO_AH = 51 # not supported
  188. IPPROTO_DSTOPTS = 60 # not supported
  189. IPPROTO_ESP = 50 # not supported
  190. IPPROTO_FRAGMENT = 44 # not supported
  191. IPPROTO_GGP = 3 # not supported
  192. IPPROTO_HOPOPTS = 0 # not supported
  193. IPPROTO_ICMP = 1 # not supported
  194. IPPROTO_ICMPV6 = 58 # not supported
  195. IPPROTO_IDP = 22 # not supported
  196. IPPROTO_IGMP = 2 # not supported
  197. IPPROTO_IP = 0
  198. IPPROTO_IPV4 = 4 # not supported
  199. IPPROTO_IPV6 = 41 # not supported
  200. IPPROTO_MAX = 256 # not supported
  201. IPPROTO_ND = 77 # not supported
  202. IPPROTO_NONE = 59 # not supported
  203. IPPROTO_PUP = 12 # not supported
  204. IPPROTO_RAW = 255 # not supported
  205. IPPROTO_ROUTING = 43 # not supported
  206. IPPROTO_TCP = 6
  207. IPPROTO_UDP = 17
  208. SO_ACCEPTCONN = 1
  209. SO_BROADCAST = 2
  210. SO_ERROR = 4
  211. SO_KEEPALIVE = 8
  212. SO_LINGER = 16
  213. SO_OOBINLINE = 32
  214. SO_RCVBUF = 64
  215. SO_REUSEADDR = 128
  216. SO_SNDBUF = 256
  217. SO_TIMEOUT = 512
  218. SO_TYPE = 1024
  219. TCP_NODELAY = 2048
  220. INADDR_ANY = "0.0.0.0"
  221. INADDR_BROADCAST = "255.255.255.255"
  222. IN6ADDR_ANY_INIT = "::"
  223. # Options with negative constants are not supported
  224. # They are being added here so that code that refers to them
  225. # will not break with an AttributeError
  226. SO_DEBUG = -1
  227. SO_DONTROUTE = -1
  228. SO_EXCLUSIVEADDRUSE = -8
  229. SO_RCVLOWAT = -16
  230. SO_RCVTIMEO = -32
  231. SO_REUSEPORT = -64
  232. SO_SNDLOWAT = -128
  233. SO_SNDTIMEO = -256
  234. SO_USELOOPBACK = -512
  235. __all__ = [
  236. # Families
  237. 'AF_UNSPEC', 'AF_INET', 'AF_INET6',
  238. # getaddrinfo and getnameinfo flags
  239. 'AI_PASSIVE', 'AI_CANONNAME', 'AI_NUMERICHOST', 'AI_V4MAPPED',
  240. 'AI_ALL', 'AI_ADDRCONFIG', 'AI_NUMERICSERV', 'EAI_NONAME',
  241. 'EAI_SERVICE', 'EAI_ADDRFAMILY',
  242. 'NI_NUMERICHOST', 'NI_NUMERICSERV', 'NI_NOFQDN', 'NI_NAMEREQD',
  243. 'NI_DGRAM', 'NI_MAXSERV', 'NI_IDN', 'NI_IDN_ALLOW_UNASSIGNED',
  244. 'NI_IDN_USE_STD3_ASCII_RULES', 'NI_MAXHOST',
  245. # socket types
  246. 'SOCK_DGRAM', 'SOCK_STREAM', 'SOCK_RAW', 'SOCK_RDM', 'SOCK_SEQPACKET',
  247. # levels
  248. 'SOL_SOCKET',
  249. # protocols
  250. 'IPPROTO_AH', 'IPPROTO_DSTOPTS', 'IPPROTO_ESP', 'IPPROTO_FRAGMENT',
  251. 'IPPROTO_GGP', 'IPPROTO_HOPOPTS', 'IPPROTO_ICMP', 'IPPROTO_ICMPV6',
  252. 'IPPROTO_IDP', 'IPPROTO_IGMP', 'IPPROTO_IP', 'IPPROTO_IPV4',
  253. 'IPPROTO_IPV6', 'IPPROTO_MAX', 'IPPROTO_ND', 'IPPROTO_NONE',
  254. 'IPPROTO_PUP', 'IPPROTO_RAW', 'IPPROTO_ROUTING', 'IPPROTO_TCP',
  255. 'IPPROTO_UDP',
  256. # Special hostnames
  257. 'INADDR_ANY', 'INADDR_BROADCAST', 'IN6ADDR_ANY_INIT',
  258. # support socket options
  259. 'SO_BROADCAST', 'SO_KEEPALIVE', 'SO_LINGER', 'SO_OOBINLINE',
  260. 'SO_RCVBUF', 'SO_REUSEADDR', 'SO_SNDBUF', 'SO_TIMEOUT', 'TCP_NODELAY',
  261. # unsupported socket options
  262. 'SO_ACCEPTCONN', 'SO_DEBUG', 'SO_DONTROUTE', 'SO_ERROR',
  263. 'SO_EXCLUSIVEADDRUSE', 'SO_RCVLOWAT', 'SO_RCVTIMEO', 'SO_REUSEPORT',
  264. 'SO_SNDLOWAT', 'SO_SNDTIMEO', 'SO_TYPE', 'SO_USELOOPBACK',
  265. # functions
  266. 'getfqdn', 'gethostname', 'gethostbyname', 'gethostbyaddr',
  267. 'getservbyname', 'getservbyport', 'getprotobyname', 'getaddrinfo',
  268. 'getnameinfo', 'getdefaulttimeout', 'setdefaulttimeout', 'htons',
  269. 'htonl', 'ntohs', 'ntohl', 'inet_pton', 'inet_ntop', 'inet_aton',
  270. 'inet_ntoa', 'create_connection', 'socket', 'ssl',
  271. # exceptions
  272. 'error', 'herror', 'gaierror', 'timeout', 'sslerror,
  273. # classes
  274. 'SocketType',
  275. # Misc flags
  276. 'has_ipv6', 'SHUT_RD', 'SHUT_WR', 'SHUT_RDWR',
  277. ]
  278. def _constant_to_name(const_value, expected_name_starts):
  279. sock_module = sys.modules['socket']
  280. try:
  281. for name in dir(sock_module):
  282. if getattr(sock_module, name) is const_value:
  283. for name_start in expected_name_starts:
  284. if name.startswith(name_start):
  285. return name
  286. return "Unknown"
  287. finally:
  288. sock_module = None
  289. import _google_ipaddr_r234
  290. def _is_ip_address(addr, version=None):
  291. try:
  292. _google_ipaddr_r234.IPAddress(addr, version)
  293. return True
  294. except ValueError:
  295. return False
  296. def is_ipv4_address(addr):
  297. return _is_ip_address(addr, 4)
  298. def is_ipv6_address(addr):
  299. return _is_ip_address(addr, 6)
  300. def is_ip_address(addr):
  301. return _is_ip_address(addr)
  302. class _nio_impl:
  303. timeout = None
  304. mode = MODE_BLOCKING
  305. def config(self, mode, timeout):
  306. self.mode = mode
  307. if self.mode == MODE_BLOCKING:
  308. self.jchannel.configureBlocking(1)
  309. if self.mode == MODE_NONBLOCKING:
  310. self.jchannel.configureBlocking(0)
  311. if self.mode == MODE_TIMEOUT:
  312. self.jchannel.configureBlocking(1)
  313. self._timeout_millis = int(timeout*1000)
  314. self.jsocket.setSoTimeout(self._timeout_millis)
  315. def getsockopt(self, level, option):
  316. if (level, option) in self.options:
  317. result = getattr(self.jsocket, "get%s" % self.options[ (level, option) ])()
  318. if option == SO_LINGER:
  319. if result == -1:
  320. enabled, linger_time = 0, 0
  321. else:
  322. enabled, linger_time = 1, result
  323. return struct.pack('ii', enabled, linger_time)
  324. return result
  325. else:
  326. raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % \
  327. (_constant_to_name(option, ['SO_', 'TCP_']), _constant_to_name(level, ['SOL_', 'IPPROTO_']), str(self.jsocket)))
  328. def setsockopt(self, level, option, value):
  329. if (level, option) in self.options:
  330. if option == SO_LINGER:
  331. values = struct.unpack('ii', value)
  332. self.jsocket.setSoLinger(*values)
  333. else:
  334. getattr(self.jsocket, "set%s" % self.options[ (level, option) ])(value)
  335. else:
  336. raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % \
  337. (_constant_to_name(option, ['SO_', 'TCP_']), _constant_to_name(level, ['SOL_', 'IPPROTO_']), str(self.jsocket)))
  338. def close(self):
  339. self.jsocket.close()
  340. def getchannel(self):
  341. return self.jchannel
  342. def fileno(self):
  343. return self.socketio
  344. class _client_socket_impl(_nio_impl):
  345. options = {
  346. (SOL_SOCKET, SO_KEEPALIVE): 'KeepAlive',
  347. (SOL_SOCKET, SO_LINGER): 'SoLinger',
  348. (SOL_SOCKET, SO_OOBINLINE): 'OOBInline',
  349. (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize',
  350. (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress',
  351. (SOL_SOCKET, SO_SNDBUF): 'SendBufferSize',
  352. (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout',
  353. (IPPROTO_TCP, TCP_NODELAY): 'TcpNoDelay',
  354. }
  355. def __init__(self, socket=None, pending_options=None):
  356. if socket:
  357. self.jchannel = socket.getChannel()
  358. else:
  359. self.jchannel = java.nio.channels.SocketChannel.open()
  360. self.jsocket = self.jchannel.socket()
  361. self.socketio = org.python.core.io.SocketIO(self.jchannel, 'rw')
  362. if pending_options:
  363. for level, optname in pending_options.keys():
  364. self.setsockopt(level, optname, pending_options[ (level, optname) ])
  365. def bind(self, jsockaddr, reuse_addr):
  366. self.jsocket.setReuseAddress(reuse_addr)
  367. self.jsocket.bind(jsockaddr)
  368. def connect(self, jsockaddr):
  369. if self.mode == MODE_TIMEOUT:
  370. self.jsocket.connect (jsockaddr, self._timeout_millis)
  371. else:
  372. self.jchannel.connect(jsockaddr)
  373. def finish_connect(self):
  374. return self.jchannel.finishConnect()
  375. def _do_read_net(self, buf):
  376. # Need two separate implementations because the java.nio APIs do not support timeouts
  377. return self.jsocket.getInputStream().read(buf)
  378. def _do_read_nio(self, buf):
  379. bytebuf = java.nio.ByteBuffer.wrap(buf)
  380. count = self.jchannel.read(bytebuf)
  381. return count
  382. def _do_write_net(self, buf):
  383. self.jsocket.getOutputStream().write(buf)
  384. return len(buf)
  385. def _do_write_nio(self, buf):
  386. bytebuf = java.nio.ByteBuffer.wrap(buf)
  387. count = self.jchannel.write(bytebuf)
  388. return count
  389. def read(self, buf):
  390. if self.mode == MODE_TIMEOUT:
  391. return self._do_read_net(buf)
  392. else:
  393. return self._do_read_nio(buf)
  394. def write(self, buf):
  395. if self.mode == MODE_TIMEOUT:
  396. return self._do_write_net(buf)
  397. else:
  398. return self._do_write_nio(buf)
  399. def shutdown(self, how):
  400. if how in (SHUT_RD, SHUT_RDWR):
  401. self.jsocket.shutdownInput()
  402. if how in (SHUT_WR, SHUT_RDWR):
  403. self.jsocket.shutdownOutput()
  404. def getsockname(self):
  405. return (self.jsocket.getLocalAddress().getHostAddress(), self.jsocket.getLocalPort())
  406. def getpeername(self):
  407. return (self.jsocket.getInetAddress().getHostAddress(), self.jsocket.getPort() )
  408. class _server_socket_impl(_nio_impl):
  409. options = {
  410. (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize',
  411. (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress',
  412. (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout',
  413. }
  414. def __init__(self, jsockaddr, backlog, reuse_addr):
  415. self.pending_client_options = {}
  416. self.jchannel = java.nio.channels.ServerSocketChannel.open()
  417. self.jsocket = self.jchannel.socket()
  418. self.jsocket.setReuseAddress(reuse_addr)
  419. self.jsocket.bind(jsockaddr, backlog)
  420. self.socketio = org.python.core.io.ServerSocketIO(self.jchannel, 'rw')
  421. def accept(self):
  422. if self.mode in (MODE_BLOCKING, MODE_NONBLOCKING):
  423. new_cli_chan = self.jchannel.accept()
  424. if new_cli_chan is not None:
  425. return _client_socket_impl(new_cli_chan.socket(), self.pending_client_options)
  426. else:
  427. return None
  428. else:
  429. # In timeout mode now
  430. new_cli_sock = self.jsocket.accept()
  431. return _client_socket_impl(new_cli_sock, self.pending_client_options)
  432. def shutdown(self, how):
  433. # This is no-op on java, for server sockets.
  434. # What the user wants to achieve is achieved by calling close() on
  435. # java/jython. But we can't call that here because that would then
  436. # later cause the user explicit close() call to fail
  437. pass
  438. def getsockopt(self, level, option):
  439. if self.options.has_key( (level, option) ):
  440. return _nio_impl.getsockopt(self, level, option)
  441. elif _client_socket_impl.options.has_key( (level, option) ):
  442. return self.pending_client_options.get( (level, option), None)
  443. else:
  444. raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % \
  445. (_constant_to_name(option, ['SO_', 'TCP_']), _constant_to_name(level, ['SOL_', 'IPPROTO_']), str(self.jsocket)))
  446. def setsockopt(self, level, option, value):
  447. if self.options.has_key( (level, option) ):
  448. _nio_impl.setsockopt(self, level, option, value)
  449. elif _client_socket_impl.options.has_key( (level, option) ):
  450. self.pending_client_options[ (level, option) ] = value
  451. else:
  452. raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % \
  453. (_constant_to_name(option, ['SO_', 'TCP_']), _constant_to_name(level, ['SOL_', 'IPPROTO_']), str(self.jsocket)))
  454. def getsockname(self):
  455. return (self.jsocket.getInetAddress().getHostAddress(), self.jsocket.getLocalPort())
  456. def getpeername(self):
  457. # Not a meaningful operation for server sockets.
  458. raise error(errno.ENOTCONN, "Socket is not connected")
  459. class _datagram_socket_impl(_nio_impl):
  460. options = {
  461. (SOL_SOCKET, SO_BROADCAST): 'Broadcast',
  462. (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize',
  463. (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress',
  464. (SOL_SOCKET, SO_SNDBUF): 'SendBufferSize',
  465. (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout',
  466. }
  467. def __init__(self, jsockaddr=None, reuse_addr=0):
  468. self.jchannel = java.nio.channels.DatagramChannel.open()
  469. self.jsocket = self.jchannel.socket()
  470. if jsockaddr is not None:
  471. self.jsocket.setReuseAddress(reuse_addr)
  472. self.jsocket.bind(jsockaddr)
  473. self.socketio = org.python.core.io.DatagramSocketIO(self.jchannel, 'rw')
  474. def connect(self, jsockaddr):
  475. self.jchannel.connect(jsockaddr)
  476. def disconnect(self):
  477. """
  478. Disconnect the datagram socket.
  479. cpython appears not to have this operation
  480. """
  481. self.jchannel.disconnect()
  482. def shutdown(self, how):
  483. # This is no-op on java, for datagram sockets.
  484. # What the user wants to achieve is achieved by calling close() on
  485. # java/jython. But we can't call that here because that would then
  486. # later cause the user explicit close() call to fail
  487. pass
  488. def _do_send_net(self, byte_array, socket_address, flags):
  489. # Need two separate implementations because the java.nio APIs do not support timeouts
  490. num_bytes = len(byte_array)
  491. if self.jsocket.isConnected() and socket_address is None:
  492. packet = java.net.DatagramPacket(byte_array, num_bytes)
  493. else:
  494. packet = java.net.DatagramPacket(byte_array, num_bytes, socket_address)
  495. self.jsocket.send(packet)
  496. return num_bytes
  497. def _do_send_nio(self, byte_array, socket_address, flags):
  498. byte_buf = java.nio.ByteBuffer.wrap(byte_array)
  499. if self.jchannel.isConnected() and socket_address is None:
  500. bytes_sent = self.jchannel.write(byte_buf)
  501. else:
  502. bytes_sent = self.jchannel.send(byte_buf, socket_address)
  503. return bytes_sent
  504. def sendto(self, byte_array, jsockaddr, flags):
  505. if self.mode == MODE_TIMEOUT:
  506. return self._do_send_net(byte_array, jsockaddr, flags)
  507. else:
  508. return self._do_send_nio(byte_array, jsockaddr, flags)
  509. def send(self, byte_array, flags):
  510. if self.mode == MODE_TIMEOUT:
  511. return self._do_send_net(byte_array, None, flags)
  512. else:
  513. return self._do_send_nio(byte_array, None, flags)
  514. def _do_receive_net(self, return_source_address, num_bytes, flags):
  515. byte_array = jarray.zeros(num_bytes, 'b')
  516. packet = java.net.DatagramPacket(byte_array, num_bytes)
  517. self.jsocket.receive(packet)
  518. bytes_rcvd = packet.getLength()
  519. if bytes_rcvd < num_bytes:
  520. byte_array = byte_array[:bytes_rcvd]
  521. return_data = byte_array.tostring()
  522. if return_source_address:
  523. host = None
  524. if packet.getAddress():
  525. host = packet.getAddress().getHostAddress()
  526. port = packet.getPort()
  527. return return_data, (host, port)
  528. else:
  529. return return_data
  530. def _do_receive_nio(self, return_source_address, num_bytes, flags):
  531. byte_array = jarray.zeros(num_bytes, 'b')
  532. byte_buf = java.nio.ByteBuffer.wrap(byte_array)
  533. source_address = self.jchannel.receive(byte_buf)
  534. if source_address is None and not self.jchannel.isBlocking():
  535. raise would_block_error()
  536. byte_buf.flip() ; bytes_read = byte_buf.remaining()
  537. if bytes_read < num_bytes:
  538. byte_array = byte_array[:bytes_read]
  539. return_data = byte_array.tostring()
  540. if return_source_address:
  541. return return_data, (source_address.getAddress().getHostAddress(), source_address.getPort())
  542. else:
  543. return return_data
  544. def recvfrom(self, num_bytes, flags):
  545. if self.mode == MODE_TIMEOUT:
  546. return self._do_receive_net(1, num_bytes, flags)
  547. else:
  548. return self._do_receive_nio(1, num_bytes, flags)
  549. def recv(self, num_bytes, flags):
  550. if self.mode == MODE_TIMEOUT:
  551. return self._do_receive_net(0, num_bytes, flags)
  552. else:
  553. return self._do_receive_nio(0, num_bytes, flags)
  554. def getsockname(self):
  555. return (self.jsocket.getLocalAddress().getHostAddress(), self.jsocket.getLocalPort())
  556. def getpeername(self):
  557. peer_address = self.jsocket.getInetAddress()
  558. if peer_address is None:
  559. raise error(errno.ENOTCONN, "Socket is not connected")
  560. return (peer_address.getHostAddress(), self.jsocket.getPort() )
  561. has_ipv6 = True # IPV6 FTW!
  562. # Name and address functions
  563. def _gethostbyaddr(name):
  564. # This is as close as I can get; at least the types are correct...
  565. addresses = java.net.InetAddress.getAllByName(gethostbyname(name))
  566. names = []
  567. addrs = []
  568. for addr in addresses:
  569. names.append(asPyString(addr.getHostName()))
  570. addrs.append(asPyString(addr.getHostAddress()))
  571. return (names, addrs)
  572. def getfqdn(name=None):
  573. """
  574. Return a fully qualified domain name for name. If name is omitted or empty
  575. it is interpreted as the local host. To find the fully qualified name,
  576. the hostname returned by gethostbyaddr() is checked, then aliases for the
  577. host, if available. The first name which includes a period is selected.
  578. In case no fully qualified domain name is available, the hostname is retur
  579. New in version 2.0.
  580. """
  581. if not name:
  582. name = gethostname()
  583. names, addrs = _gethostbyaddr(name)
  584. for a in names:
  585. if a.find(".") >= 0:
  586. return a
  587. return name
  588. def gethostname():
  589. try:
  590. return asPyString(java.net.InetAddress.getLocalHost().getHostName())
  591. except java.lang.Exception, jlx:
  592. raise _map_exception(jlx)
  593. def gethostbyname(name):
  594. try:
  595. return asPyString(java.net.InetAddress.getByName(name).getHostAddress())
  596. except java.lang.Exception, jlx:
  597. raise _map_exception(jlx)
  598. def gethostbyaddr(name):
  599. names, addrs = _gethostbyaddr(name)
  600. return (names[0], names, addrs)
  601. def getservbyname(service_name, protocol_name=None):
  602. try:
  603. from jnr.netdb import Service
  604. except ImportError:
  605. return None
  606. service = Service.getServiceByName(service_name, protocol_name)
  607. if service is None:
  608. raise error('service/proto not found')
  609. return service.getPort()
  610. def getservbyport(port, protocol_name=None):
  611. try:
  612. from jnr.netdb import Service
  613. except ImportError:
  614. return None
  615. service = Service.getServiceByPort(port, protocol_name)
  616. if service is None:
  617. raise error('port/proto not found')
  618. return service.getName()
  619. def getprotobyname(protocol_name=None):
  620. try:
  621. from jnr.netdb import Protocol
  622. except ImportError:
  623. return None
  624. proto = Protocol.getProtocolByName(protocol_name)
  625. if proto is None:
  626. raise error('protocol not found')
  627. return proto.getProto()
  628. def _realsocket(family = AF_INET, sock_type = SOCK_STREAM, protocol=0):
  629. assert family in (AF_INET, AF_INET6), "Only AF_INET and AF_INET6 sockets are currently supported on jython"
  630. assert sock_type in (SOCK_DGRAM, SOCK_STREAM), "Only SOCK_STREAM and SOCK_DGRAM sockets are currently supported on jython"
  631. if sock_type == SOCK_STREAM:
  632. if protocol != 0:
  633. assert protocol == IPPROTO_TCP, "Only IPPROTO_TCP supported on SOCK_STREAM sockets"
  634. else:
  635. protocol = IPPROTO_TCP
  636. result = _tcpsocket()
  637. else:
  638. if protocol != 0:
  639. assert protocol == IPPROTO_UDP, "Only IPPROTO_UDP supported on SOCK_DGRAM sockets"
  640. else:
  641. protocol = IPPROTO_UDP
  642. result = _udpsocket()
  643. setattr(result, "family", family)
  644. setattr(result, "type", sock_type)
  645. setattr(result, "proto", protocol)
  646. return result
  647. #
  648. # Attempt to provide IDNA (RFC 3490) support.
  649. #
  650. # Try java.net.IDN, built into java 6
  651. #
  652. idna_libraries = [
  653. ('java.net.IDN', 'toASCII', 'toUnicode',
  654. 'ALLOW_UNASSIGNED', 'USE_STD3_ASCII_RULES',
  655. java.lang.IllegalArgumentException)
  656. ]
  657. for idna_lib, efn, dfn, au, usar, exc in idna_libraries:
  658. try:
  659. m = __import__(idna_lib, globals(), locals(), [efn, dfn, au, usar])
  660. encode_fn = getattr(m, efn)
  661. def _encode_idna(name):
  662. try:
  663. return encode_fn(name)
  664. except exc:
  665. raise UnicodeEncodeError(name)
  666. decode_fn = getattr(m, dfn)
  667. def _decode_idna(name, flags=0):
  668. try:
  669. jflags = 0
  670. if flags & NI_IDN_ALLOW_UNASSIGNED:
  671. jflags |= au
  672. if flags & NI_IDN_USE_STD3_ASCII_RULES:
  673. jflags |= usar
  674. return decode_fn(name, jflags)
  675. except Exception, x:
  676. raise UnicodeDecodeError(name)
  677. supports('idna', True)
  678. break
  679. except (AttributeError, ImportError), e:
  680. pass
  681. else:
  682. _encode_idna = lambda x: x.encode("ascii")
  683. _decode_idna = lambda x, y=0: x.decode("ascii")
  684. #
  685. # Define data structures to support IPV4 and IPV6.
  686. #
  687. class _ip_address_t: pass
  688. class _ipv4_address_t(_ip_address_t):
  689. def __init__(self, sockaddr, port, jaddress):
  690. self.sockaddr = sockaddr
  691. self.port = port
  692. self.jaddress = jaddress
  693. def __getitem__(self, index):
  694. if 0 == index:
  695. return self.sockaddr
  696. elif 1 == index:
  697. return self.port
  698. else:
  699. raise IndexError()
  700. def __len__(self):
  701. return 2
  702. def __str__(self):
  703. return "('%s', %d)" % (self.sockaddr, self.port)
  704. __repr__ = __str__
  705. class _ipv6_address_t(_ip_address_t):
  706. def __init__(self, sockaddr, port, jaddress):
  707. self.sockaddr = sockaddr
  708. self.port = port
  709. self.jaddress = jaddress
  710. def __getitem__(self, index):
  711. if 0 == index:
  712. return self.sockaddr
  713. elif 1 == index:
  714. return self.port
  715. elif 2 == index:
  716. return 0
  717. elif 3 == index:
  718. return self.jaddress.scopeId
  719. else:
  720. raise IndexError()
  721. def __len__(self):
  722. return 4
  723. def __str__(self):
  724. return "('%s', %d, 0, %d)" % (self.sockaddr, self.port, self.jaddress.scopeId)
  725. __repr__ = __str__
  726. def _get_jsockaddr(address_object, family, sock_type, proto, flags):
  727. # Is this an object that was returned from getaddrinfo? If so, it already contains an InetAddress
  728. if isinstance(address_object, _ip_address_t):
  729. return java.net.InetSocketAddress(address_object.jaddress, address_object[1])
  730. # The user passed an address tuple, not an object returned from getaddrinfo
  731. # So we must call getaddrinfo, after some translations and checking
  732. if address_object is None:
  733. address_object = ("", 0)
  734. error_message = "Address must be a 2-tuple (ipv4: (host, port)) or a 4-tuple (ipv6: (host, port, flow, scope))"
  735. if not isinstance(address_object, tuple) or \
  736. ((family == AF_INET and len(address_object) != 2) or (family == AF_INET6 and len(address_object) not in [2,4] )) or \
  737. not isinstance(address_object[0], (basestring, types.NoneType)) or \
  738. not isinstance(address_object[1], (int, long)):
  739. raise TypeError(error_message)
  740. if len(address_object) == 4 and not isinstance(address_object[3], (int, long)):
  741. raise TypeError(error_message)
  742. hostname = address_object[0]
  743. if hostname is not None:
  744. hostname = hostname.strip()
  745. port = address_object[1]
  746. if family == AF_INET and sock_type == SOCK_DGRAM and hostname == "<broadcast>":
  747. hostname = INADDR_BROADCAST
  748. if hostname in ["", None]:
  749. if flags & AI_PASSIVE:
  750. hostname = {AF_INET: INADDR_ANY, AF_INET6: IN6ADDR_ANY_INIT}[family]
  751. else:
  752. hostname = "localhost"
  753. if isinstance(hostname, unicode):
  754. hostname = _encode_idna(hostname)
  755. addresses = getaddrinfo(hostname, port, family, sock_type, proto, flags)
  756. if len(addresses) == 0:
  757. raise gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed')
  758. return java.net.InetSocketAddress(addresses[0][4].jaddress, port)
  759. # Workaround for this (predominantly windows) issue
  760. # http://wiki.python.org/jython/NewSocketModule#IPV6_address_support
  761. _ipv4_addresses_only = False
  762. def _use_ipv4_addresses_only(value):
  763. global _ipv4_addresses_only
  764. _ipv4_addresses_only = value
  765. def _getaddrinfo_get_host(host, family, flags):
  766. if not isinstance(host, basestring) and host is not None:
  767. raise TypeError("getaddrinfo() argument 1 must be string or None")
  768. if flags & AI_NUMERICHOST:
  769. if not is_ip_address(host):
  770. raise gaierror(EAI_NONAME, "Name or service not known")
  771. if family == AF_INET and not is_ipv4_address(host):
  772. raise gaierror(EAI_ADDRFAMILY, "Address family for hostname not supported")
  773. if family == AF_INET6 and not is_ipv6_address(host):
  774. raise gaierror(EAI_ADDRFAMILY, "Address family for hostname not supported")
  775. if isinstance(host, unicode):
  776. host = _encode_idna(host)
  777. return host
  778. def _getaddrinfo_get_port(port, flags):
  779. if isinstance(port, basestring):
  780. try:
  781. int_port = int(port)
  782. except ValueError:
  783. if flags & AI_NUMERICSERV:
  784. raise gaierror(EAI_NONAME, "Name or service not known")
  785. # Lookup the service by name
  786. try:
  787. int_port = getservbyname(port)
  788. except error:
  789. raise gaierror(EAI_SERVICE, "Servname not supported for ai_socktype")
  790. elif port is None:
  791. int_port = 0
  792. elif not isinstance(port, (int, long)):
  793. raise error("Int or String expected")
  794. else:
  795. int_port = int(port)
  796. return int_port % 65536
  797. def getaddrinfo(host, port, family=AF_UNSPEC, socktype=0, proto=0, flags=0):
  798. try:
  799. if _ipv4_addresses_only:
  800. family = AF_INET
  801. if not family in [AF_INET, AF_INET6, AF_UNSPEC]:
  802. raise gaierror(errno.EIO, 'ai_family not supported')
  803. host = _getaddrinfo_get_host(host, family, flags)
  804. port = _getaddrinfo_get_port(port, flags)
  805. if socktype not in [0, SOCK_DGRAM, SOCK_STREAM]:
  806. raise error(errno.ESOCKTNOSUPPORT, "Socket type %s is not supported" % _constant_to_name(socktype, ['SOCK_']))
  807. filter_fns = []
  808. filter_fns.append({
  809. AF_INET: lambda x: isinstance(x, java.net.Inet4Address),
  810. AF_INET6: lambda x: isinstance(x, java.net.Inet6Address),
  811. AF_UNSPEC: lambda x: isinstance(x, java.net.InetAddress),
  812. }[family])
  813. if host in [None, ""]:
  814. if flags & AI_PASSIVE:
  815. hosts = {AF_INET: [INADDR_ANY], AF_INET6: [IN6ADDR_ANY_INIT], AF_UNSPEC: [INADDR_ANY, IN6ADDR_ANY_INIT]}[family]
  816. else:
  817. hosts = ["localhost"]
  818. else:
  819. hosts = [host]
  820. results = []
  821. for h in hosts:
  822. for a in java.net.InetAddress.getAllByName(h):
  823. if len([f for f in filter_fns if f(a)]):
  824. family = {java.net.Inet4Address: AF_INET, java.net.Inet6Address: AF_INET6}[a.getClass()]
  825. if flags & AI_CANONNAME:
  826. canonname = asPyString(a.getCanonicalHostName())
  827. else:
  828. canonname = ""
  829. sockaddr = asPyString(a.getHostAddress())
  830. # TODO: Include flowinfo and scopeid in a 4-tuple for IPv6 addresses
  831. sock_tuple = {AF_INET : _ipv4_address_t, AF_INET6 : _ipv6_address_t}[family](sockaddr, port, a)
  832. if socktype == 0:
  833. socktypes = [SOCK_DGRAM, SOCK_STREAM]
  834. else:
  835. socktypes = [socktype]
  836. for result_socktype in socktypes:
  837. result_proto = {SOCK_DGRAM: IPPROTO_UDP, SOCK_STREAM: IPPROTO_TCP}[result_socktype]
  838. if proto in [0, result_proto]:
  839. # The returned socket will only support the result_proto
  840. # If this does not match the requested proto, don't return it
  841. results.append((family, result_socktype, result_proto, canonname, sock_tuple))
  842. return results
  843. except java.lang.Exception, jlx:
  844. raise _map_exception(jlx)
  845. def _getnameinfo_get_host(address, flags):
  846. if not isinstance(address, basestring):
  847. raise TypeError("getnameinfo() address 1 must be string, not None")
  848. if isinstance(address, unicode):
  849. address = _encode_idna(address)
  850. jia = java.net.InetAddress.getByName(address)
  851. result = jia.getCanonicalHostName()
  852. if flags & NI_NAMEREQD:
  853. if is_ip_address(result):
  854. raise gaierror(EAI_NONAME, "Name or service not known")
  855. elif flags & NI_NUMERICHOST:
  856. result = jia.getHostAddress()
  857. # Ignoring NI_NOFQDN for now
  858. if flags & NI_IDN:
  859. result = _decode_idna(result, flags)
  860. return result
  861. def _getnameinfo_get_port(port, flags):
  862. if not isinstance(port, (int, long)):
  863. raise TypeError("getnameinfo() port number must be an integer")
  864. if flags & NI_NUMERICSERV:
  865. return port
  866. proto = None
  867. if flags & NI_DGRAM:
  868. proto = "udp"
  869. return getservbyport(port, proto)
  870. def getnameinfo(sock_addr, flags):
  871. if not isinstance(sock_addr, tuple) or len(sock_addr) < 2:
  872. raise TypeError("getnameinfo() argument 1 must be a tuple")
  873. host = _getnameinfo_get_host(sock_addr[0], flags)
  874. port = _getnameinfo_get_port(sock_addr[1], flags)
  875. return (host, port)
  876. def getdefaulttimeout():
  877. return _defaulttimeout
  878. def _calctimeoutvalue(value):
  879. if value is None:
  880. return None
  881. try:
  882. floatvalue = float(value)
  883. except:
  884. raise TypeError('Socket timeout value must be a number or None')
  885. if floatvalue < 0.0:
  886. raise ValueError("Socket timeout value cannot be negative")
  887. if floatvalue < 0.000001:
  888. return 0.0
  889. return floatvalue
  890. def setdefaulttimeout(timeout):
  891. global _defaulttimeout
  892. try:
  893. _defaulttimeout = _calctimeoutvalue(timeout)
  894. finally:
  895. _nonblocking_api_mixin.timeout = _defaulttimeout
  896. def htons(x): return x
  897. def htonl(x): return x
  898. def ntohs(x): return x
  899. def ntohl(x): return x
  900. def inet_pton(family, ip_string):
  901. try:
  902. if family == AF_INET:
  903. if not is_ipv4_address(ip_string):
  904. raise error("illegal IP address string passed to inet_pton")
  905. elif family == AF_INET6:
  906. if not is_ipv6_address(ip_string):
  907. raise error("illegal IP address string passed to inet_pton")
  908. else:
  909. raise error(errno.EAFNOSUPPORT, "Address family not supported by protocol")
  910. ia = java.net.InetAddress.getByName(ip_string)
  911. bytes = []
  912. for byte in ia.getAddress():
  913. if byte < 0:
  914. bytes.append(byte+256)
  915. else:
  916. bytes.append(byte)
  917. return "".join([chr(byte) for byte in bytes])
  918. except java.lang.Exception, jlx:
  919. raise _map_exception(jlx)
  920. def inet_ntop(family, packed_ip):
  921. try:
  922. jByteArray = jarray.array(packed_ip, 'b')
  923. if family == AF_INET:
  924. if len(jByteArray) != 4:
  925. raise ValueError("invalid length of packed IP address string")
  926. elif family == AF_INET6:
  927. if len(jByteArray) != 16:
  928. raise ValueError("invalid length of packed IP address string")
  929. else:
  930. raise ValueError("unknown address family %s" % family)
  931. ia = java.net.InetAddress.getByAddress(jByteArray)
  932. return ia.getHostAddress()
  933. except java.lang.Exception, jlx:
  934. raise _map_exception(jlx)
  935. def inet_aton(ip_string):
  936. return inet_pton(AF_INET, ip_string)
  937. def inet_ntoa(packed_ip):
  938. return inet_ntop(AF_INET, packed_ip)
  939. from functools import wraps
  940. def raises_error(method):
  941. @wraps(method)
  942. def set_last_error(obj, *args, **kwargs):
  943. try:
  944. setattr(obj, '_last_error', 0)
  945. return method(obj, *args, **kwargs)
  946. except error, e:
  947. setattr(obj, '_last_error', e[0])
  948. raise
  949. return set_last_error
  950. class _nonblocking_api_mixin:
  951. mode = MODE_BLOCKING
  952. reference_count = 0
  953. close_lock = threading.Lock()
  954. def __init__(self):
  955. self.timeout = _defaulttimeout
  956. if self.timeout is not None:
  957. self.mode = MODE_TIMEOUT
  958. self.pending_options = {
  959. (SOL_SOCKET, SO_REUSEADDR): 0,
  960. }
  961. def gettimeout(self):
  962. return self.timeout
  963. def settimeout(self, timeout):
  964. self.timeout = _calctimeoutvalue(timeout)
  965. if self.timeout is None:
  966. self.mode = MODE_BLOCKING
  967. elif self.timeout < 0.000001:
  968. self.mode = MODE_NONBLOCKING
  969. else:
  970. self.mode = MODE_TIMEOUT
  971. self._config()
  972. def setblocking(self, flag):
  973. if flag:
  974. self.mode = MODE_BLOCKING
  975. self.timeout = None
  976. else:
  977. self.mode = MODE_NONBLOCKING
  978. self.timeout = 0.0
  979. self._config()
  980. def getblocking(self):
  981. return self.mode == MODE_BLOCKING
  982. @raises_error
  983. def setsockopt(self, level, optname, value):
  984. try:
  985. if self.sock_impl:
  986. self.sock_impl.setsockopt(level, optname, value)
  987. else:
  988. self.pending_options[ (level, optname) ] = value
  989. except java.lang.Exception, jlx:
  990. raise _map_exception(jlx)
  991. def getsockopt(self, level, optname):
  992. # Handle "pseudo" options first
  993. if level == SOL_SOCKET and optname == SO_TYPE:
  994. return getattr(self, "type")
  995. if level == SOL_SOCKET and optname == SO_ERROR:
  996. return_value = self._last_error
  997. self._last_error = 0
  998. return return_value
  999. # Now handle "real" options
  1000. try:
  1001. if self.sock_impl:
  1002. return self.sock_impl.getsockopt(level, optname)
  1003. else:
  1004. return self.pending_options.get( (level, optname), None)
  1005. except java.lang.Exception, jlx:
  1006. raise _map_exception(jlx)
  1007. @raises_error
  1008. def shutdown(self, how):
  1009. assert how in (SHUT_RD, SHUT_WR, SHUT_RDWR)
  1010. if not self.sock_impl:
  1011. raise error(errno.ENOTCONN, "Transport endpoint is not connected")
  1012. try:
  1013. self.sock_impl.shutdown(how)
  1014. except java.lang.Exception, jlx:
  1015. raise _map_exception(jlx)
  1016. @raises_error
  1017. def close(self):
  1018. try:
  1019. if self.sock_impl:
  1020. self.sock_impl.close()
  1021. except java.lang.Exception, jlx:
  1022. raise _map_exception(jlx)
  1023. @raises_error
  1024. def getsockname(self):
  1025. try:
  1026. if self.sock_impl is None:
  1027. # If the user has already bound an address, return that
  1028. if self.local_addr:
  1029. return self.local_addr
  1030. # The user has not bound, connected or listened
  1031. # This is what cpython raises in this scenario
  1032. raise error(errno.EINVAL, "Invalid argument")
  1033. return self.sock_impl.getsockname()
  1034. except java.lang.Exception, jlx:
  1035. raise _map_exception(jlx)
  1036. @raises_error
  1037. def getpeername(self):
  1038. try:
  1039. if self.sock_impl is None:
  1040. raise error(errno.ENOTCONN, "Socket is not connected")
  1041. return self.sock_impl.getpeername()
  1042. except java.lang.Exception, jlx:
  1043. raise _map_exception(jlx)
  1044. def _config(self):
  1045. assert self.mode in _permitted_modes
  1046. if self.sock_impl:
  1047. self.sock_impl.config(self.mode, self.timeout)
  1048. for level, optname in self.pending_options.keys():
  1049. if optname != SO_REUSEADDR:
  1050. self.sock_impl.setsockopt(level, optname, self.pending_options[ (level, optname) ])
  1051. def getchannel(self):
  1052. if not self.sock_impl:
  1053. return None
  1054. return self.sock_impl.getchannel()
  1055. def fileno(self):
  1056. if not self.sock_impl:
  1057. return None
  1058. return self.sock_impl.fileno()
  1059. def _get_jsocket(self):
  1060. return self.sock_impl.jsocket
  1061. class _tcpsocket(_nonblocking_api_mixin):
  1062. sock_impl = None
  1063. istream = None
  1064. ostream = None
  1065. local_addr = None
  1066. server = 0
  1067. _last_error = 0
  1068. def __init__(self):
  1069. _nonblocking_api_mixin.__init__(self)
  1070. def getsockopt(self, level, optname):
  1071. if level == SOL_SOCKET and optname == SO_ACCEPTCONN:
  1072. return self.server
  1073. return _nonblocking_api_mixin.getsockopt(self, level, optname)
  1074. @raises_error
  1075. def bind(self, addr):
  1076. assert not self.sock_impl
  1077. assert not self.local_addr
  1078. # Do the address format check
  1079. _get_jsockaddr(addr, self.family, self.type, self.proto, AI_PASSIVE)
  1080. self.local_addr = addr
  1081. @raises_error
  1082. def listen(self, backlog):
  1083. "This signifies a server socket"
  1084. try:
  1085. assert not self.sock_impl
  1086. self.server = 1
  1087. self.sock_impl = _server_socket_impl(_get_jsockaddr(self.local_addr, self.family, self.type, self.proto, AI_PASSIVE),
  1088. backlog, self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ])
  1089. self._config()
  1090. except java.lang.Exception, jlx:
  1091. raise _map_exception(jlx)
  1092. @raises_error
  1093. def accept(self):
  1094. "This signifies a server socket"
  1095. try:
  1096. if not self.sock_impl:
  1097. self.listen()
  1098. assert self.server
  1099. new_sock = self.sock_impl.accept()
  1100. if not new_sock:
  1101. raise would_block_error()
  1102. cliconn = _tcpsocket()
  1103. cliconn.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ] = new_sock.jsocket.getReuseAddress()
  1104. cliconn.sock_impl = new_sock
  1105. cliconn._setup()
  1106. return cliconn, new_sock.getpeername()
  1107. except java.lang.Exception, jlx:
  1108. raise _map_exception(jlx)
  1109. @raises_error
  1110. def _do_connect(self, addr):
  1111. try:
  1112. assert not self.sock_impl
  1113. self.sock_impl = _client_socket_impl()
  1114. if self.local_addr: # Has the socket been bound to a local address?
  1115. self.sock_impl.bind(_get_jsockaddr(self.local_addr, self.family, self.type, self.proto, 0),
  1116. self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ])
  1117. self._config() # Configure timeouts, etc, now that the socket exists
  1118. self.sock_impl.connect(_get_jsockaddr(addr, self.family, self.type, self.proto, 0))
  1119. except java.lang.Exception, jlx:
  1120. raise _map_exception(jlx)
  1121. def connect(self, addr):
  1122. "This signifies a client socket"
  1123. self._do_connect(addr)
  1124. self._setup()
  1125. def connect_ex(self, addr):
  1126. "This signifies a client socket"
  1127. if not self.sock_impl:
  1128. self._do_connect(addr)
  1129. if self.sock_impl.finish_connect():
  1130. self._setup()
  1131. if self.mode == MODE_NONBLOCKING:
  1132. return errno.EISCONN
  1133. return 0
  1134. return errno.EINPROGRESS
  1135. def _setup(self):
  1136. if self.mode != MODE_NONBLOCKING:
  1137. self.istream = self.sock_impl.jsocket.getInputStream()
  1138. self.ostream = self.sock_impl.jsocket.getOutputStream()
  1139. @raises_error
  1140. def recv(self, n):
  1141. try:
  1142. if not self.sock_impl: raise error(errno.ENOTCONN, 'Socket is not connected')
  1143. if self.sock_impl.jchannel.isConnectionPending():
  1144. self.sock_impl.jchannel.finishConnect()
  1145. data = jarray.zeros(n, 'b')
  1146. m = self.sock_impl.read(data)
  1147. if m == -1:#indicates EOF has been reached, so we just return the empty string
  1148. return ""
  1149. elif m <= 0:
  1150. if self.mode == MODE_NONBLOCKING:
  1151. raise would_block_error()
  1152. return ""
  1153. if m < n:
  1154. data = data[:m]
  1155. return data.tostring()
  1156. except java.lang.Exception, jlx:
  1157. raise _map_exception(jlx)
  1158. def recvfrom(self, n):
  1159. return self.recv(n), None
  1160. @raises_error
  1161. def send(self, s):
  1162. try:
  1163. if not self.sock_impl: raise error(errno.ENOTCONN, 'Socket is not connected')
  1164. if self.sock_impl.jchannel.isConnectionPending():
  1165. self.sock_impl.jchannel.finishConnect()
  1166. numwritten = self.sock_impl.write(s)
  1167. if numwritten == 0 and self.mode == MODE_NONBLOCKING:
  1168. raise would_block_error()
  1169. return numwritten
  1170. except java.lang.Exception, jlx:
  1171. raise _map_exception(jlx)
  1172. sendall = send
  1173. @raises_error
  1174. def close(self):
  1175. try:
  1176. if self.istream:
  1177. self.istream.close()
  1178. if self.ostream:
  1179. self.ostream.close()
  1180. if self.sock_impl:
  1181. self.sock_impl.close()
  1182. except java.lang.Exception, jlx:
  1183. raise _map_exception(jlx)
  1184. class _udpsocket(_nonblocking_api_mixin):
  1185. sock_impl = None
  1186. connected = False
  1187. local_addr = None
  1188. _last_error = 0
  1189. def __init__(self):
  1190. _nonblock

Large files files are truncated, but you can click here to view the full file