PageRenderTime 63ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/dist/Lib/socket.py

https://github.com/shengd/cs345
Python | 1585 lines | 1416 code | 109 blank | 60 comment | 101 complexity | c2aa1965f9d933933f6ca79ab7efdbe4 MD5 | raw file
Possible License(s): BSD-3-Clause

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

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