Create a TCP socket connection
(self)
| 1537 | return pieces |
| 1538 | |
| 1539 | def _connect(self): |
| 1540 | "Create a TCP socket connection" |
| 1541 | # we want to mimic what socket.create_connection does to support |
| 1542 | # ipv4/ipv6, but we want to set options prior to calling |
| 1543 | # socket.connect() |
| 1544 | err = None |
| 1545 | |
| 1546 | for res in socket.getaddrinfo( |
| 1547 | self.host, self.port, self.socket_type, socket.SOCK_STREAM |
| 1548 | ): |
| 1549 | family, socktype, proto, canonname, socket_address = res |
| 1550 | sock = None |
| 1551 | try: |
| 1552 | sock = socket.socket(family, socktype, proto) |
| 1553 | # TCP_NODELAY |
| 1554 | sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) |
| 1555 | |
| 1556 | # TCP_KEEPALIVE |
| 1557 | if self.socket_keepalive: |
| 1558 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) |
| 1559 | for k, v in self.socket_keepalive_options.items(): |
| 1560 | sock.setsockopt(socket.IPPROTO_TCP, k, v) |
| 1561 | |
| 1562 | # set the socket_connect_timeout before we connect |
| 1563 | sock.settimeout(self.socket_connect_timeout) |
| 1564 | |
| 1565 | # connect |
| 1566 | sock.connect(socket_address) |
| 1567 | |
| 1568 | # set the socket_timeout now that we're connected |
| 1569 | sock.settimeout(self.socket_timeout) |
| 1570 | return sock |
| 1571 | |
| 1572 | except OSError as _: |
| 1573 | err = _ |
| 1574 | if sock is not None: |
| 1575 | try: |
| 1576 | sock.shutdown(socket.SHUT_RDWR) # ensure a clean close |
| 1577 | except OSError: |
| 1578 | pass |
| 1579 | sock.close() |
| 1580 | |
| 1581 | if err is not None: |
| 1582 | raise err |
| 1583 | raise OSError("socket.getaddrinfo returned an empty list") |
| 1584 | |
| 1585 | def _host_error(self): |
| 1586 | return f"{self.host}:{self.port}" |
no test coverage detected