_socket2.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. # Copyright (c) 2009-2014 Denis Bilenko and gevent contributors. See LICENSE for details.
  2. """
  3. Python 2 socket module.
  4. """
  5. # Our import magic sadly makes this warning useless
  6. # pylint: disable=undefined-variable
  7. import time
  8. from gevent import _socketcommon
  9. from gevent._util import copy_globals
  10. from gevent._compat import PYPY
  11. copy_globals(_socketcommon, globals(),
  12. names_to_ignore=_socketcommon.__py3_imports__ + _socketcommon.__extensions__,
  13. dunder_names_to_keep=())
  14. __socket__ = _socketcommon.__socket__
  15. __implements__ = _socketcommon._implements
  16. __extensions__ = _socketcommon.__extensions__
  17. __imports__ = [i for i in _socketcommon.__imports__ if i not in _socketcommon.__py3_imports__]
  18. __dns__ = _socketcommon.__dns__
  19. try:
  20. _fileobject = __socket__._fileobject
  21. _socketmethods = __socket__._socketmethods
  22. except AttributeError:
  23. # Allow this module to be imported under Python 3
  24. # for building the docs
  25. _fileobject = object
  26. _socketmethods = ('bind', 'connect', 'connect_ex',
  27. 'fileno', 'listen', 'getpeername',
  28. 'getsockname', 'getsockopt',
  29. 'setsockopt', 'sendall',
  30. 'setblocking', 'settimeout',
  31. 'gettimeout', 'shutdown')
  32. else:
  33. # Python 2 doesn't natively support with statements on _fileobject;
  34. # but it eases our test cases if we can do the same with on both Py3
  35. # and Py2. Implementation copied from Python 3
  36. if not hasattr(_fileobject, '__enter__'):
  37. # we could either patch in place:
  38. #_fileobject.__enter__ = lambda self: self
  39. #_fileobject.__exit__ = lambda self, *args: self.close() if not self.closed else None
  40. # or we could subclass. subclassing has the benefit of not
  41. # changing the behaviour of the stdlib if we're just imported; OTOH,
  42. # under Python 2.6/2.7, test_urllib2net.py asserts that the class IS
  43. # socket._fileobject (sigh), so we have to work around that.
  44. class _fileobject(_fileobject): # pylint:disable=function-redefined
  45. def __enter__(self):
  46. return self
  47. def __exit__(self, *args):
  48. if not self.closed:
  49. self.close()
  50. def _get_memory(data):
  51. try:
  52. mv = memoryview(data)
  53. if mv.shape:
  54. return mv
  55. # No shape, probably working with a ctypes object,
  56. # or something else exotic that supports the buffer interface
  57. return mv.tobytes()
  58. except TypeError:
  59. # fixes "python2.7 array.array doesn't support memoryview used in
  60. # gevent.socket.send" issue
  61. # (http://code.google.com/p/gevent/issues/detail?id=94)
  62. return buffer(data)
  63. class _closedsocket(object):
  64. __slots__ = []
  65. def _dummy(*args, **kwargs): # pylint:disable=no-method-argument,unused-argument
  66. raise error(EBADF, 'Bad file descriptor')
  67. # All _delegate_methods must also be initialized here.
  68. send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
  69. if PYPY:
  70. def _drop(self):
  71. pass
  72. def _reuse(self):
  73. pass
  74. __getattr__ = _dummy
  75. timeout_default = object()
  76. class socket(object):
  77. """
  78. gevent `socket.socket <https://docs.python.org/2/library/socket.html#socket-objects>`_
  79. for Python 2.
  80. This object should have the same API as the standard library socket linked to above. Not all
  81. methods are specifically documented here; when they are they may point out a difference
  82. to be aware of or may document a method the standard library does not.
  83. """
  84. # pylint:disable=too-many-public-methods
  85. def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
  86. if _sock is None:
  87. self._sock = _realsocket(family, type, proto)
  88. self.timeout = _socket.getdefaulttimeout()
  89. else:
  90. if hasattr(_sock, '_sock'):
  91. self._sock = _sock._sock
  92. self.timeout = getattr(_sock, 'timeout', False)
  93. if self.timeout is False:
  94. self.timeout = _socket.getdefaulttimeout()
  95. else:
  96. self._sock = _sock
  97. self.timeout = _socket.getdefaulttimeout()
  98. if PYPY:
  99. self._sock._reuse()
  100. self._sock.setblocking(0)
  101. fileno = self._sock.fileno()
  102. self.hub = get_hub()
  103. io = self.hub.loop.io
  104. self._read_event = io(fileno, 1)
  105. self._write_event = io(fileno, 2)
  106. def __repr__(self):
  107. return '<%s at %s %s>' % (type(self).__name__, hex(id(self)), self._formatinfo())
  108. def __str__(self):
  109. return '<%s %s>' % (type(self).__name__, self._formatinfo())
  110. def _formatinfo(self):
  111. # pylint:disable=broad-except
  112. try:
  113. fileno = self.fileno()
  114. except Exception as ex:
  115. fileno = str(ex)
  116. try:
  117. sockname = self.getsockname()
  118. sockname = '%s:%s' % sockname
  119. except Exception:
  120. sockname = None
  121. try:
  122. peername = self.getpeername()
  123. peername = '%s:%s' % peername
  124. except Exception:
  125. peername = None
  126. result = 'fileno=%s' % fileno
  127. if sockname is not None:
  128. result += ' sock=' + str(sockname)
  129. if peername is not None:
  130. result += ' peer=' + str(peername)
  131. if getattr(self, 'timeout', None) is not None:
  132. result += ' timeout=' + str(self.timeout)
  133. return result
  134. def _get_ref(self):
  135. return self._read_event.ref or self._write_event.ref
  136. def _set_ref(self, value):
  137. self._read_event.ref = value
  138. self._write_event.ref = value
  139. ref = property(_get_ref, _set_ref)
  140. def _wait(self, watcher, timeout_exc=timeout('timed out')):
  141. """Block the current greenlet until *watcher* has pending events.
  142. If *timeout* is non-negative, then *timeout_exc* is raised after *timeout* second has passed.
  143. By default *timeout_exc* is ``socket.timeout('timed out')``.
  144. If :func:`cancel_wait` is called, raise ``socket.error(EBADF, 'File descriptor was closed in another greenlet')``.
  145. """
  146. if watcher.callback is not None:
  147. raise _socketcommon.ConcurrentObjectUseError('This socket is already used by another greenlet: %r' % (watcher.callback, ))
  148. if self.timeout is not None:
  149. timeout = Timeout.start_new(self.timeout, timeout_exc, ref=False)
  150. else:
  151. timeout = None
  152. try:
  153. self.hub.wait(watcher)
  154. finally:
  155. if timeout is not None:
  156. timeout.cancel()
  157. def accept(self):
  158. sock = self._sock
  159. while True:
  160. try:
  161. client_socket, address = sock.accept()
  162. break
  163. except error as ex:
  164. if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
  165. raise
  166. sys.exc_clear()
  167. self._wait(self._read_event)
  168. sockobj = socket(_sock=client_socket)
  169. if PYPY:
  170. client_socket._drop()
  171. return sockobj, address
  172. def close(self, _closedsocket=_closedsocket, cancel_wait_ex=cancel_wait_ex):
  173. # This function should not reference any globals. See Python issue #808164.
  174. self.hub.cancel_wait(self._read_event, cancel_wait_ex)
  175. self.hub.cancel_wait(self._write_event, cancel_wait_ex)
  176. s = self._sock
  177. self._sock = _closedsocket()
  178. if PYPY:
  179. s._drop()
  180. @property
  181. def closed(self):
  182. return isinstance(self._sock, _closedsocket)
  183. def connect(self, address):
  184. if self.timeout == 0.0:
  185. return self._sock.connect(address)
  186. sock = self._sock
  187. if isinstance(address, tuple):
  188. r = getaddrinfo(address[0], address[1], sock.family)
  189. address = r[0][-1]
  190. if self.timeout is not None:
  191. timer = Timeout.start_new(self.timeout, timeout('timed out'))
  192. else:
  193. timer = None
  194. try:
  195. while True:
  196. err = sock.getsockopt(SOL_SOCKET, SO_ERROR)
  197. if err:
  198. raise error(err, strerror(err))
  199. result = sock.connect_ex(address)
  200. if not result or result == EISCONN:
  201. break
  202. elif (result in (EWOULDBLOCK, EINPROGRESS, EALREADY)) or (result == EINVAL and is_windows):
  203. self._wait(self._write_event)
  204. else:
  205. raise error(result, strerror(result))
  206. finally:
  207. if timer is not None:
  208. timer.cancel()
  209. def connect_ex(self, address):
  210. try:
  211. return self.connect(address) or 0
  212. except timeout:
  213. return EAGAIN
  214. except error as ex:
  215. if type(ex) is error: # pylint:disable=unidiomatic-typecheck
  216. return ex.args[0]
  217. else:
  218. raise # gaierror is not silenced by connect_ex
  219. def dup(self):
  220. """dup() -> socket object
  221. Return a new socket object connected to the same system resource.
  222. Note, that the new socket does not inherit the timeout."""
  223. return socket(_sock=self._sock)
  224. def makefile(self, mode='r', bufsize=-1):
  225. # Two things to look out for:
  226. # 1) Closing the original socket object should not close the
  227. # socket (hence creating a new instance)
  228. # 2) The resulting fileobject must keep the timeout in order
  229. # to be compatible with the stdlib's socket.makefile.
  230. # Pass self as _sock to preserve timeout.
  231. fobj = _fileobject(type(self)(_sock=self), mode, bufsize)
  232. if PYPY:
  233. self._sock._drop()
  234. return fobj
  235. def recv(self, *args):
  236. sock = self._sock # keeping the reference so that fd is not closed during waiting
  237. while True:
  238. try:
  239. return sock.recv(*args)
  240. except error as ex:
  241. if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
  242. raise
  243. # QQQ without clearing exc_info test__refcount.test_clean_exit fails
  244. sys.exc_clear()
  245. self._wait(self._read_event)
  246. def recvfrom(self, *args):
  247. sock = self._sock
  248. while True:
  249. try:
  250. return sock.recvfrom(*args)
  251. except error as ex:
  252. if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
  253. raise
  254. sys.exc_clear()
  255. self._wait(self._read_event)
  256. def recvfrom_into(self, *args):
  257. sock = self._sock
  258. while True:
  259. try:
  260. return sock.recvfrom_into(*args)
  261. except error as ex:
  262. if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
  263. raise
  264. sys.exc_clear()
  265. self._wait(self._read_event)
  266. def recv_into(self, *args):
  267. sock = self._sock
  268. while True:
  269. try:
  270. return sock.recv_into(*args)
  271. except error as ex:
  272. if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
  273. raise
  274. sys.exc_clear()
  275. self._wait(self._read_event)
  276. def send(self, data, flags=0, timeout=timeout_default):
  277. sock = self._sock
  278. if timeout is timeout_default:
  279. timeout = self.timeout
  280. try:
  281. return sock.send(data, flags)
  282. except error as ex:
  283. if ex.args[0] != EWOULDBLOCK or timeout == 0.0:
  284. raise
  285. sys.exc_clear()
  286. self._wait(self._write_event)
  287. try:
  288. return sock.send(data, flags)
  289. except error as ex2:
  290. if ex2.args[0] == EWOULDBLOCK:
  291. return 0
  292. raise
  293. def __send_chunk(self, data_memory, flags, timeleft, end):
  294. """
  295. Send the complete contents of ``data_memory`` before returning.
  296. This is the core loop around :meth:`send`.
  297. :param timeleft: Either ``None`` if there is no timeout involved,
  298. or a float indicating the timeout to use.
  299. :param end: Either ``None`` if there is no timeout involved, or
  300. a float giving the absolute end time.
  301. :return: An updated value for ``timeleft`` (or None)
  302. :raises timeout: If ``timeleft`` was given and elapsed while
  303. sending this chunk.
  304. """
  305. data_sent = 0
  306. len_data_memory = len(data_memory)
  307. started_timer = 0
  308. while data_sent < len_data_memory:
  309. chunk = data_memory[data_sent:]
  310. if timeleft is None:
  311. data_sent += self.send(chunk, flags)
  312. elif started_timer and timeleft <= 0:
  313. # Check before sending to guarantee a check
  314. # happens even if each chunk successfully sends its data
  315. # (especially important for SSL sockets since they have large
  316. # buffers). But only do this if we've actually tried to
  317. # send something once to avoid spurious timeouts on non-blocking
  318. # sockets.
  319. raise timeout('timed out')
  320. else:
  321. started_timer = 1
  322. data_sent += self.send(chunk, flags, timeout=timeleft)
  323. timeleft = end - time.time()
  324. return timeleft
  325. def sendall(self, data, flags=0):
  326. if isinstance(data, unicode):
  327. data = data.encode()
  328. # this sendall is also reused by gevent.ssl.SSLSocket subclass,
  329. # so it should not call self._sock methods directly
  330. data_memory = _get_memory(data)
  331. len_data_memory = len(data_memory)
  332. if not len_data_memory:
  333. # Don't send empty data, can cause SSL EOFError.
  334. # See issue 719
  335. return 0
  336. # On PyPy up through 2.6.0, subviews of a memoryview() object
  337. # copy the underlying bytes the first time the builtin
  338. # socket.send() method is called. On a non-blocking socket
  339. # (that thus calls socket.send() many times) with a large
  340. # input, this results in many repeated copies of an ever
  341. # smaller string, depending on the networking buffering. For
  342. # example, if each send() can process 1MB of a 50MB input, and
  343. # we naively pass the entire remaining subview each time, we'd
  344. # copy 49MB, 48MB, 47MB, etc, thus completely killing
  345. # performance. To workaround this problem, we work in
  346. # reasonable, fixed-size chunks. This results in a 10x
  347. # improvement to bench_sendall.py, while having no measurable impact on
  348. # CPython (since it doesn't copy at all the only extra overhead is
  349. # a few python function calls, which is negligible for large inputs).
  350. # See https://bitbucket.org/pypy/pypy/issues/2091/non-blocking-socketsend-slow-gevent
  351. # Too small of a chunk (the socket's buf size is usually too
  352. # small) results in reduced perf due to *too many* calls to send and too many
  353. # small copies. With a buffer of 143K (the default on my system), for
  354. # example, bench_sendall.py yields ~264MB/s, while using 1MB yields
  355. # ~653MB/s (matching CPython). 1MB is arbitrary and might be better
  356. # chosen, say, to match a page size?
  357. chunk_size = max(self.getsockopt(SOL_SOCKET, SO_SNDBUF), 1024 * 1024) # pylint:disable=no-member
  358. data_sent = 0
  359. end = None
  360. timeleft = None
  361. if self.timeout is not None:
  362. timeleft = self.timeout
  363. end = time.time() + timeleft
  364. while data_sent < len_data_memory:
  365. chunk_end = min(data_sent + chunk_size, len_data_memory)
  366. chunk = data_memory[data_sent:chunk_end]
  367. timeleft = self.__send_chunk(chunk, flags, timeleft, end)
  368. data_sent += len(chunk) # Guaranteed it sent the whole thing
  369. def sendto(self, *args):
  370. sock = self._sock
  371. try:
  372. return sock.sendto(*args)
  373. except error as ex:
  374. if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
  375. raise
  376. sys.exc_clear()
  377. self._wait(self._write_event)
  378. try:
  379. return sock.sendto(*args)
  380. except error as ex2:
  381. if ex2.args[0] == EWOULDBLOCK:
  382. return 0
  383. raise
  384. def setblocking(self, flag):
  385. if flag:
  386. self.timeout = None
  387. else:
  388. self.timeout = 0.0
  389. def settimeout(self, howlong):
  390. if howlong is not None:
  391. try:
  392. f = howlong.__float__
  393. except AttributeError:
  394. raise TypeError('a float is required')
  395. howlong = f()
  396. if howlong < 0.0:
  397. raise ValueError('Timeout value out of range')
  398. self.__dict__['timeout'] = howlong # avoid recursion with any property on self.timeout
  399. def gettimeout(self):
  400. return self.__dict__['timeout'] # avoid recursion with any property on self.timeout
  401. def shutdown(self, how):
  402. if how == 0: # SHUT_RD
  403. self.hub.cancel_wait(self._read_event, cancel_wait_ex)
  404. elif how == 1: # SHUT_WR
  405. self.hub.cancel_wait(self._write_event, cancel_wait_ex)
  406. else:
  407. self.hub.cancel_wait(self._read_event, cancel_wait_ex)
  408. self.hub.cancel_wait(self._write_event, cancel_wait_ex)
  409. self._sock.shutdown(how)
  410. family = property(lambda self: self._sock.family)
  411. type = property(lambda self: self._sock.type)
  412. proto = property(lambda self: self._sock.proto)
  413. def fileno(self):
  414. return self._sock.fileno()
  415. def getsockname(self):
  416. return self._sock.getsockname()
  417. def getpeername(self):
  418. return self._sock.getpeername()
  419. # delegate the functions that we haven't implemented to the real socket object
  420. _s = "def %s(self, *args): return self._sock.%s(*args)\n\n"
  421. _m = None
  422. for _m in set(_socketmethods) - set(locals()):
  423. exec(_s % (_m, _m,))
  424. del _m, _s
  425. if PYPY:
  426. def _reuse(self):
  427. self._sock._reuse()
  428. def _drop(self):
  429. self._sock._drop()
  430. SocketType = socket
  431. if hasattr(_socket, 'socketpair'):
  432. def socketpair(family=getattr(_socket, 'AF_UNIX', _socket.AF_INET),
  433. type=_socket.SOCK_STREAM, proto=0):
  434. one, two = _socket.socketpair(family, type, proto)
  435. result = socket(_sock=one), socket(_sock=two)
  436. if PYPY:
  437. one._drop()
  438. two._drop()
  439. return result
  440. elif 'socketpair' in __implements__:
  441. __implements__.remove('socketpair')
  442. if hasattr(_socket, 'fromfd'):
  443. def fromfd(fd, family, type, proto=0):
  444. s = _socket.fromfd(fd, family, type, proto)
  445. result = socket(_sock=s)
  446. if PYPY:
  447. s._drop()
  448. return result
  449. elif 'fromfd' in __implements__:
  450. __implements__.remove('fromfd')
  451. if hasattr(__socket__, 'ssl'):
  452. def ssl(sock, keyfile=None, certfile=None):
  453. # deprecated in 2.7.9 but still present;
  454. # sometimes backported by distros. See ssl.py
  455. # Note that we import gevent.ssl, not _ssl2, to get the correct
  456. # version.
  457. from gevent import ssl as _sslmod
  458. # wrap_socket is 2.7.9/backport, sslwrap_simple is older. They take
  459. # the same arguments.
  460. wrap = getattr(_sslmod, 'wrap_socket', None) or getattr(_sslmod, 'sslwrap_simple')
  461. return wrap(sock, keyfile, certfile)
  462. __implements__.append('ssl')
  463. __all__ = __implements__ + __extensions__ + __imports__