# Path: server/websockets/compatibility.py

# 
# Path: server/websockets/exceptions.py
# class InvalidHandshake(Exception):
#     """
#     Exception raised when a handshake request or response is invalid.
# 
#     """
# 
# class InvalidOrigin(InvalidHandshake):
#     """
#     Exception raised when the origin in a handshake request is forbidden.
# 
#     """
# 
# Path: server/websockets/handshake.py
# def build_response(set_header, key):
#     """
#     Build a handshake response to send to the client.
# 
#     ``key`` comes from :func:`check_request`.
# 
#     """
#     set_header('Upgrade', 'WebSocket')
#     set_header('Connection', 'Upgrade')
#     set_header('Sec-WebSocket-Accept', accept(key))
# 
# def check_request(get_header):
#     """
#     Check a handshake request received from the client.
# 
#     If the handshake is valid, this function returns the ``key`` which must be
#     passed to :func:`build_response`.
# 
#     Otherwise it raises an :exc:`~websockets.exceptions.InvalidHandshake`
#     exception and the server must return an error like 400 Bad Request.
# 
#     This function doesn't verify that the request is an HTTP/1.1 or higher GET
#     request and doesn't perform Host and Origin checks. These controls are
#     usually performed earlier in the HTTP request handling code. They're 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(','))
#         key = get_header('Sec-WebSocket-Key')
#         assert len(base64.b64decode(key.encode(), validate=True)) == 16
#         assert get_header('Sec-WebSocket-Version') == '13'
#     except Exception as exc:
#         raise InvalidHandshake("Invalid request") from exc
#     else:
#         return key
# 
# Path: server/websockets/http.py
# USER_AGENT = ' '.join((
#     'Python/{}'.format(sys.version[:3]),
#     'websockets/{}'.format(websockets_version),
# ))
# 
# @asyncio.coroutine
# def read_request(stream):
#     """
#     Read an HTTP/1.1 request from ``stream``.
# 
#     Return ``(path, headers)`` where ``path`` is a :class:`str` and
#     ``headers`` is a :class:`~email.message.Message`. ``path`` isn't
#     URL-decoded.
# 
#     Raise an exception if the request isn't well formatted.
# 
#     The request is assumed not to contain a body.
# 
#     """
#     request_line, headers = yield from read_message(stream)
#     method, path, version = request_line[:-2].decode().split(None, 2)
#     if method != 'GET':
#         raise ValueError("Unsupported method")
#     if version != 'HTTP/1.1':
#         raise ValueError("Unsupported HTTP version")
#     return path, 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):


import asyncio
import collections.abc
import email.message
import logging
from .compatibility import asyncio_ensure_future
from .exceptions import InvalidHandshake, InvalidOrigin
from .handshake import build_response, check_request
from .http import USER_AGENT, read_request
from .protocol import CONNECTING, OPEN, WebSocketCommonProtocol
        Decide whether an exception means that the server is shutting down.

        """
        return (
            isinstance(exc, asyncio.CancelledError) and
            self.ws_server.closing
        )

    @asyncio.coroutine
    def handshake(self, origins=None, subprotocols=None, extra_headers=None):
        """
        Perform the server side of the opening handshake.

        If provided, ``origins`` is a list of acceptable HTTP Origin values.
        Include ``''`` if the lack of an origin is acceptable.

        If provided, ``subprotocols`` is a list of supported subprotocols in
        order of decreasing preference.

        If provided, ``extra_headers`` sets additional HTTP response headers.
        It can be a mapping or an iterable of (name, value) pairs. It can also
        be a callable taking the request path and headers in arguments.

        Return the URI of the request.

        """
        # Read handshake request.
        try:
            path, headers = yield from read_request(self.reader)
        except ValueError as exc:

# Path: server/websockets/compatibility.py

# 
# Path: server/websockets/exceptions.py
# class InvalidHandshake(Exception):
#     """
#     Exception raised when a handshake request or response is invalid.
# 
#     """
# 
# class InvalidOrigin(InvalidHandshake):
#     """
#     Exception raised when the origin in a handshake request is forbidden.
# 
#     """
# 
# Path: server/websockets/handshake.py
# def build_response(set_header, key):
#     """
#     Build a handshake response to send to the client.
# 
#     ``key`` comes from :func:`check_request`.
# 
#     """
#     set_header('Upgrade', 'WebSocket')
#     set_header('Connection', 'Upgrade')
#     set_header('Sec-WebSocket-Accept', accept(key))
# 
# def check_request(get_header):
#     """
#     Check a handshake request received from the client.
# 
#     If the handshake is valid, this function returns the ``key`` which must be
#     passed to :func:`build_response`.
# 
#     Otherwise it raises an :exc:`~websockets.exceptions.InvalidHandshake`
#     exception and the server must return an error like 400 Bad Request.
# 
#     This function doesn't verify that the request is an HTTP/1.1 or higher GET
#     request and doesn't perform Host and Origin checks. These controls are
#     usually performed earlier in the HTTP request handling code. They're 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(','))
#         key = get_header('Sec-WebSocket-Key')
#         assert len(base64.b64decode(key.encode(), validate=True)) == 16
#         assert get_header('Sec-WebSocket-Version') == '13'
#     except Exception as exc:
#         raise InvalidHandshake("Invalid request") from exc
#     else:
#         return key
# 
# Path: server/websockets/http.py
# USER_AGENT = ' '.join((
#     'Python/{}'.format(sys.version[:3]),
#     'websockets/{}'.format(websockets_version),
# ))
# 
# @asyncio.coroutine
# def read_request(stream):
#     """
#     Read an HTTP/1.1 request from ``stream``.
# 
#     Return ``(path, headers)`` where ``path`` is a :class:`str` and
#     ``headers`` is a :class:`~email.message.Message`. ``path`` isn't
#     URL-decoded.
# 
#     Raise an exception if the request isn't well formatted.
# 
#     The request is assumed not to contain a body.
# 
#     """
#     request_line, headers = yield from read_message(stream)
#     method, path, version = request_line[:-2].decode().split(None, 2)
#     if method != 'GET':
#         raise ValueError("Unsupported method")
#     if version != 'HTTP/1.1':
#         raise ValueError("Unsupported HTTP version")
#     return path, 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/server.py
import asyncio
import collections.abc
import email.message
import logging
from .compatibility import asyncio_ensure_future
from .exceptions import InvalidHandshake, InvalidOrigin
from .handshake import build_response, check_request
from .http import USER_AGENT, read_request
from .protocol import CONNECTING, OPEN, WebSocketCommonProtocol

        Decide whether an exception means that the server is shutting down.

        """
        return (
            isinstance(exc, asyncio.CancelledError) and
            self.ws_server.closing
        )

    @asyncio.coroutine
    def handshake(self, origins=None, subprotocols=None, extra_headers=None):
        """
        Perform the server side of the opening handshake.

        If provided, ``origins`` is a list of acceptable HTTP Origin values.
        Include ``''`` if the lack of an origin is acceptable.

        If provided, ``subprotocols`` is a list of supported subprotocols in
        order of decreasing preference.

        If provided, ``extra_headers`` sets additional HTTP response headers.
        It can be a mapping or an iterable of (name, value) pairs. It can also
        be a callable taking the request path and headers in arguments.

        Return the URI of the request.

        """
        # Read handshake request.
        try:
            path, headers = yield from read_request(self.reader)
        except ValueError as exc:

            raise InvalidHandshake("Malformed HTTP message") from exc