def recvfrom_into(self, buffer, nbytes=None, flags=0): if not self.act_non_blocking: trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) return super(GreenSSLSocket, self).recvfrom_into(buffer, nbytes, flags)
def _socket_connect(self, addr): real_connect = socket.connect if self.act_non_blocking: return real_connect(self, addr) else: # *NOTE: gross, copied code from greenio because it's not factored # well enough to reuse if self.gettimeout() is None: while True: try: return real_connect(self, addr) except orig_socket.error as e: if e.args[0] in CONNECT_ERR: trampoline(self, write=True) elif e.args[0] in CONNECT_SUCCESS: return else: raise else: end = time.time() + self.gettimeout() while True: try: real_connect(self, addr) except orig_socket.error as e: if e.args[0] in CONNECT_ERR: trampoline(self, write=True, timeout=end - time.time(), timeout_exc=SSLError('timed out')) elif e.args[0] in CONNECT_SUCCESS: return else: raise if time.time() >= end: raise SSLError('timed out')
def send (self, data, flags=0): if self._sslobj: return self._call_trampolining( super(GreenSSLSocket, self).send, data, flags) else: trampoline(self, write=True, timeout_exc=SSLError('timed out')) return socket.send(self, data, flags)
def send(self, data, flags=0): if self._sslobj: return self._call_trampolining( super(GreenSSLSocket, self).send, data, flags) else: trampoline(self, write=True, timeout_exc=SSLError('timed out')) return socket.send(self, data, flags)
def accept(self): """Accepts a new connection from a remote client, and returns a tuple containing that new connection wrapped with a server-side SSL channel, and the address of the remote client.""" # RDW grr duplication of code from greenio if self.act_non_blocking: newsock, addr = socket.accept(self) else: while True: try: newsock, addr = socket.accept(self) set_nonblocking(newsock) break except orig_socket.error as e: if e.args[0] not in BLOCKING_ERR: raise trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) new_ssl = type(self)( newsock, keyfile=self.keyfile, certfile=self.certfile, server_side=True, cert_reqs=self.cert_reqs, ssl_version=self.ssl_version, ca_certs=self.ca_certs, do_handshake_on_connect=self.do_handshake_on_connect, suppress_ragged_eofs=self.suppress_ragged_eofs) return (new_ssl, addr)
def recv_into(self, *args): if not self.act_non_blocking: trampoline(self.fd, read=True, timeout=self.gettimeout(), timeout_exc=socket.timeout) return self.fd.recv_into(*args)
def recv(self, buflen): if self.act_non_blocking: return self.fd.recv(buflen) buf = self.recvbuffer if buf: chunk, self.recvbuffer = buf[:buflen], buf[buflen:] return chunk fd = self.fd _bytes = recv_func(fd, buflen) if self.gettimeout(): end = time.time() + self.gettimeout() else: end = None timeout = None while _bytes is None: try: if end: timeout = end - time.time() trampoline(fd, read=True, timeout=timeout, timeout_exc=socket.timeout) except socket.timeout: raise except socket.error as e: if e[0] == errno.EPIPE: _bytes = b'' else: raise else: _bytes = recv_func(fd, buflen) self.recvcount += len(_bytes) return _bytes
def recvfrom(self, addr, buflen=1024, flags=0): if not self.act_non_blocking: trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) return super(GreenSSLSocket, self).recvfrom(addr, buflen, flags)
def sendto (self, data, addr, flags=0): # *NOTE: gross, copied code from ssl.py becase it's not factored well enough to be used as-is if self._sslobj: raise ValueError("sendto not allowed on instances of %s" % self.__class__) else: trampoline(self, write=True, timeout_exc=SSLError('timed out')) return socket.sendto(self, data, addr, flags)
def sendto(self, data, addr, flags=0): # *NOTE: gross, copied code from ssl.py becase it's not factored well enough to be used as-is if self._sslobj: raise ValueError("sendto not allowed on instances of %s" % self.__class__) else: trampoline(self, write=True, timeout_exc=SSLError('timed out')) return socket.sendto(self, data, addr, flags)
def send(self, data, flags=0): if not isinstance(data, bytes): data = data.encode() if self._sslobj: return self._call_trampolining( super(GreenSSLSocket, self).send, data, flags) else: trampoline(self, write=True, timeout_exc=SSLError('timed out')) return socket.send(self, data, flags)
def new_read(fd, *args, **kw): from eventlib import api try: api.trampoline(fd, read=True) except socket.error, e: if e[0] == errno.EPIPE: return '' else: raise
def connect_ex(self, address): if self.act_non_blocking: return self.fd.connect_ex(address) fd = self.fd if self.gettimeout() is None: while not socket_connect(fd, address): try: trampoline(fd, write=True, timeout_exc=socket.timeout) except socket.error, ex: return ex[0]
def accept(self): if self.act_non_blocking: return self.fd.accept() fd = self.fd while True: res = socket_accept(fd) if res is not None: client, addr = res set_nonblocking(client) return type(self)(client), addr trampoline(fd, read=True, timeout=self.gettimeout(), timeout_exc=socket.timeout)
def go(): client = util.tcp_socket() desc = greenio.GreenSocket(client) desc.connect(('127.0.0.1', bound_port)) try: api.trampoline(desc, read=True, write=True, timeout=0.1) except api.TimeoutError: assert False, "Timed out" server.close() client.close()
def test_001_trampoline_timeout(self): server = api.tcp_listener(('0.0.0.0', 0)) bound_port = server.getsockname()[1] try: desc = greenio.GreenSocket(util.tcp_socket()) desc.connect(('127.0.0.1', bound_port)) api.trampoline(desc, read=True, write=False, timeout=0.1) except api.TimeoutError: pass # test passed else: assert False, "Didn't timeout" check_hub()
def connect(self, address): if self.act_non_blocking: return self.fd.connect(address) fd = self.fd if self.gettimeout() is None: while not socket_connect(fd, address): trampoline(fd, write=True, timeout_exc=socket.timeout) else: end = time.time() + self.gettimeout() while True: if socket_connect(fd, address): return if time.time() >= end: raise socket.timeout trampoline(fd, write=True, timeout=end-time.time(), timeout_exc=socket.timeout)
def sendall(self, data, flags=0): # *NOTE: gross, copied code from ssl.py becase it's not factored well enough to be used as-is if self._sslobj: if flags != 0: raise ValueError( "non-zero flags not allowed in calls to sendall() on %s" % self.__class__) amount = len(data) count = 0 while (count < amount): v = self.send(data[count:]) count += v return amount else: trampoline(self, write=True, timeout_exc=SSLError('timed out')) return socket.sendall(self, data, flags)
def sendall (self, data, flags=0): # *NOTE: gross, copied code from ssl.py becase it's not factored well enough to be used as-is if self._sslobj: if flags != 0: raise ValueError( "non-zero flags not allowed in calls to sendall() on %s" % self.__class__) amount = len(data) count = 0 while (count < amount): v = self.send(data[count:]) count += v return amount else: trampoline(self, write=True, timeout_exc=SSLError('timed out')) return socket.sendall(self, data, flags)
def accept(self): """Accepts a new connection from a remote client, and returns a tuple containing that new connection wrapped with a server-side SSL channel, and the address of the remote client.""" # RDW grr duplication of code from greenio if self.act_non_blocking: newsock, addr = socket.accept(self) else: while True: try: newsock, addr = socket.accept(self) set_nonblocking(newsock) break except orig_socket.error, e: if e.args[0] not in BLOCKING_ERR: raise trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out'))
def _socket_connect(self, addr): real_connect = socket.connect if self.act_non_blocking: return real_connect(self, addr) else: # *NOTE: gross, copied code from greenio because it's not factored # well enough to reuse if self.gettimeout() is None: while True: try: return real_connect(self, addr) except orig_socket.error, e: if e.args[0] in CONNECT_ERR: trampoline(self, write=True) elif e.args[0] in CONNECT_SUCCESS: return else: raise else:
def _call_trampolining(self, func, *a, **kw): if self.act_non_blocking: return func(*a, **kw) else: while True: try: return func(*a, **kw) except SSLError as e: if e.args[0] == SSL_ERROR_WANT_READ: trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) elif e.args[0] == SSL_ERROR_WANT_WRITE: trampoline(self, write=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) else: raise
def _call_trampolining(self, func, *a, **kw): if self.act_non_blocking: return func(*a, **kw) else: while True: try: return func(*a, **kw) except SSLError, e: if e.args[0] == SSL_ERROR_WANT_READ: trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) elif e.args[0] == SSL_ERROR_WANT_WRITE: trampoline(self, write=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) else: raise
except orig_socket.error, e: if e.args[0] in CONNECT_ERR: trampoline(self, write=True) elif e.args[0] in CONNECT_SUCCESS: return else: raise else: end = time.time() + self.gettimeout() while True: try: real_connect(self, addr) except orig_socket.error, e: if e.args[0] in CONNECT_ERR: trampoline(self, write=True, timeout=end - time.time(), timeout_exc=SSLError('timed out')) elif e.args[0] in CONNECT_SUCCESS: return else: raise if time.time() >= end: raise SSLError('timed out') def connect(self, addr): """Connects to remote ADDR, and then wraps the connection in an SSL channel.""" # *NOTE: grrrrr copied this code from ssl.py because of the reference # to socket.connect which we don't want to call directly if self._sslobj: raise ValueError("attempt to connect already-connected SSLSocket!")
def new_write(fd, *args, **kw): from eventlib import api api.trampoline(fd, write=True) return __original_write__(fd, *args, **kw)
def sendto(self, *args): trampoline(self.fd, write=True, timeout_exc=socket.timeout) return self.fd.sendto(*args)
def sendall(self, data): fd = self.fd tail = self.send(data) while tail < len(data): trampoline(self.fd, write=True, timeout_exc=socket.timeout) tail += self.send(data[tail:])
return real_connect(self, addr) except orig_socket.error, e: if e.args[0] in CONNECT_ERR: trampoline(self, write=True) elif e.args[0] in CONNECT_SUCCESS: return else: raise else: end = time.time() + self.gettimeout() while True: try: real_connect(self, addr) except orig_socket.error, e: if e.args[0] in CONNECT_ERR: trampoline(self, write=True, timeout=end-time.time(), timeout_exc=SSLError('timed out')) elif e.args[0] in CONNECT_SUCCESS: return else: raise if time.time() >= end: raise SSLError('timed out') def connect(self, addr): """Connects to remote ADDR, and then wraps the connection in an SSL channel.""" # *NOTE: grrrrr copied this code from ssl.py because of the reference # to socket.connect which we don't want to call directly if self._sslobj: raise ValueError("attempt to connect already-connected SSLSocket!") self._socket_connect(addr)
def recvfrom (self, addr, buflen=1024, flags=0): if not self.act_non_blocking: trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) return super(GreenSSLSocket, self).recvfrom(addr, buflen, flags)
if self.gettimeout() is None: while not socket_connect(fd, address): try: trampoline(fd, write=True, timeout_exc=socket.timeout) except socket.error, ex: return ex[0] else: end = time.time() + self.gettimeout() while True: if socket_connect(fd, address): return 0 if time.time() >= end: raise socket.timeout try: trampoline(fd, write=True, timeout=end - time.time(), timeout_exc=socket.timeout) except socket.error, ex: return ex[0] def dup(self, *args, **kw): sock = self.fd.dup(*args, **kw) set_nonblocking(sock) newsock = type(self)(sock) newsock.settimeout(self.timeout) return newsock def fileno(self, *args, **kw): fn = self.fileno = self.fd.fileno return fn(*args, **kw)
def recvfrom_into (self, buffer, nbytes=None, flags=0): if not self.act_non_blocking: trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=SSLError('timed out')) return super(GreenSSLSocket, self).recvfrom_into(buffer, nbytes, flags)