# Path: server/websockets/exceptions.py
# class InvalidHandshake(Exception):
#     """
#     Exception raised when a handshake request or response is invalid.
# 
#     """
# 
# Path: server/websockets/handshake.py
# def build_request(set_header):
#     """
#     Build a handshake request to send to the server.
# 
#     Return the ``key`` which must be passed to :func:`check_response`.
# 
#     """
#     rand = bytes(random.getrandbits(8) for _ in range(16))
#     key = base64.b64encode(rand).decode()
#     set_header('Upgrade', 'WebSocket')
#     set_header('Connection', 'Upgrade')
#     set_header('Sec-WebSocket-Key', key)
#     set_header('Sec-WebSocket-Version', '13')
#     return key
# 
# def check_response(get_header, key):
#     """
#     Check a handshake response received from the server.
# 
#     ``key`` comes from :func:`build_request`.
# 
#     If the handshake is valid, this function returns ``None``.
# 
#     Otherwise it raises an :exc:`~websockets.exceptions.InvalidHandshake`
#     exception.
# 
#     This function doesn't verify that the response is an HTTP/1.1 or higher
#     response with a 101 status code. These controls are the responsibility of
#     the caller.
# 
#     """
#     try:
#         assert get_header('Upgrade').lower() == 'websocket'
#         assert any(
#             token.strip() == 'upgrade'
#             for token in get_header('Connection').lower().split(','))
#         assert get_header('Sec-WebSocket-Accept') == accept(key)
#     except Exception as exc:
#         raise InvalidHandshake("Invalid response") from exc
# 
# Path: server/websockets/http.py
# USER_AGENT = ' '.join((
#     'Python/{}'.format(sys.version[:3]),
#     'websockets/{}'.format(websockets_version),
# ))
# 
# @asyncio.coroutine
# def read_response(stream):
#     """
#     Read an HTTP/1.1 response from ``stream``.
# 
#     Return ``(status, headers)`` where ``status`` is a :class:`int` and
#     ``headers`` is a :class:`~email.message.Message`.
# 
#     Raise an exception if the request isn't well formatted.
# 
#     The response is assumed not to contain a body.
# 
#     """
#     status_line, headers = yield from read_message(stream)
#     version, status, reason = status_line[:-2].decode().split(None, 2)
#     if version != 'HTTP/1.1':
#         raise ValueError("Unsupported HTTP version")
#     return int(status), headers
# 
# Path: server/websockets/protocol.py
# CONNECTING, OPEN, CLOSING, CLOSED = range(4)
# class WebSocketCommonProtocol(asyncio.StreamReaderProtocol):
#     def __init__(self, *,
#                  host=None, port=None, secure=None,
#                  timeout=10, max_size=2 ** 20, max_queue=2 ** 5,
#                  loop=None, legacy_recv=False):
#     def local_address(self):
#     def remote_address(self):
#     def open(self):
#     def state_name(self):
#     def close(self, code=1000, reason=''):
#     def recv(self):
#     def send(self, data):
#     def ping(self, data=None):
#     def pong(self, data=b''):
#     def encode_data(self, data):
#     def ensure_open(self):
#     def run(self):
#     def read_message(self):
#                 def append(frame):
#                 def append(frame):
#                 def append(frame):
#                 def append(frame):
#     def read_data_frame(self, max_size):
#     def read_frame(self, max_size):
#     def write_frame(self, opcode, data=b''):
#     def close_connection(self, force=False):
#     def fail_connection(self, code=1011, reason=''):
#     def client_connected(self, reader, writer):
#     def eof_received(self):
#     def connection_lost(self, exc):
# 
# Path: server/websockets/uri.py
# def parse_uri(uri):
#     """
#     This function parses and validates a WebSocket URI.
# 
#     If the URI is valid, it returns a :class:`WebSocketURI`.
# 
#     Otherwise it raises an :exc:`~websockets.exceptions.InvalidURI` exception.
# 
#     """
#     uri = urllib.parse.urlparse(uri)
#     try:
#         assert uri.scheme in ('ws', 'wss')
#         assert uri.params == ''
#         assert uri.fragment == ''
#         assert uri.username is None
#         assert uri.password is None
#         assert uri.hostname is not None
#     except AssertionError as exc:
#         raise InvalidURI() from exc
# 
#     secure = uri.scheme == 'wss'
#     host = uri.hostname
#     port = uri.port or (443 if secure else 80)
#     resource_name = uri.path or '/'
#     if uri.query:
#         resource_name += '?' + uri.query
#     return WebSocketURI(secure, host, port, resource_name)


