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 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 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 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 set_npn_protocols(self, npn_protocols): protos = bytearray() for protocol in npn_protocols: b = bytes(protocol, 'ascii') if len(b) == 0 or len(b) > 255: raise SSLError('NPN protocols must be 1 to 255 in length') protos.append(len(b)) protos.extend(b) self._set_npn_protocols(protos)
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 set_alpn_protocols(self, alpn_protocols): protos = bytearray() for protocol in alpn_protocols: b = bytes(protocol, "ascii") if len(b) == 0 or len(b) > 255: raise SSLError("ALPN protocols must be 1 to 255 in length") protos.append(len(b)) protos.extend(b) self._set_alpn_protocols(protos)
def set_alpn_protocols(self, alpn_protocols): protos = bytearray() for protocol in alpn_protocols: b = protocol.encode('ascii') if len(b) == 0 or len(b) > 255: raise SSLError('ALPN protocols must be 1 to 255 in length') protos.append(len(b)) protos.extend(b) self._set_alpn_protocols(protos)
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 set_npn_protocols(self, npn_protocols): warnings.warn("ssl NPN is deprecated, use ALPN instead", DeprecationWarning, stacklevel=2) protos = bytearray() for protocol in npn_protocols: b = bytes(protocol, 'ascii') if len(b) == 0 or len(b) > 255: raise SSLError('NPN protocols must be 1 to 255 in length') protos.append(len(b)) protos.extend(b) self._set_npn_protocols(protos)
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)