code: def http_connect_tunnel(
      master: str,
      service: str,
      cert_file: Union[str, bool, None],
      cert_name: Optional[str],
      authorization_token: Optional[str] = None,
  ) -> None:
      parsed_master = request.parse_master_address(master)
      assert (
          parsed_master.hostname is not None
      ), "Failed to parse master address: {}".format(master)
  
      # The "lomond.WebSocket()" function does not honor the "no_proxy" or
      # "NO_PROXY" environment variables. To work around that, we check if
      # the hostname is in the "no_proxy" or "NO_PROXY" environment variables
      # ourselves using the "proxy_bypass()" function, which checks the "no_proxy"
      # and "NO_PROXY" environment variables, and returns True if the host does
      # not require a proxy server. The "lomond.WebSocket()" function will disable
      # the proxy if the "proxies" parameter is an empty dictionary.  Otherwise,
      # if the "proxies" parameter is "None", it will honor the "HTTP_PROXY" and
      # "HTTPS_PROXY" environment variables. When the "proxies" parameter is not
      # specified, the default value is "None".
      proxies = {} if urllib.request.proxy_bypass(parsed_master.hostname) else None  # type: ignore
  
      url = request.make_url(master, "proxy/{}/".format(service))
      ws = lomond.WebSocket(
          request.maybe_upgrade_ws_scheme(url), proxies=proxies
      )
      if authorization_token is not None:
          ws.add_header(
              b"Authorization", f"Bearer {authorization_token}".encode()
          )
  
      # We can't send data to the WebSocket before the connection becomes ready, which takes a bit of
      # time; this semaphore lets the sending thread wait for that to happen.
      ready_sem = threading.Semaphore(0)
  
      # Directly using sys.stdin.buffer.read or sys.stdout.buffer.write would block due to
      # buffering; instead, we use unbuffered file objects based on the same file descriptors.
      unbuffered_stdin = os.fdopen(
          sys.stdin.fileno(), "rb", buffering=0
      )
      unbuffered_stdout = os.fdopen(
          sys.stdout.fileno(), "wb", buffering=0
      )
  
      c1 = threading.Thread(
          target=copy_to_websocket,
          args=(ws, unbuffered_stdin, ready_sem),
      )
      c2 = threading.Thread(
          target=copy_from_websocket,
          args=(unbuffered_stdout, ws, ready_sem, cert_file, cert_name),
      )
      c1.start()
      c2.start()
      c1.join()
      c2.join()
  
imports: from __future__ import annotations
  import contextlib
  import io
  import os
  import socket
  import socketserver
  import ssl
  import sys
  import threading
  import time
  import urllib.request
  from dataclasses import dataclass
  from typing import Iterator, List, Optional, Union
  import lomond
  from determined.common.api import Session, authentication, bindings, request
label_desc: Use image node_id 5 for calling a global function with example usage: http_connect_tunnel(master, service, cert_file, cert_name, authorization_token) without return types