import asyncio
import collections.abc
import email.message
from .exceptions import InvalidHandshake
from .handshake import build_request, check_response
from .http import USER_AGENT, read_response
from .protocol import CONNECTING, OPEN, WebSocketCommonProtocol
from .uri import parse_uri
    from .py35.client import Connect
        self.raw_request_headers = headers

        # Send handshake request. Since the URI and the headers only contain
        # ASCII characters, we can keep this simple.
        request = ['GET %s HTTP/1.1' % wsuri.resource_name]
        request.extend('{}: {}'.format(k, v) for k, v in headers)
        request.append('\r\n')
        request = '\r\n'.join(request).encode()
        self.writer.write(request)

        # Read handshake response.
        try:
            status_code, headers = yield from read_response(self.reader)
        except ValueError as exc:
            raise InvalidHandshake("Malformed HTTP message") from exc
        if status_code != 101:
            raise InvalidHandshake("Bad status code: {}".format(status_code))

        self.response_headers = headers
        self.raw_response_headers = list(headers.raw_items())

        get_header = lambda k: headers.get(k, '')
        check_response(get_header, key)

        self.subprotocol = headers.get('Sec-WebSocket-Protocol', None)
        if (self.subprotocol is not None and
                self.subprotocol not in subprotocols):
            raise InvalidHandshake(
                "Unknown subprotocol: {}".format(self.subprotocol))


