# Buggy code
def _establish_new_socket_connection(
    session_id: str,
    server_hostname: str,
    server_port: int,
    logger: Logger,
    receive_timeout: float,
    proxy: Optional[str],
    proxy_headers: Optional[Dict[str, str]],
    trace_enabled: bool,
) -> Union[ssl.SSLSocket, Socket]:
    if proxy is not None:
        parsed_proxy = urlparse(proxy)
        proxy_host, proxy_port = parsed_proxy.hostname, parsed_proxy.port or 80
        proxy_addr = socket.getaddrinfo(
            proxy_host,
            proxy_port,
            0,
            socket.SOCK_STREAM,
            socket.SOL_TCP,
        )[0]
        sock = socket.socket(proxy_addr[0], proxy_addr[1], proxy_addr[2])
        sock.settimeout(receive_timeout)
        sock.connect(proxy_addr[4])  # proxy address
        message = [f"CONNECT {server_hostname}:{server_port} HTTP/1.0"]
        if parsed_proxy.username is not None and parsed_proxy.password is not None:
            # In the case where the proxy is "http://{username}:{password}@{hostname}:{port}"
            raw_value = f"{parsed_proxy.username}:{parsed_proxy.password}"
            auth = b64encode(raw_value.encode("utf-8")).decode("ascii")
            message.append(f"Proxy-Authorization: Basic {auth}")
        if proxy_headers is not None:
            for k, v in proxy_headers.items():
                message.append(f"{k}: {v}")
        message.append("")
        message.append("")
        req: str = "\r\n".join([line.lstrip() for line in message])
        if trace_enabled:
            logger.debug(f"Proxy connect request (session id: {session_id}):\n{req}")
        sock.send(req.encode("utf-8"))
        status, text = _parse_connect_response(sock)
        if trace_enabled:
            log_message = f"Proxy connect response (session id: {session_id}):\n{text}"
            logger.debug(log_message)
        if status != 200:
            raise Exception(
                f"Failed to connect to the proxy (proxy: {proxy}, connect status code: {status})"
            )

        sock = ssl.SSLContext(ssl.PROTOCOL_SSLv23).wrap_socket(
            sock,
            do_handshake_on_connect=True,
            suppress_ragged_eofs=True,
            server_hostname=server_hostname,
        )
        return sock

    if server_port != 443:
        addr = socket.getaddrinfo(
            server_hostname, server_port, 0, socket.SOCK_STREAM, socket.SOL_TCP
        )[0]
        # only for library testing
        logger.info(
            f"Using non-ssl socket to connect ({server_hostname}:{server_port})"
        )
        sock = Socket(addr[0], addr[1], addr[2])
        sock.settimeout(3)
        sock.connect((server_hostname, server_port))
        return sock

    sock = Socket(type=ssl.SOCK_STREAM)
    sock = ssl.SSLContext(ssl.PROTOCOL_SSLv23).wrap_socket(
        sock,
        do_handshake_on_connect=True,
        suppress_ragged_eofs=True,
        server_hostname=server_hostname,
    )
    sock.settimeout(receive_timeout)
    sock.connect((server_hostname, server_port))
    return sock


