def sendall(self, data): if self.closed: raise socket.error(errno.EBADF, 'Closed socket') if self.fail: raise socket.error(errno.EPIPE, 'Peer closed connection') self.output += data delay()
def bind(self, *pos, **kw): """ Implements proxy connection for UDP sockets, which happens during the bind() phase. """ proxy_type, proxy_addr, proxy_port, rdns, username, password = self.proxy if not proxy_type or self.type != socket.SOCK_DGRAM: return _orig_socket.bind(self, *pos, **kw) if self._proxyconn: raise socket.error(EINVAL, "Socket already bound to an address") if proxy_type != SOCKS5: msg = "UDP only supported by SOCKS5 proxy type" raise socket.error(EOPNOTSUPP, msg) _BaseSocket.bind(self, *pos, **kw) # Need to specify actual local port because # some relays drop packets if a port of zero is specified. # Avoid specifying host address in case of NAT though. _, port = self.getsockname() dst = ("0", port) self._proxyconn = _orig_socket() proxy = self._proxy_addr() self._proxyconn.connect(proxy) UDP_ASSOCIATE = b"\x03" _, relay = self._SOCKS5_request(self._proxyconn, UDP_ASSOCIATE, dst) # The relay is most likely on the same host as the SOCKS proxy, # but some proxies return a private IP address (10.x.y.z) host, _ = proxy _, port = relay _BaseSocket.connect(self, (host, port)) self.proxy_sockname = ("0.0.0.0", 0) # Unknown
def read_response(self): if not self._reader: raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR) # _next_response might be cached from a can_read() call if self._next_response is not False: response = self._next_response self._next_response = False return response response = self._reader.gets() socket_read_size = self.socket_read_size while response is False: try: if HIREDIS_USE_BYTE_BUFFER: bufflen = self._sock.recv_into(self._buffer) if bufflen == 0: raise socket.error(SERVER_CLOSED_CONNECTION_ERROR) else: buffer = self._sock.recv(socket_read_size) # an empty string indicates the server shutdown the socket if not isinstance(buffer, bytes) or len(buffer) == 0: raise socket.error(SERVER_CLOSED_CONNECTION_ERROR) except socket.timeout: raise TimeoutError("Timeout reading from socket") except socket.error: e = sys.exc_info()[1] raise ConnectionError("Error while reading from socket: %s" % (e.args,)) if HIREDIS_USE_BYTE_BUFFER: self._reader.feed(self._buffer, 0, bufflen) else: self._reader.feed(buffer) response = self._reader.gets() # if an older version of hiredis is installed, we need to attempt # to convert ResponseErrors to their appropriate types. if not HIREDIS_SUPPORTS_CALLABLE_ERRORS: if isinstance(response, ResponseError): response = self.parse_error(response.args[0]) elif isinstance(response, list) and response and \ isinstance(response[0], ResponseError): response[0] = self.parse_error(response[0].args[0]) # if the response is a ConnectionError or the response is a list and # the first item is a ConnectionError, raise it as something bad # happened if isinstance(response, ConnectionError): raise response elif isinstance(response, list) and response and \ isinstance(response[0], ConnectionError): raise response[0] return response
def read_response(self): if not self._reader: raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR) # _next_response might be cached from a can_read() call if self._next_response is not False: response = self._next_response self._next_response = False return response response = self._reader.gets() socket_read_size = self.socket_read_size while response is False: try: if HIREDIS_USE_BYTE_BUFFER: bufflen = self._sock.recv_into(self._buffer) if bufflen == 0: raise socket.error(SERVER_CLOSED_CONNECTION_ERROR) else: buffer = self._sock.recv(socket_read_size) # an empty string indicates the server shutdown the socket if not isinstance(buffer, bytes) or len(buffer) == 0: raise socket.error(SERVER_CLOSED_CONNECTION_ERROR) except socket.timeout: raise TimeoutError("Timeout reading from socket") except socket.error: e = sys.exc_info()[1] raise ConnectionError("Error while reading from socket: %s" % (e.args, )) if HIREDIS_USE_BYTE_BUFFER: self._reader.feed(self._buffer, 0, bufflen) else: self._reader.feed(buffer) response = self._reader.gets() # if an older version of hiredis is installed, we need to attempt # to convert ResponseErrors to their appropriate types. if not HIREDIS_SUPPORTS_CALLABLE_ERRORS: if isinstance(response, ResponseError): response = self.parse_error(response.args[0]) elif isinstance(response, list) and response and \ isinstance(response[0], ResponseError): response[0] = self.parse_error(response[0].args[0]) # if the response is a ConnectionError or the response is a list and # the first item is a ConnectionError, raise it as something bad # happened if isinstance(response, ConnectionError): raise response elif isinstance(response, list) and response and \ isinstance(response[0], ConnectionError): raise response[0] return response
def recv(self, max_len=0): if self.closed: raise socket.error(errno.EBADF, 'Closed socket') if self.fail: raise socket.error(errno.EPIPE, 'Peer closed connection') if not self.input: return '' if max_len <= 0: max_len = len(self.input) if not dice(): max_len = randint(1, max_len) data = self.input[:max_len] self.input = self.input[max_len:] delay() return data
def __init__(self,timeout=2,max_outstanding=10): """ :timeout - amount of time a ICMP echo request can be outstanding :max_outstanding - maximum number of outstanding ICMP echo requests without responses (limits traffic) """ self.timeout = timeout self.max_outstanding = max_outstanding # id we will increment with each ping self.id = 0 # object to hold and keep track of all of our self.pings self.pings = {} # event to file when we want to shut down self.die_event = Event() # setup socket icmp = socket.getprotobyname("icmp") try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) except socket.error, (errno, msg): if errno == 1: # Operation not permitted msg = msg + ( " - Note that ICMP messages can only be sent from processes" " running as root." ) raise socket.error(msg) raise # raise the original error
def __init__(self, timeout=2, max_outstanding=10): """ :timeout - amount of time a ICMP echo request can be outstanding :max_outstanding - maximum number of outstanding ICMP echo requests without responses (limits traffic) """ self.timeout = timeout self.max_outstanding = max_outstanding # id we will increment with each ping self.id = 0 # object to hold and keep track of all of our self.pings self.pings = {} # Hold failures self.failures = [] # event to file when we want to shut down self.die_event = Event() # setup socket icmp = socket.getprotobyname("icmp") try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) except socket.error as e: if e.errno == 1: # Operation not permitted e.message = str(e) + ( " - Note that ICMP messages can only be sent from processes" " running as root.") raise socket.error(e.message) raise # raise the original error self.receive_glet = gevent.spawn(self.__receive__) self.processto_glet = gevent.spawn(self.__process_timeouts__)
def handle_request(self, handler, raw_request_data): # in a sending only transport, no more data is expected from the client # but we need to be notified immediately if the connection has been # aborted by the client. fd = handler.socket.fileno() # start 2 greenlets, one that checks for an aborted connection # and the other that produces the messages producer = gevent.Greenlet(self.produce_messages, handler) conn_check = gevent.Greenlet(select.select, [fd], [], [fd]) threads = [ producer, conn_check ] # start both threads for thread in threads: thread.start() # wait for one to return ret = util.waitany(threads) if ret == producer: # the producer thread returned first, all good here. conn_check.kill() return # looks like the connection was aborted producer.kill() raise socket.error(socket.EBADF)
def __init__(self, *args, **kwargs): Connection.__init__(self, *args, **kwargs) self.connected_event = Event() self._write_queue = Queue() self._callbacks = {} self._push_watchers = defaultdict(set) sockerr = None addresses = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM) for (af, socktype, proto, canonname, sockaddr) in addresses: try: self._socket = socket.socket(af, socktype, proto) if self.ssl_options: self._socket = ssl.wrap_socket(self._socket, **self.ssl_options) self._socket.settimeout(1.0) self._socket.connect(sockaddr) sockerr = None break except socket.error as err: sockerr = err if sockerr: raise socket.error(sockerr.errno, "Tried connecting to %s. Last error: %s" % ([a[4] for a in addresses], sockerr.strerror)) if self.sockopts: for args in self.sockopts: self._socket.setsockopt(*args) self._read_watcher = gevent.spawn(self.handle_read) self._write_watcher = gevent.spawn(self.handle_write) self._send_options_message()
def __init__(self, timeout=1, max_outstanding=1000): """ :timeout - amount of time a ICMP echo request can be outstanding :max_outstanding - maximum number of outstanding ICMP echo requests without responses (limits traffic) """ self.timeout = timeout self.max_outstanding = max_outstanding # id we will increment with each ping self.id = 0 # object to hold and keep track of all of our self.pings self.pings = {} # event to file when we want to shut down self.die_event = Event() # setup socket icmp = socket.getprotobyname("icmp") try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) except socket.error, (errno, msg): if errno == 1: # Operation not permitted msg = msg + ( " - Note that ICMP messages can only be sent from processes" " running as root.") raise socket.error(msg) raise # raise the original error
def _thread_error(self, thread): """ Handles the case that the send or receive thread exit or throw an exception. """ # Avoid double-killing the thread if thread == self._send_thread: self._send_thread = None if thread == self._recv_thread: self._recv_thread = None # Figure out why the thread exited if thread.successful(): exception = socket.error('thread exited prematurely') elif isinstance(thread.exception, gevent.GreenletExit): # Thread was killed; don't do anything but close self.close() return else: exception = thread.exception # Close the connection... self.close() # Notify the application what happened self.closed(exception)
def _raw_read(modbus, fd): data = '' try: while(1): raw_data = fd.recv(16 * 1024) if raw_data: data += raw_data if len(data) > 7: tid,pid,length,uid = struct.unpack('>HHHB',data[:7]) if len(data) >= length + 6: # new msg func_code = ord(data[7]) end_msg = 8 + length - 2 msg = data[8:end_msg] data = data[end_msg:] transaction = modbus._transaction.get(tid) if transaction: transaction.put((uid,func_code,msg)) else: break except: pass finally: fd.close() try: modbus._connected = False modbus._fd = None #inform all pending requests that the socket closed for trans in modbus._transaction.values(): trans.put(socket.error(errno.EPIPE,"Broken pipe")) except ReferenceError: pass
def _prepare_for_handoff(self): """Stop operations and prepare for a connection handoff. Note that, among other things, this stops the client from responding to PINGs from the server, and so effectively begins a timeout until the server drops the connection.""" if self.ssl: raise ValueError("Handing off of an ssl connection is not supported") # wait until we aren't changing nick, then permanently acquire the lock to prevent further changes # (note that forced_nick_change could still change it, but that's ok because we're stopping recv_loop) self._nick_lock.acquire() self._named_greenlets['_idle_watchdog'].kill(block=True) self._kill_recv = True # recv_loop will exit after processing current lines if self._recv_waiting: # recv_loop is stuck in a socket.recv call and should be bumped out self._named_greenlets['_recv_loop'].kill(socket.error(errno.EINTR, "recv_loop is being killed"), block=False) self._named_greenlets['_recv_loop'].get() # we are now no longer recving messages - we set a trap on _send(), then wait for send_queue to drain. # in practice, things should be unlikely to hit trap. def trap(*a, **k): raise Exception("Connection is being handed off, messages cannot be sent") self._send = trap # since we need to clear send queue, it makes no sense to try to hand off while it is limited if self._send_queue.get_limit() is not None: raise Exception("Can't hand off while send queue is limited") # We re-use the activity flag to check queue after each message is sent while True: self._activity.clear() if self._send_queue.empty(): break self._activity.wait()
def _read_from_socket(self, length=None): socket_read_size = self.socket_read_size buf = self._buffer buf.seek(self.bytes_written) marker = 0 try: while True: data = self._sock.recv(socket_read_size) # an empty string indicates the server shutdown the socket if isinstance(data, bytes) and len(data) == 0: raise socket.error(SERVER_CLOSED_CONNECTION_ERROR) buf.write(data) data_length = len(data) self.bytes_written += data_length marker += data_length if length is not None and length > marker: continue break except socket.timeout: raise TimeoutError("Timeout reading from socket") except socket.error: e = sys.exc_info()[1] raise ConnectionError("Error while reading from socket: %s" % (e.args, ))
def create_connection_hosts(addrs, port, timeout): for addr in addrs: try: return socket.create_connection((addr, port), timeout=timeout) except: pass raise socket.error("all addrs are failed.") # @UndefinedVariable
def create_connection_ipv4(address, timeout=None, source_address=None, only_ports=None): """Attempts to mimick to :py:func:`socket.create_connection`, but connections are only made to IPv4 addresses. :param only_ports: If given, can be a list to limit which ports are restricted to IPv4. Connections to all other ports may be IPv6. """ host, port = address if only_ports and port not in only_ports: return socket.create_connection(address, timeout, source_address) last_exc = None for res in socket.getaddrinfo(host, port, socket.AF_INET): _, _, _, _, sockaddr = res try: return socket.create_connection(sockaddr, timeout, source_address) except socket.error as exc: last_exc = exc if last_exc is not None: raise last_exc else: raise socket.error('getaddrinfo returns an empty list')
def _raw_read(command,fd): try: while(1): raw_data = fd.recv(16 * 1024) with command._lock: if raw_data and command._transaction_list: command._transaction_list[0].put(raw_data) else: break except: pass finally: try: fd.close() except socket.error: pass try: command._connected = False command._fd = None #inform all pending transaction that the socket is closed with command._lock: for trans in command._transaction_list: trans.put(socket.error(errno.EPIPE,"Broken pipe")) except ReferenceError: pass
def _read_from_socket(self, length=None): socket_read_size = self.socket_read_size buf = self._buffer buf.seek(self.bytes_written) marker = 0 try: while True: data = self._sock.recv(socket_read_size) # an empty string indicates the server shutdown the socket if isinstance(data, bytes) and len(data) == 0: raise socket.error(SERVER_CLOSED_CONNECTION_ERROR) buf.write(data) data_length = len(data) self.bytes_written += data_length marker += data_length if length is not None and length > marker: continue break except socket.timeout: raise TimeoutError("Timeout reading from socket") except socket.error: e = sys.exc_info()[1] raise ConnectionError("Error while reading from socket: %s" % (e.args,))
def wrapper_func(*args,**kwargs): try: return attr(*args,**kwargs) except socket.error as e: if e.errno == errno.EPIPE: raise socket.error(errno.ECONNREFUSED,"Connection refused") else: raise
def _tests(self, key): if key == "socket.error": raise socket.error() if key == "socket.dns": raise DNSError() if key == "memcache.illegal": raise MemcacheIllegalInputError() if key == "memcache.error": raise MemcacheError()
def test_error(self): socket.getaddrinfo('host', 25, socket.AF_INET).AndReturn([ (None, None, None, None, 'sockaddr') ]) socket.create_connection('sockaddr', IgnoreArg(), IgnoreArg()).AndRaise(socket.error('error')) self.mox.ReplayAll() with self.assertRaises(socket.error): self.socket_creator(('host', 25), 'timeout', 'source')
def test_exit_closeerror(self): sock = mock.Mock(**{'close.side_effect': socket.error()}) closer = utils.SocketCloser(sock) result = closer.__exit__(TestException, TestException('foo'), []) self.assertEqual(result, None) sock.close.assert_called_once_with() self.assertEqual(closer.errors, None)
def wrapper_func(*args, **kwargs): try: return attr(*args, **kwargs) except socket.error as e: if e.errno == errno.EPIPE: raise socket.error(errno.ECONNREFUSED, "Connection refused") else: raise
def test_together_closeerror(self): sock = mock.Mock(**{'close.side_effect': socket.error()}) with self.assertRaises(TestException): with utils.SocketCloser(sock): sock.make_call() raise TestException('spam') sock.make_call.assert_called_once_with() sock.close.assert_called_once_with()
def getipinfo(self, ip, retry=None): if ipnotuse(ip): return None, 0, '' start_time = time() costtime = 0 domains = None servername = '' sock = None ssl_sock = None try: sock = socket.socket(socket.AF_INET if ':' not in ip else socket.AF_INET6) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0)) sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True) ssl_sock = self.get_ssl_socket(sock, b'www.google.com') ssl_sock.settimeout(g_conntimeout) ssl_sock.connect((ip, 443)) ssl_sock.settimeout(g_handshaketimeout) ssl_sock.do_handshake() handshaked_time = time() - start_time ssl_sock.settimeout(g_timeout) if handshaked_time > g_handshaketimeout: raise socket.error('handshake cost %dms timed out' % int(handshaked_time * 1000)) cert = self.get_peercert(ssl_sock) if not cert: raise socket.error(u"无法从 %s 获取证书。", ip) domains = self.getdomains(cert) if not domains: raise ssl.SSLError(u"%s 无法获取 commonName:%s " % (ip, cert)) except NetWorkIOError as e: sock.close() ssl_sock = None if not retry and e.args == (-1, 'Unexpected EOF'): return self.getipinfo(ip, True) WARNING('%r', e) if ssl_sock: servername = self.getservername(ssl_sock, sock, ip) costtime = int((time() - start_time) * 1000) return domains, costtime, servername
def write(self, data): if self.closed: raise socket.error(9, 'File is already closed') if not data: return if self.record_type == FCGI_STDERR: sys.stderr.write(data) self.conn.write_record(Record(self.record_type, data, self.request_id))
def read(self, size=1, timeout=None): timeout_errmsg = "timeout on socket(%s, %d)" % (self._host, self._port) with gevent.Timeout(timeout or self._timeout, SocketTimeout(timeout_errmsg)): while len(self._data) < size: self._event.wait() self._event.clear() if not self._connected: raise socket.error(errno.EPIPE,"Broken pipe") msg = self._data[:size] self._data = self._data[size:] return msg
def read(self): data = self.socket.recv(4) if not data: raise socket.error('closed') size = struct.unpack("!I", data)[0] # FIXME: Rewrite, optimize! buf = '' while len(buf) != size: data = self.socket.recv(size - len(buf)) buf += data return buf
def verify_yahoo_account(account): try: conn = IMAPClient(IMAP_HOSTS['Yahoo'], use_uid=True, ssl=True) except IMAPClient.Error as e: raise socket.error(str(e)) conn.debug = False try: conn.login(account.email_address, account.password) except IMAPClient.Error as e: print >>sys.stderr, '[ALERT] Invalid credentials (Failure)' sys.exit(1) return conn
def get_connection(self): try: host, port = provider_info(self.provider_name)['smtp'].split(':') connection = smtplib.SMTP(str(host), int(port)) # Convert to a socket.error so geventconnpool will retry automatically # to establish new connections. We do this so the pool is resistant to # temporary connection errors. except smtplib.SMTPConnectError as e: self.log.error(str(e)) raise socket.error('SMTPConnectError') smtp_connection = SMTPConnection(self.account_id, self.email_address, self.provider_name, self.auth_type, self.auth_token, connection, self.log) return smtp_connection
def _new_connection(self): try: conn = IMAPClient(self.imap_host, use_uid=True, ssl=True) except IMAPClient.Error as e: raise socket.error(str(e)) conn.debug = False try: conn.oauth2_login(self.email_address, self.o_access_token) except IMAPClient.Error as e: if str(e) == "[ALERT] Invalid credentials (Failure)": self._set_account_info() conn.oauth2_login(self.email_address, self.o_access_token) return conn
def raw_read(self, maxsize=None, timeout=None): timeout_errmsg = "timeout on socket(%s, %d)" % (self._host, self._port) with gevent.Timeout(timeout or self._timeout, SocketTimeout(timeout_errmsg)): while not self._data: self._event.wait() self._event.clear() if not self._connected: raise socket.error(errno.EPIPE,"Broken pipe") if maxsize: msg = self._data[:maxsize] self._data = self._data[maxsize:] else: msg = self._data self._data = '' return msg
def response_reader(self): try: # need handshake here greeting = self._socket.recv(IPROTO_GREETING_SIZE) self._salt = base64.decodestring(greeting[64:])[:20] self._auth_event.set() buf = b"" while self.connected: # chunk socket read tmp_buf = self._socket.recv(self.gbuf_size) if not tmp_buf: raise NetworkError(socket.error(errno.ECONNRESET, "Lost connection to server during query")) buf += tmp_buf len_buf = len(buf) curr = 0 while len_buf - curr >= 5: length_pack = buf[curr:curr + 5] length = msgpack.unpackb(length_pack) if len_buf - curr < 5 + length: break body = buf[curr + 5:curr + 5 + length] curr += 5 + length response = Response(self, body) # unpack response # set AsyncResult sync = response.sync if sync in self.req_event: self.req_event[sync].set((response, None)) # one cut for buffer if curr: buf = buf[curr:] except socket.error, ex: if self._writer and not self._writer.ready(): self._writer.kill() with self.lock: self.close() for event in self.req_event.values(): event.set((None, ex))
def verify_gmail_account(account): try: conn = IMAPClient(IMAP_HOSTS['Gmail'], use_uid=True, ssl=True) except IMAPClient.Error as e: raise socket.error(str(e)) conn.debug = False try: conn.oauth2_login(account.email_address, account.o_access_token) except IMAPClient.Error as e: if str(e) == '[ALERT] Invalid credentials (Failure)': # maybe refresh the access token with session_scope() as db_session: account = verify_imap_account(db_session, account) conn.oauth2_login(account.email_address, account.o_access_token) return conn
def _get_connection(self): try: host, port = self.smtp_endpoint connection = smtplib.SMTP() # connection.set_debuglevel(2) connection.connect(host, port) # Convert to a socket.error so geventconnpool will retry automatically # to establish new connections. We do this so the pool is resistant to # temporary connection errors. except smtplib.SMTPConnectError as e: self.log.error(str(e)) raise socket.error('SMTPConnectError') smtp_connection = SMTPConnection(self.account_id, self.email_address, self.provider_name, self.auth_type, self.auth_token, connection, self.log) return smtp_connection
def do_one_ping(addr_info, identifier, sequence, timeout, packet_size): """ Returns either the delay (in seconds) or `None` on timeout. """ icmp = socket.getprotobyname('icmp') if addr_info[0] == socket.AF_INET6: icmp = socket.getprotobyname('ipv6-icmp') try: my_socket = socket.socket(addr_info[0], socket.SOCK_RAW, icmp) except socket.error, (errno, msg): if errno == 1: # Operation not permitted msg = msg + " - Note that ICMP messages can only by sent from processes running " \ "as root." raise socket.error(msg) # raise the original error raise
def _send(self, recipients, msg): """ Send the email message over the network. """ try: with self.get_connection() as smtpconn: failures = smtpconn.sendmail(self.email_address, recipients, msg) # Sent to none successfully except smtplib.SMTPRecipientsRefused: raise SendError(failures) except smtplib.SMTPException as e: self.log.error("Sending failed", exception=e) raise socket.error("Sending failed: Exception {0}".format(e)) # Send to at least one failed if failures: raise SendError(failures) # Sent to all successfully self.log.info("Sending successful", sender=self.email_address, recipients=recipients)
def _readline(self, eol=None, timeout=None): timeout_errmsg = "timeout on socket(%s, %d)" % (self._host, self._port) with gevent.Timeout(timeout or self._timeout, SocketTimeout(timeout_errmsg)): # local_timeout = timeout or self._timeout local_eol = eol or self._eol # start_time = time.time() eol_pos = self._data.find(local_eol) while eol_pos == -1: self._event.wait() self._event.clear() if not self._connected: raise socket.error(errno.EPIPE,"Broken pipe") eol_pos = self._data.find(local_eol) msg = self._data[:eol_pos] self._data = self._data[eol_pos + len(local_eol):] return msg
def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None, socket_options=None): """Connect to *address* and return the socket object. Convenience function. Connect to *address* (a 2-tuple ``(host, port)``) and return the socket object. Passing the optional *timeout* parameter will set the timeout on the socket instance before attempting to connect. If no *timeout* is supplied, the global default timeout setting returned by :func:`getdefaulttimeout` is used. If *source_address* is set it must be a tuple of (host, port) for the socket to bind as a source address before making the connection. An host of '' or port 0 tells the OS to use the default. """ host, port = address err = None for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res sock = None try: sock = socket.socket(af, socktype, proto) # If provided, set socket level options before connecting. # This is the only addition urllib3 makes to this function. _set_socket_options(sock, socket_options) if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: sock.settimeout(timeout) if source_address: sock.bind(source_address) sock.connect(sa) return sock except socket.error as _: err = _ if sock is not None: sock.close() if err is not None: raise err else: raise socket.error("getaddrinfo returns an empty list")
def recvfrom(self, bufsize, flags=0): if self.type != socket.SOCK_DGRAM: return _BaseSocket.recvfrom(self, bufsize, flags) if not self._proxyconn: self.bind(("", 0)) buf = BytesIO(_BaseSocket.recv(self, bufsize, flags)) buf.seek(+2, SEEK_CUR) frag = buf.read(1) if ord(frag): raise NotImplementedError("Received UDP packet fragment") fromhost, fromport = self._read_SOCKS5_address(buf) if self.proxy_peername: peerhost, peerport = self.proxy_peername if fromhost != peerhost or peerport not in (0, fromport): raise socket.error(EAGAIN, "Packet filtered") return (buf.read(), (fromhost, fromport))
def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None): """Connect to *address* and return the socket object. Convenience function. Connect to *address* (a 2-tuple ``(host, port)``) and return the socket object. Passing the optional *timeout* parameter will set the timeout on the socket instance before attempting to connect. If no *timeout* is supplied, the global default timeout setting returned by :func:`getdefaulttimeout` is used. If *source_address* is set it must be a tuple of (host, port) for the socket to bind as a source address before making the connection. An host of '' or port 0 tells the OS to use the default. """ host, port = address err = None force_direct_connect = host == globalconfig['reconnect.routerip'] and True or False for res in socket.getaddrinfo(host, port, 0 if socket.has_ipv6 else socket.AF_INET, socket.SOCK_STREAM): af, socktype, proto, _canonname, sa = res sock = None try: sock = socket.socket(af, socktype, proto, force_direct_connect=force_direct_connect) if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: sock.settimeout(timeout) if source_address: sock.bind(source_address) sock.connect(sa) return sock except socket.error: err = sys.exc_info()[1] # without exc_clear(), if connect() fails once, the socket is referenced by the frame in exc_info # and the next bind() fails (see test__socket.TestCreateConnection) # that does not happen with regular sockets though, because _socket.socket.connect() is a built-in. # this is similar to "getnameinfo loses a reference" failure in test_socket.py sys.exc_clear() if sock is not None: sock.close() if err is not None: raise err else: raise socket.error("getaddrinfo returns an empty list")
def _send(self, recipients, msg): """ Send the email message over the network. """ try: with self.get_connection() as smtpconn: failures = smtpconn.sendmail(self.email_address, recipients, msg) # Sent to none successfully except smtplib.SMTPRecipientsRefused: raise SendError(failures) except smtplib.SMTPException as e: self.log.error('Sending failed', exception=e) raise socket.error('Sending failed: Exception {0}'.format(e)) # Send to at least one failed if failures: raise SendError(failures) # Sent to all successfully self.log.info('Sending successful', sender=self.email_address, recipients=recipients)
def _new_connection(self): try: connection = smtplib.SMTP(SMTP_HOSTS[self.provider], SMTP_PORT) # Convert to a socket.error so geventconnpool will retry automatically # to establish new connections. We do this so the pool is resistant to # temporary connection errors. except smtplib.SMTPConnectError as e: self.log.error(str(e)) raise socket.error('SMTPConnectError') connection.set_debuglevel(self.debug) account_info = AccountInfo(id=self.account_id, email=self.email_address, provider=self.provider, auth_type=self.auth_type, auth_token=self.auth_token) smtp_connection = SMTPConnection(account_info, connection, self.log) return smtp_connection
def _connect(self): """这部分是真正的建立与reids的tcp连接""" # we want to mimic what socket.create_connection does to support # ipv4/ipv6, but we want to set options prior to calling # socket.connect() err = None for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): family, socktype, proto, canonname, socket_address = res sock = None try: sock = socket.socket(family, socktype, proto) # TCP_NODELAY sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) # TCP_KEEPALIVE if self.socket_keepalive: sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) for k, v in iteritems(self.socket_keepalive_options): sock.setsockopt(socket.SOL_TCP, k, v) # set the socket_connect_timeout before we connect sock.settimeout(self.socket_connect_timeout) # connect sock.connect(socket_address) # set the socket_timeout now that we're connected sock.settimeout(self.socket_timeout) return sock except socket.error as _: err = _ if sock is not None: sock.close() if err is not None: raise err raise socket.error("socket.getaddrinfo returned an empty list")
def test_together_closeerror_thresh(self): sock = mock.Mock(**{'close.side_effect': socket.error()}) closer = utils.SocketCloser(sock, 1) with closer: sock.make_call() raise TestException('spam') sock.make_call.assert_called_once_with() self.assertFalse(sock.close.called) self.assertEqual(closer.errors, 1) sock.reset_mock() with self.assertRaises(TestException): with closer: sock.make_call() raise TestException('spam') sock.make_call.assert_called_once_with() sock.close.assert_called_once_with() self.assertEqual(closer.errors, 1)
def _create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None, prepare=None): # Taken from: # https://github.com/python/cpython/blob/0f40482fde59ff307569fa5676183dd8432809a8/Lib/socket.py#L771 # Licensed under the PSFL, version 2 # Copyright (c) 2001-now Python Software Foundation host, port = address err = None for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res sock = None try: sock = socket(af, socktype, proto) if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: sock.settimeout(timeout) if source_address: sock.bind(source_address) if prepare: prepare(sock) sock.connect(sa) # Break explicitly a reference cycle err = None return sock except socket.error as e: err = e if sock is not None: sock.close() if err is not None: try: raise err finally: # Break explicitly a reference cycle err = None else: raise socket.error("getaddrinfo returns an empty list")
def _send(self, recipients, msg): """ Send the email message over the network. """ with self.pool.get() as smtpconn: with smtpconn: try: failures = smtpconn.sendmail(self.email_address, recipients, msg) # Sent to none successfully except smtplib.SMTPRecipientsRefused: raise SendError(failures) except (smtplib.SMTPException, smtplib.SMTPServerDisconnected)\ as e: self.log.error('Sending failed: Exception {0}'.format(e)) raise socket.error( 'Sending failed: Exception {0}'.format(e)) # Send to at least one failed if failures: raise SendError(failures) # Sent to all successfully self.log.info('Sending successful: {0} to {1}'.format( self.email_address, ', '.join(recipients)))
def _new_connection(self): try: connection = smtplib.SMTP(SMTP_HOSTS[self.provider], SMTP_PORT) # Convert to a socket.error so geventconnpool will retry automatically # to establish new connections. We do this so the pool is resistant to # temporary connection errors. except smtplib.SMTPConnectError as e: self.log.error(str(e)) raise socket.error('SMTPConnectError') connection.set_debuglevel(self.debug) auth_token = self.o_access_token if self.o_access_token else\ self.password account_info = AccountInfo(id=self.account_id, email=self.email_address, provider=self.provider, full_name=self.full_name, auth_type=self.auth_type, auth_token=auth_token) smtp_connection = SMTPConnection(account_info, connection, self.log) return smtp_connection
def _connect(self): from gevent import socket err = None for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): family, socktype, proto, canonname, socket_address = res sock = None try: sock = socket.socket(family, socktype, proto) # TCP_NODELAY sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) # TCP_KEEPALIVE if self.socket_keepalive: sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) for k, v in self.socket_keepalive_options.iteritems(): sock.setsockopt(socket.SOL_TCP, k, v) # set the socket_connect_timeout before we connect sock.settimeout(self.socket_connect_timeout) # connect sock.connect(socket_address) # set the socket_timeout now that we're connected sock.settimeout(self.socket_timeout) return sock except socket.error as _: err = _ if sock is not None: sock.close() if err is not None: raise err raise socket.error("socket.getaddrinfo returned an empty list")
def create_connection( address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, dns_timeout=None, source_address=None, use_happyeyeballs=True, prepare=None, ): _log.debug("create_connection %r", address) (host, port, *_) = address try: ipaddress.ip_address(host) use_happyeyeballs = False except ValueError: pass if not use_happyeyeballs: # TODO: a bit problematic we use socket's hidden timeout sentinel # as our default, but it hasn't changed for 12 years so we're probably # gonna be fine; maybe! return _create_connection(address, timeout=timeout, source_address=source_address, prepare=prepare) group = pool.Group() # TODO: OK, I'm gonna be honest: this system of greenlet orchestration # is really, uhh, let's just say not good; the proper way of implementing # this would be something like curio's TaskGroup: a Group that tracks the # completion states of its members # (0, (family, addr)) = success (gai) # (1, sock) = success (result) # (-1, (family, None, exc)) = fail (gai) # (-2, (family, addr, exc)) = fail (connect) bus = queue.Queue() def _do_gai(family, proto=0, flags=0): _log.debug("_do_gai: started family=%s, proto=%d, flags=%s", family, proto, flags) try: addrs = gevent.with_timeout( dns_timeout, socket.getaddrinfo, host, port, family, socket.SOCK_STREAM, proto, flags, ) _log.debug("_do_gai: finished family=%s, addrs=%r", family, addrs) while addrs: (*_, addr) = addrs.pop() bus.put((0, (family, addr))) except _Cancel: _log.debug("_do_gai: cancelled family=%s", family) except gevent.Timeout: bus.put((-1, (family, None, socket.gaierror(-errno.ETIMEDOUT, "Timed out")))) except Exception as e: bus.put((-1, (family, None, e))) dns_attempts = 2 group.apply_async(_do_gai, args=(socket.AF_INET6, 0, socket.AI_V4MAPPED)) group.apply_async(_do_gai, args=(socket.AF_INET, )) def _do_connect(family, addr): _log.debug("_do_connect: started family=%s, addr=%s", family, addr) # TODO: god I hate the flow of logic in this proc sock = socket.socket(family, socket.SOCK_STREAM) if source_address: sock.bind(source_address) if prepare: prepare(sock) try: sock.connect(addr) _log.debug( "_do_connect: finished family=%s, addr=%s, socket=%r", family, addr, sock, ) except _Cancel: _log.debug("_do_connect: cancelled family=%s, addr=%s", family, addr) except Exception as e: bus.put((-2, (family, addr, e))) except: sock.close() raise else: return bus.put((1, sock)) sock.close() do_later = queue.Queue() started_ipv6 = event.Event() def _laterlet(): try: stagger = started_ipv6.wait(timeout=RESOLVE_DELAY) if stagger: gevent.sleep(CONNECT_DELAY) for cb, args, kwds in do_later: group.apply_async(cb, args, kwds) except _Cancel: pass group.apply_async(_laterlet) if timeout is socket._GLOBAL_DEFAULT_TIMEOUT: timeout = None started = time.monotonic() conn_attempts = 0 errors = [] t = timeout try: while True: # TODO: technically this is not right: # we take dns query times into account as timeout # no good; though there's no better way of solving it # without restructuring the entire algo if t is not None: t = max(MIN_TIMEOUT, timeout - (time.monotonic() - started)) op, rest = bus.get(timeout=t) _log.debug("bus get op %d with payload %s", op, rest) _log.debug("error states = %r", errors) if op == 1: return rest elif op == -1: errors.append(rest) dns_attempts -= 1 if dns_attempts <= 0: raise socket.error(errors) continue elif op == -2: errors.append(rest) conn_attempts -= 1 if conn_attempts <= 0: raise socket.error(errors) continue family, addr = rest conn_attempts += 1 if family == socket.AF_INET: do_later.put((_do_connect, (socket.AF_INET, addr), {})) else: started_ipv6.set() group.apply_async(_do_connect, (socket.AF_INET6, addr)) except queue.Empty: raise socket.timeout("timed out") finally: group.kill(_Cancel)
class TestUDPTendrilManager(unittest.TestCase): @mock.patch.object(manager.TendrilManager, '__init__') def test_init(self, mock_init): manager = udp.UDPTendrilManager() mock_init.assert_called_once_with(None) self.assertEqual(manager._sock, None) self.assertIsInstance(manager._sock_event, event.Event) self.assertEqual(manager._sock_event.is_set(), False) @mock.patch.object(manager.TendrilManager, 'start') def test_start(self, mock_start): manager = udp.UDPTendrilManager() manager._sock = 'sock' manager._sock_event = mock.Mock() manager.start('acceptor', 'wrapper') mock_start.assert_called_once_with('acceptor', 'wrapper') self.assertEqual(manager._sock, None) manager._sock_event.clear.assert_called_once_with() @mock.patch.object(manager.TendrilManager, 'stop') def test_stop(self, mock_stop): manager = udp.UDPTendrilManager() manager._sock = 'sock' manager._sock_event = mock.Mock() manager.stop('thread') mock_stop.assert_called_once_with('thread') self.assertEqual(manager._sock, None) manager._sock_event.clear.assert_called_once_with() @mock.patch.object(manager.TendrilManager, 'shutdown') def test_shutdown(self, mock_shutdown): manager = udp.UDPTendrilManager() manager._sock = 'sock' manager._sock_event = mock.Mock() manager.shutdown() mock_shutdown.assert_called_once_with() self.assertEqual(manager._sock, None) manager._sock_event.clear.assert_called_once_with() @mock.patch.object(manager.TendrilManager, 'connect') @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) @mock.patch.object(udp.UDPTendrilManager, 'local_addr', ('0.0.0.0', 8880)) def test_connect(self, mock_UDPTendril, mock_track_tendril, mock_connect): acceptor = mock.Mock() manager = udp.UDPTendrilManager() tend = manager.connect(('127.0.0.1', 8080), acceptor) mock_connect.assert_called_once_with(('127.0.0.1', 8080), acceptor, None) mock_UDPTendril.assert_called_once_with(manager, ('0.0.0.0', 8880), ('127.0.0.1', 8080)) acceptor.assert_called_once_with(mock_UDPTendril.return_value) mock_track_tendril.assert_called_once_with( mock_UDPTendril.return_value) self.assertEqual(id(tend), id(mock_UDPTendril.return_value)) @mock.patch.object(manager.TendrilManager, 'connect') @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) @mock.patch.object(udp.UDPTendrilManager, 'local_addr', ('0.0.0.0', 8880)) def test_connect_rejected(self, mock_UDPTendril, mock_track_tendril, mock_connect): acceptor = mock.Mock(side_effect=application.RejectConnection()) manager = udp.UDPTendrilManager() tend = manager.connect(('127.0.0.1', 8080), acceptor) mock_connect.assert_called_once_with(('127.0.0.1', 8080), acceptor, None) mock_UDPTendril.assert_called_once_with(manager, ('0.0.0.0', 8880), ('127.0.0.1', 8080)) acceptor.assert_called_once_with(mock_UDPTendril.return_value) self.assertFalse(mock_track_tendril.called) self.assertEqual(tend, None) @mock.patch.object(socket, 'socket', return_value=mock.Mock( **{ 'recvfrom.side_effect': TestException(), 'getsockname.return_value': ('127.0.0.1', 8080), })) @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) def test_listener_creator(self, mock_UDPTendril, mock_track_tendril, mock_socket): acceptor = mock.Mock() manager = udp.UDPTendrilManager() manager.running = True with self.assertRaises(TestException): manager.listener(acceptor, None) mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM) mock_socket.return_value.assert_has_calls([ mock.call.bind(('', 0)), mock.call.getsockname(), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.close(), ]) self.assertEqual(manager.local_addr, ('127.0.0.1', 8080)) self.assertFalse(mock_UDPTendril.called) self.assertFalse(acceptor.called) self.assertFalse(mock_track_tendril.called) @mock.patch.object(socket, 'socket', return_value=mock.Mock( **{ 'recvfrom.side_effect': TestException(), 'getsockname.return_value': ('127.0.0.1', 8080), })) @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) @mock.patch.object(udp.UDPTendrilManager, 'recv_bufsize', 8192) def test_listener_creator_recv_bufsize(self, mock_UDPTendril, mock_track_tendril, mock_socket): acceptor = mock.Mock() manager = udp.UDPTendrilManager() manager.running = True with self.assertRaises(TestException): manager.listener(acceptor, None) mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM) mock_socket.return_value.assert_has_calls([ mock.call.bind(('', 0)), mock.call.getsockname(), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.recvfrom(8192), mock.call.close(), ]) self.assertEqual(manager.local_addr, ('127.0.0.1', 8080)) self.assertFalse(mock_UDPTendril.called) self.assertFalse(acceptor.called) self.assertFalse(mock_track_tendril.called) @mock.patch.object(socket, 'socket', return_value=mock.Mock( **{ 'recvfrom.side_effect': gevent.GreenletExit(), 'getsockname.return_value': ('127.0.0.1', 8080), 'close.side_effect': socket.error(), })) @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) def test_listener_killed(self, mock_UDPTendril, mock_track_tendril, mock_socket): acceptor = mock.Mock() manager = udp.UDPTendrilManager() manager.running = True with self.assertRaises(gevent.GreenletExit): manager.listener(acceptor, None) mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM) mock_socket.return_value.assert_has_calls([ mock.call.bind(('', 0)), mock.call.getsockname(), mock.call.recvfrom(4096), mock.call.close(), ]) self.assertEqual(manager.local_addr, ('127.0.0.1', 8080)) self.assertFalse(mock_UDPTendril.called) self.assertFalse(acceptor.called) self.assertFalse(mock_track_tendril.called) @mock.patch.object(socket, 'socket', return_value=mock.Mock( **{ 'recvfrom.side_effect': TestException(), 'getsockname.return_value': ('127.0.0.1', 8080), })) @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) def test_listener_wrapper(self, mock_UDPTendril, mock_track_tendril, mock_socket): wrapped_sock = mock.Mock(**{ 'recvfrom.side_effect': TestException(), }) wrapper = mock.Mock(return_value=wrapped_sock) acceptor = mock.Mock() manager = udp.UDPTendrilManager() manager.running = True with self.assertRaises(TestException): manager.listener(acceptor, wrapper) mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM) mock_socket.return_value.assert_has_calls([ mock.call.bind(('', 0)), mock.call.getsockname(), ]) wrapper.assert_called_once_with(mock_socket.return_value) wrapped_sock.assert_has_calls([ mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.close(), ]) self.assertEqual(manager.local_addr, ('127.0.0.1', 8080)) self.assertFalse(mock_UDPTendril.called) self.assertFalse(acceptor.called) self.assertFalse(mock_track_tendril.called) @mock.patch.object(socket, 'socket', return_value=mock.Mock(**{ 'getsockname.return_value': ('127.0.0.1', 8080), })) @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) def test_listener_noacceptor(self, mock_UDPTendril, mock_track_tendril, mock_socket): msgs = ['msg1', 'msg2', 'msg3'] mock_socket.return_value.recvfrom.side_effect = [ (msgs[0], ('127.0.0.2', 8082)), (msgs[1], ('127.0.0.3', 8083)), (msgs[2], ('127.0.0.4', 8084)), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), ] tend = mock.Mock() manager = udp.UDPTendrilManager() manager.running = True manager.tendrils[(('127.0.0.1', 8080), ('127.0.0.3', 8083))] = tend with self.assertRaises(TestException): manager.listener(None, None) mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM) mock_socket.return_value.assert_has_calls([ mock.call.bind(('', 0)), mock.call.getsockname(), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.close(), ]) self.assertEqual(manager.local_addr, ('127.0.0.1', 8080)) self.assertFalse(mock_UDPTendril.called) self.assertFalse(mock_track_tendril.called) tend._recv_frameify.assert_called_once_with('msg2') @mock.patch.object(socket, 'socket', return_value=mock.Mock(**{ 'getsockname.return_value': ('127.0.0.1', 8080), })) @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) def test_listener_recv_frameify_error(self, mock_UDPTendril, mock_track_tendril, mock_socket): mock_socket.return_value.recvfrom.side_effect = [ ('frame', ('127.0.0.3', 8083)), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), ] tend = mock.Mock(**{'_recv_frameify.side_effect': TestException()}) manager = udp.UDPTendrilManager() manager.running = True manager.tendrils[(('127.0.0.1', 8080), ('127.0.0.3', 8083))] = tend with self.assertRaises(TestException): manager.listener(None, None) mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM) mock_socket.return_value.assert_has_calls([ mock.call.bind(('', 0)), mock.call.getsockname(), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.close(), ]) self.assertEqual(manager.local_addr, ('127.0.0.1', 8080)) self.assertFalse(mock_UDPTendril.called) self.assertFalse(mock_track_tendril.called) tend._recv_frameify.assert_called_once_with('frame') tend.close.assert_called_once_with() self.assertEqual(tend.closed.call_count, 1) args = tend.closed.call_args[0] self.assertEqual(len(args), 1) self.assertIsInstance(args[0], TestException) @mock.patch.object(socket, 'socket', return_value=mock.Mock(**{ 'getsockname.return_value': ('127.0.0.1', 8080), })) @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) def test_listener_acceptor(self, mock_UDPTendril, mock_track_tendril, mock_socket): msgs = ['msg1', 'msg2', 'msg3'] mock_socket.return_value.recvfrom.side_effect = [ (msgs[0], ('127.0.0.2', 8082)), (msgs[1], ('127.0.0.3', 8083)), (msgs[2], ('127.0.0.4', 8084)), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), ] tendrils = [mock.Mock(), mock.Mock(), mock.Mock()] mock_UDPTendril.side_effect = [tendrils[0], tendrils[2]] acceptor = mock.Mock() manager = udp.UDPTendrilManager() manager.running = True manager.tendrils[(('127.0.0.1', 8080), ('127.0.0.3', 8083))] = tendrils[1] with self.assertRaises(TestException): manager.listener(acceptor, None) mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM) mock_socket.return_value.assert_has_calls([ mock.call.bind(('', 0)), mock.call.getsockname(), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.close(), ]) self.assertEqual(manager.local_addr, ('127.0.0.1', 8080)) mock_UDPTendril.assert_has_calls([ mock.call(manager, ('127.0.0.1', 8080), ('127.0.0.2', 8082)), mock.call(manager, ('127.0.0.1', 8080), ('127.0.0.4', 8084)), ]) acceptor.assert_has_calls([ mock.call(tendrils[0]), mock.call(tendrils[2]), ]) mock_track_tendril.assert_has_calls([ mock.call(tendrils[0]), mock.call(tendrils[2]), ]) tendrils[0]._recv_frameify.assert_called_once_with('msg1') tendrils[1]._recv_frameify.assert_called_once_with('msg2') tendrils[2]._recv_frameify.assert_called_once_with('msg3') @mock.patch.object(socket, 'socket', return_value=mock.Mock(**{ 'getsockname.return_value': ('127.0.0.1', 8080), })) @mock.patch.object(manager.TendrilManager, '_track_tendril') @mock.patch.object(udp, 'UDPTendril', return_value=mock.Mock()) def test_listener_rejector(self, mock_UDPTendril, mock_track_tendril, mock_socket): mock_socket.return_value.recvfrom.side_effect = [ ('msg1', ('127.0.0.2', 8082)), ('msg2', ('127.0.0.3', 8083)), ('msg3', ('127.0.0.4', 8084)), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), TestException(), ] tendrils = [mock.Mock(), mock.Mock(), mock.Mock()] mock_UDPTendril.side_effect = tendrils[:] acceptor = mock.Mock(side_effect=application.RejectConnection()) manager = udp.UDPTendrilManager() manager.running = True with self.assertRaises(TestException): manager.listener(acceptor, None) mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM) mock_socket.return_value.assert_has_calls([ mock.call.bind(('', 0)), mock.call.getsockname(), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.recvfrom(4096), mock.call.close(), ]) self.assertEqual(manager.local_addr, ('127.0.0.1', 8080)) mock_UDPTendril.assert_has_calls([ mock.call(manager, ('127.0.0.1', 8080), ('127.0.0.2', 8082)), mock.call(manager, ('127.0.0.1', 8080), ('127.0.0.3', 8083)), mock.call(manager, ('127.0.0.1', 8080), ('127.0.0.4', 8084)), ]) acceptor.assert_has_calls([ mock.call(tendrils[0]), mock.call(tendrils[1]), mock.call(tendrils[2]), ]) self.assertFalse(mock_track_tendril.called) self.assertFalse(tendrils[0]._recv_frameify.called) self.assertFalse(tendrils[1]._recv_frameify.called) self.assertFalse(tendrils[2]._recv_frameify.called) def test_sock_getter_notrunning(self): manager = udp.UDPTendrilManager() manager._sock = 'socket' manager._sock_event = mock.Mock() result = manager.sock self.assertEqual(result, None) self.assertFalse(manager._sock_event.wait.called) def test_sock_getter(self): manager = udp.UDPTendrilManager() manager.running = True manager._sock = 'socket' manager._sock_event = mock.Mock() result = manager.sock self.assertEqual(result, 'socket') manager._sock_event.wait.assert_called_once_with()