# Path: server/websockets/exceptions.py
# class InvalidHandshake(Exception):
#     """
#     Exception raised when a handshake request or response is invalid.
# 
#     """
# 
# Path: server/websockets/handshake.py
# def build_request(set_header):
#     """
#     Build a handshake request to send to the server.
# 
#     Return the ``key`` which must be passed to :func:`check_response`.
# 
#     """
#     rand = bytes(random.getrandbits(8) for _ in range(16))
#     key = base64.b64encode(rand).decode()
#     set_header('Upgrade', 'WebSocket')
#     set_header('Connection', 'Upgrade')
#     set_header('Sec-WebSocket-Key', key)
#     set_header('Sec-WebSocket-Version', '13')
#     return key
# 
# def check_response(get_header, key):
#     """
#     Check a handshake response received from the server.
# 
#     ``key`` comes from :func:`build_request`.
# 
#     If the handshake is valid, this function returns ``None``.
# 
#     Otherwise it raises an :exc:`~websockets.exceptions.InvalidHandshake`
#     exception.
# 
#     This function doesn't verify that the response is an HTTP/1.1 or higher
#     response with a 101 status code. These controls are the responsibility of
#     the caller.
# 
#     """
#     try:
#         assert get_header('Upgrade').lower() == 'websocket'
#         assert any(
#             token.strip() == 'upgrade'
#             for token in get_header('Connection').lower().split(','))
#         assert get_header('Sec-WebSocket-Accept') == accept(key)
#     except Exception as exc:
#         raise InvalidHandshake("Invalid response") from exc
# 
# Path: server/websockets/http.py
# USER_AGENT = ' '.join((
#     'Python/{}'.format(sys.version[:3]),
#     'websockets/{}'.format(websockets_version),
# ))
# 
# @asyncio.coroutine
# def read_response(stream):
#     """
#     Read an HTTP/1.1 response from ``stream``.
# 
#     Return ``(status, headers)`` where ``status`` is a :class:`int` and
#     ``headers`` is a :class:`~email.message.Message`.
# 
#     Raise an exception if the request isn't well formatted.
# 
#     The response is assumed not to contain a body.
# 
#     """
#     status_line, headers = yield from read_message(stream)
#     version, status, reason = status_line[:-2].decode().split(None, 2)
#     if version != 'HTTP/1.1':
#         raise ValueError("Unsupported HTTP version")
#     return int(status), headers
# 
# Path: server/websockets/protocol.py
# CONNECTING, OPEN, CLOSING, CLOSED = range(4)
# class WebSocketCommonProtocol(asyncio.StreamReaderProtocol):
#     def __init__(self, *,
#                  host=None, port=None, secure=None,
#                  timeout=10, max_size=2 ** 20, max_queue=2 ** 5,
#                  loop=None, legacy_recv=False):
#     def local_address(self):
#     def remote_address(self):
#     def open(self):
#     def state_name(self):
#     def close(self, code=1000, reason=''):
#     def recv(self):
#     def send(self, data):
#     def ping(self, data=None):
#     def pong(self, data=b''):
#     def encode_data(self, data):
#     def ensure_open(self):
#     def run(self):
#     def read_message(self):
#                 def append(frame):
#                 def append(frame):
#                 def append(frame):
#                 def append(frame):
#     def read_data_frame(self, max_size):
#     def read_frame(self, max_size):
#     def write_frame(self, opcode, data=b''):
#     def close_connection(self, force=False):
#     def fail_connection(self, code=1011, reason=''):
#     def client_connected(self, reader, writer):
#     def eof_received(self):
#     def connection_lost(self, exc):
# 
# Path: server/websockets/uri.py
# def parse_uri(uri):
#     """
#     This function parses and validates a WebSocket URI.
# 
#     If the URI is valid, it returns a :class:`WebSocketURI`.
# 
#     Otherwise it raises an :exc:`~websockets.exceptions.InvalidURI` exception.
# 
#     """
#     uri = urllib.parse.urlparse(uri)
#     try:
#         assert uri.scheme in ('ws', 'wss')
#         assert uri.params == ''
#         assert uri.fragment == ''
#         assert uri.username is None
#         assert uri.password is None
#         assert uri.hostname is not None
#     except AssertionError as exc:
#         raise InvalidURI() from exc
# 
#     secure = uri.scheme == 'wss'
#     host = uri.hostname
#     port = uri.port or (443 if secure else 80)
#     resource_name = uri.path or '/'
#     if uri.query:
#         resource_name += '?' + uri.query
#     return WebSocketURI(secure, host, port, resource_name)


# Path: server/websockets/client.py
import asyncio
import collections.abc
import email.message
from .exceptions import InvalidHandshake
from .handshake import build_request, check_response
from .http import USER_AGENT, read_response
from .protocol import CONNECTING, OPEN, WebSocketCommonProtocol
from .uri import parse_uri
    from .py35.client import Connect

        self.raw_request_headers = headers

        # Send handshake request. Since the URI and the headers only contain
        # ASCII characters, we can keep this simple.
        request = ['GET %s HTTP/1.1' % wsuri.resource_name]
        request.extend('{}: {}'.format(k, v) for k, v in headers)
        request.append('\r\n')
        request = '\r\n'.join(request).encode()
        self.writer.write(request)

        # Read handshake response.
        try:
            status_code, headers = yield from read_response(self.reader)
        except ValueError as exc:
            raise InvalidHandshake("Malformed HTTP message") from exc
        if status_code != 101:
            raise InvalidHandshake("Bad status code: {}".format(status_code))

        self.response_headers = headers
        self.raw_response_headers = list(headers.raw_items())

        get_header = lambda k: headers.get(k, '')
        check_response(get_header, key)

        self.subprotocol = headers.get('Sec-WebSocket-Protocol', None)
        if (self.subprotocol is not None and
                self.subprotocol not in subprotocols):
            raise InvalidHandshake(
                "Unknown subprotocol: {}".format(self.subprotocol))


        assert self.state == CONNECTING