# Traceback (SlackApiError)
2021-02-14 18:19:49,579 ERROR    slack_sdk.rtm.v2          Failed to establish a connection (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81, error: _ssl.c:1108: The handshake operation timed out)
Traceback (most recent call last):
File "/opt/errbot/lib/python3.8/site-packages/slack_sdk/socket_mode/builtin/connection.py", line 109, in connect
sock.connect((hostname, port))
File "/usr/lib/python3.8/ssl.py", line 1342, in connect
self._real_connect(addr, False)
File "/usr/lib/python3.8/ssl.py", line 1333, in _real_connect
self.do_handshake()
File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
socket.timeout: _ssl.c:1108: The handshake operation timed out
2021-02-14 18:19:49,579 INFO     slack_sdk.rtm.v2          The connection has been closed (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:19:49,579 INFO     slack_sdk.rtm.v2          The connection has been closed (session id: b88f63ee-d644-45a8-bf18-be36c8673728)
2021-02-14 18:19:49,579 INFO     slack_sdk.rtm.v2          A new session has been established (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:19:49,579 INFO     slack_sdk.rtm.v2          Connected to a new endpoint...
2021-02-14 18:19:59,590 DEBUG    slack_sdk.rtm.v2          This connection is already closed. (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:19:59,590 INFO     slack_sdk.rtm.v2          The session seems to be already closed. Going to reconnect... (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:19:59,590 INFO     slack_sdk.rtm.v2          Connecting to a new endpoint...
2021-02-14 18:20:00,075 ERROR    slack_sdk.rtm.v2          Failed to retrieve WSS URL: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'}
2021-02-14 18:20:00,075 ERROR    slack_sdk.rtm.v2          Failed to check the current session or reconnect to the server (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81, error: SlackApiError, message: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'})
2021-02-14 18:20:10,092 DEBUG    slack_sdk.rtm.v2          This connection is already closed. (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:10,117 INFO     slack_sdk.rtm.v2          The session seems to be already closed. Going to reconnect... (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:10,121 INFO     slack_sdk.rtm.v2          Connecting to a new endpoint...
2021-02-14 18:20:10,339 ERROR    slack_sdk.rtm.v2          Failed to retrieve WSS URL: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'}
2021-02-14 18:20:10,339 ERROR    slack_sdk.rtm.v2          Failed to check the current session or reconnect to the server (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81, error: SlackApiError, message: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'})
2021-02-14 18:20:20,350 DEBUG    slack_sdk.rtm.v2          This connection is already closed. (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:20,350 INFO     slack_sdk.rtm.v2          The session seems to be already closed. Going to reconnect... (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:20,350 INFO     slack_sdk.rtm.v2          Connecting to a new endpoint...
2021-02-14 18:20:20,556 ERROR    slack_sdk.rtm.v2          Failed to retrieve WSS URL: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'}
2021-02-14 18:20:20,557 ERROR    slack_sdk.rtm.v2          Failed to check the current session or reconnect to the server (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81, error: SlackApiError, message: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'ratelimited'})
2021-02-14 18:20:30,567 DEBUG    slack_sdk.rtm.v2          This connection is already closed. (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:30,567 INFO     slack_sdk.rtm.v2          The session seems to be already closed. Going to reconnect... (session id: 18e8f520-5e64-443c-98ed-089ab1ef6f81)
2021-02-14 18:20:30,567 INFO     slack_sdk.rtm.v2          Connecting to a new endpoint...

# Fixed code
def _establish_new_socket_connection(
    session_id: str,
    server_hostname: str,
    server_port: int,
    logger: Logger,
    sock_send_lock: Lock,
    receive_timeout: float,
    proxy: Optional[str],
    proxy_headers: Optional[Dict[str, str]],
    trace_enabled: bool,
) -> Union[ssl.SSLSocket, Socket]:
    if proxy is not None:
        parsed_proxy = urlparse(proxy)
        proxy_host, proxy_port = parsed_proxy.hostname, parsed_proxy.port or 80
        proxy_addr = socket.getaddrinfo(
            proxy_host,
            proxy_port,
            0,
            socket.SOCK_STREAM,
            socket.SOL_TCP,
        )[0]
        sock = socket.socket(proxy_addr[0], proxy_addr[1], proxy_addr[2])
        if hasattr(socket, "TCP_NODELAY"):
            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        if hasattr(socket, "SO_KEEPALIVE"):
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
        sock.settimeout(receive_timeout)
        sock.connect(proxy_addr[4])  # proxy address
        message = [f"CONNECT {server_hostname}:{server_port} HTTP/1.0"]
        if parsed_proxy.username is not None and parsed_proxy.password is not None:
            # In the case where the proxy is "http://{username}:{password}@{hostname}:{port}"
            raw_value = f"{parsed_proxy.username}:{parsed_proxy.password}"
            auth = b64encode(raw_value.encode("utf-8")).decode("ascii")
            message.append(f"Proxy-Authorization: Basic {auth}")
        if proxy_headers is not None:
            for k, v in proxy_headers.items():
                message.append(f"{k}: {v}")
        message.append("")
        message.append("")
        req: str = "\r\n".join([line.lstrip() for line in message])
        if trace_enabled:
            logger.debug(f"Proxy connect request (session id: {session_id}):\n{req}")
        with sock_send_lock:
            sock.send(req.encode("utf-8"))
        status, text = _parse_connect_response(sock)
        if trace_enabled:
            log_message = f"Proxy connect response (session id: {session_id}):\n{text}"
            logger.debug(log_message)
        if status != 200:
            raise Exception(
                f"Failed to connect to the proxy (proxy: {proxy}, connect status code: {status})"
            )

        sock = ssl.SSLContext(ssl.PROTOCOL_SSLv23).wrap_socket(
            sock,
            do_handshake_on_connect=True,
            suppress_ragged_eofs=True,
            server_hostname=server_hostname,
        )
        return sock

    if server_port != 443:
        addr = socket.getaddrinfo(
            server_hostname, server_port, 0, socket.SOCK_STREAM, socket.SOL_TCP
        )[0]
        # only for library testing
        logger.info(
            f"Using non-ssl socket to connect ({server_hostname}:{server_port})"
        )
        sock = Socket(addr[0], addr[1], addr[2])
        sock.settimeout(3)
        sock.connect((server_hostname, server_port))
        return sock

    sock = Socket(type=ssl.SOCK_STREAM)
    sock = ssl.SSLContext(ssl.PROTOCOL_SSLv23).wrap_socket(
        sock,
        do_handshake_on_connect=True,
        suppress_ragged_eofs=True,
        server_hostname=server_hostname,
    )
    sock.settimeout(receive_timeout)
    sock.connect((server_hostname, server_port))
    return sock