Esempio n. 1
0
def _check_header_lines(request, mandatory_headers):
    check_request_line(request)

    # The expected field names, and the meaning of their corresponding
    # values, are as follows.
    #  |Upgrade| and |Connection|
    for key, expected_value in mandatory_headers:
        validate_mandatory_header(request, key, expected_value)
def _check_header_lines(request, mandatory_headers):
    check_request_line(request)

    # The expected field names, and the meaning of their corresponding
    # values, are as follows.
    #  |Upgrade| and |Connection|
    for key, expected_value in mandatory_headers:
        validate_mandatory_header(request, key, expected_value)
Esempio n. 3
0
    def do_handshake(self):
        check_request_line(self._request)

        validate_mandatory_header(self._request, common.UPGRADE_HEADER,
                                  common.WEBSOCKET_UPGRADE_TYPE)

        connection = get_mandatory_header(self._request,
                                          common.CONNECTION_HEADER)

        try:
            connection_tokens = parse_token_list(connection)
        except HandshakeError, e:
            raise HandshakeError('Failed to parse %s: %s' %
                                 (common.CONNECTION_HEADER, e))
Esempio n. 4
0
    def do_handshake(self):
        check_request_line(self._request)

        validate_mandatory_header(
            self._request,
            common.UPGRADE_HEADER,
            common.WEBSOCKET_UPGRADE_TYPE)

        connection = get_mandatory_header(
            self._request, common.CONNECTION_HEADER)

        try:
            connection_tokens = parse_token_list(connection)
        except HandshakeError, e:
            raise HandshakeError(
                'Failed to parse %s: %s' % (common.CONNECTION_HEADER, e))
Esempio n. 5
0
    def do_handshake(self):
        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        # Parsing.

        check_request_line(self._request)

        validate_mandatory_header(
            self._request,
            common.UPGRADE_HEADER,
            common.WEBSOCKET_UPGRADE_TYPE)

        self._validate_connection_header()

        self._request.ws_resource = self._request.uri

        unused_host = get_mandatory_header(self._request, common.HOST_HEADER)

        self._request.ws_version = self._check_version()

        # This handshake must be based on latest hybi. We are responsible to
        # fallback to HTTP on handshake failure as latest hybi handshake
        # specifies.
        try:
            self._get_origin()
            self._set_protocol()
            self._parse_extensions()

            # Key validation, response generation.

            key = self._get_key()
            (accept, accept_binary) = compute_accept(key)
            self._logger.debug(
                '%s: %r (%s)',
                common.SEC_WEBSOCKET_ACCEPT_HEADER,
                accept,
                util.hexify(accept_binary))

            self._logger.debug('Protocol version is RFC 6455')

            # Setup extension processors.

            processors = []
            if self._request.ws_requested_extensions is not None:
                for extension_request in self._request.ws_requested_extensions:
                    processor = get_extension_processor(extension_request)
                    # Unknown extension requests are just ignored.
                    if processor is not None:
                        processors.append(processor)
            self._request.ws_extension_processors = processors

            # Extra handshake handler may modify/remove processors.
            self._dispatcher.do_extra_handshake(self._request)

            stream_options = StreamOptions()

            self._request.ws_extensions = None
            for processor in self._request.ws_extension_processors:
                if processor is None:
                    # Some processors may be removed by extra handshake
                    # handler.
                    continue

                extension_response = processor.get_extension_response()
                if extension_response is None:
                    # Rejected.
                    continue

                if self._request.ws_extensions is None:
                    self._request.ws_extensions = []
                self._request.ws_extensions.append(extension_response)

                processor.setup_stream_options(stream_options)

            if self._request.ws_extensions is not None:
                self._logger.debug(
                    'Extensions accepted: %r',
                    map(common.ExtensionParameter.name,
                        self._request.ws_extensions))

            self._request.ws_stream = Stream(self._request, stream_options)

            if self._request.ws_requested_protocols is not None:
                if self._request.ws_protocol is None:
                    raise HandshakeException(
                        'do_extra_handshake must choose one subprotocol from '
                        'ws_requested_protocols and set it to ws_protocol')
                validate_subprotocol(self._request.ws_protocol, hixie=False)

                self._logger.debug(
                    'Subprotocol accepted: %r',
                    self._request.ws_protocol)
            else:
                if self._request.ws_protocol is not None:
                    raise HandshakeException(
                        'ws_protocol must be None when the client didn\'t '
                        'request any subprotocol')

            self._send_handshake(accept)
        except HandshakeException, e:
            if not e.status:
                # Fallback to 400 bad request by default.
                e.status = common.HTTP_STATUS_BAD_REQUEST
            raise e
Esempio n. 6
0
    def do_handshake(self):
        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        # Parsing.

        check_connect_method(self._request)

        validate_mandatory_header(self._request, ':protocol', 'websocket')

        self._request.ws_resource = self._request.uri

        get_mandatory_header(self._request, 'authority')

        self._request.ws_version = self._check_version()

        try:
            self._get_origin()
            self._set_protocol()
            self._parse_extensions()

            # Setup extension processors.
            self._request.ws_extension_processors = self._get_extension_processors_requested()

            # List of extra headers. The extra handshake handler may add header
            # data as name/value pairs to this list and pywebsocket appends
            # them to the WebSocket handshake.
            self._request.extra_headers = []

            # Extra handshake handler may modify/remove processors.
            self._dispatcher.do_extra_handshake(self._request)
            processors = [
                processor
                for processor in self._request.ws_extension_processors
                if processor is not None
            ]

            # Ask each processor if there are extensions on the request which
            # cannot co-exist. When processor decided other processors cannot
            # co-exist with it, the processor marks them (or itself) as
            # "inactive". The first extension processor has the right to
            # make the final call.
            for processor in reversed(processors):
                if processor.is_active():
                    processor.check_consistency_with_other_processors(
                        processors)
            processors = [
                processor for processor in processors if processor.is_active()
            ]

            accepted_extensions = []

            stream_options = StreamOptions()

            for index, processor in enumerate(processors):
                if not processor.is_active():
                    continue

                extension_response = processor.get_extension_response()
                if extension_response is None:
                    # Rejected.
                    continue

                accepted_extensions.append(extension_response)

                processor.setup_stream_options(stream_options)

                # Inactivate all of the following compression extensions.
                for j in range(index + 1, len(processors)):
                    processors[j].set_active(False)

            if len(accepted_extensions) > 0:
                self._request.ws_extensions = accepted_extensions
                self._logger.debug(
                    'Extensions accepted: %r',
                    list(
                        map(common.ExtensionParameter.name,
                            accepted_extensions)))
            else:
                self._request.ws_extensions = None

            self._request.ws_stream = self._create_stream(stream_options)

            if self._request.ws_requested_protocols is not None:
                if self._request.ws_protocol is None:
                    raise HandshakeException(
                        'do_extra_handshake must choose one subprotocol from '
                        'ws_requested_protocols and set it to ws_protocol')
                validate_subprotocol(self._request.ws_protocol)

                self._logger.debug('Subprotocol accepted: %r',
                                   self._request.ws_protocol)
            else:
                if self._request.ws_protocol is not None:
                    raise HandshakeException(
                        'ws_protocol must be None when the client didn\'t '
                        'request any subprotocol')

            self._prepare_handshake_response()
        except HandshakeException as e:
            if not e.status:
                # Fallback to 400 bad request by default.
                e.status = common.HTTP_STATUS_BAD_REQUEST
            raise e
Esempio n. 7
0
    def do_handshake(self):
        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        # Parsing.

        check_request_line(self._request)

        validate_mandatory_header(
            self._request,
            common.UPGRADE_HEADER,
            common.WEBSOCKET_UPGRADE_TYPE)

        self._validate_connection_header()

        self._request.ws_resource = self._request.uri

        unused_host = get_mandatory_header(self._request, common.HOST_HEADER)

        self._request.ws_version = self._check_version()

        # This handshake must be based on latest hybi. We are responsible to
        # fallback to HTTP on handshake failure as latest hybi handshake
        # specifies.
        try:
            self._get_origin()
            self._set_protocol()
            self._parse_extensions()

            # Key validation, response generation.

            key = self._get_key()
            (accept, accept_binary) = compute_accept(key)
            self._logger.debug(
                '%s: %r (%s)',
                common.SEC_WEBSOCKET_ACCEPT_HEADER,
                accept,
                util.hexify(accept_binary))

            self._logger.debug('Protocol version is RFC 6455')

            # Setup extension processors.

            processors = []
            if self._request.ws_requested_extensions is not None:
                for extension_request in self._request.ws_requested_extensions:
                    processor = get_extension_processor(extension_request)
                    # Unknown extension requests are just ignored.
                    if processor is not None:
                        processors.append(processor)
            self._request.ws_extension_processors = processors

            # List of extra headers. The extra handshake handler may add header
            # data as name/value pairs to this list and pywebsocket appends
            # them to the WebSocket handshake.
            self._request.extra_headers = []

            # Extra handshake handler may modify/remove processors.
            self._dispatcher.do_extra_handshake(self._request)
            processors = filter(lambda processor: processor is not None,
                                self._request.ws_extension_processors)

            # Ask each processor if there are extensions on the request which
            # cannot co-exist. When processor decided other processors cannot
            # co-exist with it, the processor marks them (or itself) as
            # "inactive". The first extension processor has the right to
            # make the final call.
            for processor in reversed(processors):
                if processor.is_active():
                    processor.check_consistency_with_other_processors(
                        processors)
            processors = filter(lambda processor: processor.is_active(),
                                processors)

            accepted_extensions = []

            # We need to take into account of mux extension here.
            # If mux extension exists:
            # - Remove processors of extensions for logical channel,
            #   which are processors located before the mux processor
            # - Pass extension requests for logical channel to mux processor
            # - Attach the mux processor to the request. It will be referred
            #   by dispatcher to see whether the dispatcher should use mux
            #   handler or not.
            mux_index = -1
            for i, processor in enumerate(processors):
                if processor.name() == common.MUX_EXTENSION:
                    mux_index = i
                    break
            if mux_index >= 0:
                logical_channel_extensions = []
                for processor in processors[:mux_index]:
                    logical_channel_extensions.append(processor.request())
                    processor.set_active(False)
                self._request.mux_processor = processors[mux_index]
                self._request.mux_processor.set_extensions(
                    logical_channel_extensions)
                processors = filter(lambda processor: processor.is_active(),
                                    processors)

            stream_options = StreamOptions()

            for processor in processors:
                extension_response = processor.get_extension_response()
                if extension_response is None:
                    # Rejected.
                    continue

                accepted_extensions.append(extension_response)

                processor.setup_stream_options(stream_options)

            if len(accepted_extensions) > 0:
                self._request.ws_extensions = accepted_extensions
                self._logger.debug(
                    'Extensions accepted: %r',
                    map(common.ExtensionParameter.name, accepted_extensions))
            else:
                self._request.ws_extensions = None

            self._request.ws_stream = self._create_stream(stream_options)

            if self._request.ws_requested_protocols is not None:
                if self._request.ws_protocol is None:
                    raise HandshakeException(
                        'do_extra_handshake must choose one subprotocol from '
                        'ws_requested_protocols and set it to ws_protocol')
                validate_subprotocol(self._request.ws_protocol)

                self._logger.debug(
                    'Subprotocol accepted: %r',
                    self._request.ws_protocol)
            else:
                if self._request.ws_protocol is not None:
                    raise HandshakeException(
                        'ws_protocol must be None when the client didn\'t '
                        'request any subprotocol')

            self._send_handshake(accept)
        except HandshakeException, e:
            if not e.status:
                # Fallback to 400 bad request by default.
                e.status = common.HTTP_STATUS_BAD_REQUEST
            raise e
Esempio n. 8
0
 def _check_version(self):
     unused_value = validate_mandatory_header(
         self._request, common.SEC_WEBSOCKET_VERSION_HEADER, '8')
Esempio n. 9
0
    def do_handshake(self):
        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        # Parsing.

        check_request_line(self._request)

        validate_mandatory_header(self._request, common.UPGRADE_HEADER,
                                  common.WEBSOCKET_UPGRADE_TYPE)

        self._validate_connection_header()

        self._request.ws_resource = self._request.uri

        unused_host = get_mandatory_header(self._request, common.HOST_HEADER)

        self._request.ws_version = self._check_version()

        try:
            self._get_origin()
            self._set_protocol()
            self._parse_extensions()

            # Key validation, response generation.

            key = self._get_key()
            accept = compute_accept(key)
            self._logger.debug('%s: %r (%s)',
                               common.SEC_WEBSOCKET_ACCEPT_HEADER, accept,
                               util.hexify(base64.b64decode(accept)))

            self._logger.debug('Protocol version is RFC 6455')

            # Setup extension processors.

            processors = []
            if self._request.ws_requested_extensions is not None:
                for extension_request in self._request.ws_requested_extensions:
                    processor = get_extension_processor(extension_request)
                    # Unknown extension requests are just ignored.
                    if processor is not None:
                        processors.append(processor)
            self._request.ws_extension_processors = processors

            # List of extra headers. The extra handshake handler may add header
            # data as name/value pairs to this list and pywebsocket appends
            # them to the WebSocket handshake.
            self._request.extra_headers = []

            # Extra handshake handler may modify/remove processors.
            self._dispatcher.do_extra_handshake(self._request)
            processors = [
                processor
                for processor in self._request.ws_extension_processors
                if processor is not None
            ]

            # Ask each processor if there are extensions on the request which
            # cannot co-exist. When processor decided other processors cannot
            # co-exist with it, the processor marks them (or itself) as
            # "inactive". The first extension processor has the right to
            # make the final call.
            for processor in reversed(processors):
                if processor.is_active():
                    processor.check_consistency_with_other_processors(
                        processors)
            processors = [
                processor for processor in processors if processor.is_active()
            ]

            accepted_extensions = []

            stream_options = StreamOptions()

            for index, processor in enumerate(processors):
                if not processor.is_active():
                    continue

                extension_response = processor.get_extension_response()
                if extension_response is None:
                    # Rejected.
                    continue

                accepted_extensions.append(extension_response)

                processor.setup_stream_options(stream_options)

                # Inactivate all of the following compression extensions.
                for j in range(index + 1, len(processors)):
                    processors[j].set_active(False)

            if len(accepted_extensions) > 0:
                self._request.ws_extensions = accepted_extensions
                self._logger.debug(
                    'Extensions accepted: %r',
                    list(
                        map(common.ExtensionParameter.name,
                            accepted_extensions)))
            else:
                self._request.ws_extensions = None

            self._request.ws_stream = self._create_stream(stream_options)

            if self._request.ws_requested_protocols is not None:
                if self._request.ws_protocol is None:
                    raise HandshakeException(
                        'do_extra_handshake must choose one subprotocol from '
                        'ws_requested_protocols and set it to ws_protocol')
                validate_subprotocol(self._request.ws_protocol)

                self._logger.debug('Subprotocol accepted: %r',
                                   self._request.ws_protocol)
            else:
                if self._request.ws_protocol is not None:
                    raise HandshakeException(
                        'ws_protocol must be None when the client didn\'t '
                        'request any subprotocol')

            self._send_handshake(accept)
        except HandshakeException as e:
            if not e.status:
                # Fallback to 400 bad request by default.
                e.status = common.HTTP_STATUS_BAD_REQUEST
            raise e
Esempio n. 10
0
File: hybi.py Progetto: GhostQ/GitSB
    def do_handshake(self):
        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        # Parsing.

        check_request_line(self._request)

        validate_mandatory_header(self._request, common.UPGRADE_HEADER,
                                  common.WEBSOCKET_UPGRADE_TYPE)

        self._validate_connection_header()

        self._request.ws_resource = self._request.uri

        unused_host = get_mandatory_header(self._request, common.HOST_HEADER)

        self._request.ws_version = self._check_version()

        # This handshake must be based on latest hybi. We are responsible to
        # fallback to HTTP on handshake failure as latest hybi handshake
        # specifies.
        try:
            self._get_origin()
            self._set_protocol()
            self._parse_extensions()

            # Key validation, response generation.

            key = self._get_key()
            (accept, accept_binary) = compute_accept(key)
            self._logger.debug('%s: %r (%s)',
                               common.SEC_WEBSOCKET_ACCEPT_HEADER, accept,
                               util.hexify(accept_binary))

            self._logger.debug('Protocol version is RFC 6455')

            # Setup extension processors.

            processors = []
            if self._request.ws_requested_extensions is not None:
                for extension_request in self._request.ws_requested_extensions:
                    processor = get_extension_processor(extension_request)
                    # Unknown extension requests are just ignored.
                    if processor is not None:
                        processors.append(processor)
            self._request.ws_extension_processors = processors

            # List of extra headers. The extra handshake handler may add header
            # data as name/value pairs to this list and pywebsocket appends
            # them to the WebSocket handshake.
            self._request.extra_headers = []

            # Extra handshake handler may modify/remove processors.
            self._dispatcher.do_extra_handshake(self._request)
            processors = filter(lambda processor: processor is not None,
                                self._request.ws_extension_processors)

            # Ask each processor if there are extensions on the request which
            # cannot co-exist. When processor decided other processors cannot
            # co-exist with it, the processor marks them (or itself) as
            # "inactive". The first extension processor has the right to
            # make the final call.
            for processor in reversed(processors):
                if processor.is_active():
                    processor.check_consistency_with_other_processors(
                        processors)
            processors = filter(lambda processor: processor.is_active(),
                                processors)

            accepted_extensions = []

            # We need to take into account of mux extension here.
            # If mux extension exists:
            # - Remove processors of extensions for logical channel,
            #   which are processors located before the mux processor
            # - Pass extension requests for logical channel to mux processor
            # - Attach the mux processor to the request. It will be referred
            #   by dispatcher to see whether the dispatcher should use mux
            #   handler or not.
            mux_index = -1
            for i, processor in enumerate(processors):
                if processor.name() == common.MUX_EXTENSION:
                    mux_index = i
                    break
            if mux_index >= 0:
                logical_channel_extensions = []
                for processor in processors[:mux_index]:
                    logical_channel_extensions.append(processor.request())
                    processor.set_active(False)
                self._request.mux_processor = processors[mux_index]
                self._request.mux_processor.set_extensions(
                    logical_channel_extensions)
                processors = filter(lambda processor: processor.is_active(),
                                    processors)

            stream_options = StreamOptions()

            for index, processor in enumerate(processors):
                if not processor.is_active():
                    continue

                extension_response = processor.get_extension_response()
                if extension_response is None:
                    # Rejected.
                    continue

                accepted_extensions.append(extension_response)

                processor.setup_stream_options(stream_options)

                if not is_compression_extension(processor.name()):
                    continue

                # Inactivate all of the following compression extensions.
                for j in xrange(index + 1, len(processors)):
                    if is_compression_extension(processors[j].name()):
                        processors[j].set_active(False)

            if len(accepted_extensions) > 0:
                self._request.ws_extensions = accepted_extensions
                self._logger.debug(
                    'Extensions accepted: %r',
                    map(common.ExtensionParameter.name, accepted_extensions))
            else:
                self._request.ws_extensions = None

            self._request.ws_stream = self._create_stream(stream_options)

            if self._request.ws_requested_protocols is not None:
                if self._request.ws_protocol is None:
                    raise HandshakeException(
                        'do_extra_handshake must choose one subprotocol from '
                        'ws_requested_protocols and set it to ws_protocol')
                validate_subprotocol(self._request.ws_protocol)

                self._logger.debug('Subprotocol accepted: %r',
                                   self._request.ws_protocol)
            else:
                if self._request.ws_protocol is not None:
                    raise HandshakeException(
                        'ws_protocol must be None when the client didn\'t '
                        'request any subprotocol')

            self._send_handshake(accept)
        except HandshakeException, e:
            if not e.status:
                # Fallback to 400 bad request by default.
                e.status = common.HTTP_STATUS_BAD_REQUEST
            raise e
Esempio n. 11
0
    def do_handshake(self):
        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        # Parsing.

        check_request_line(self._request)

        validate_mandatory_header(self._request, common.UPGRADE_HEADER,
                                  common.WEBSOCKET_UPGRADE_TYPE)

        self._validate_connection_header()

        self._request.ws_resource = self._request.uri

        unused_host = get_mandatory_header(self._request, common.HOST_HEADER)

        self._request.ws_version = self._check_version()

        # This handshake must be based on latest hybi. We are responsible to
        # fallback to HTTP on handshake failure as latest hybi handshake
        # specifies.
        try:
            self._get_origin()
            self._set_protocol()
            self._parse_extensions()

            # Key validation, response generation.

            key = self._get_key()
            (accept, accept_binary) = compute_accept(key)
            self._logger.debug('%s: %r (%s)',
                               common.SEC_WEBSOCKET_ACCEPT_HEADER, accept,
                               util.hexify(accept_binary))

            self._logger.debug('IETF HyBi protocol')

            # Setup extension processors.

            processors = []
            if self._request.ws_requested_extensions is not None:
                for extension_request in self._request.ws_requested_extensions:
                    processor = get_extension_processor(extension_request)
                    # Unknown extension requests are just ignored.
                    if processor is not None:
                        processors.append(processor)
            self._request.ws_extension_processors = processors

            # Extra handshake handler may modify/remove processors.
            self._dispatcher.do_extra_handshake(self._request)

            stream_options = StreamOptions()

            self._request.ws_extensions = None
            for processor in self._request.ws_extension_processors:
                if processor is None:
                    # Some processors may be removed by extra handshake
                    # handler.
                    continue

                extension_response = processor.get_extension_response()
                if extension_response is None:
                    # Rejected.
                    continue

                if self._request.ws_extensions is None:
                    self._request.ws_extensions = []
                self._request.ws_extensions.append(extension_response)

                processor.setup_stream_options(stream_options)

            if self._request.ws_extensions is not None:
                self._logger.debug(
                    'Extensions accepted: %r',
                    map(common.ExtensionParameter.name,
                        self._request.ws_extensions))

            self._request.ws_stream = Stream(self._request, stream_options)

            if self._request.ws_requested_protocols is not None:
                if self._request.ws_protocol is None:
                    raise HandshakeException(
                        'do_extra_handshake must choose one subprotocol from '
                        'ws_requested_protocols and set it to ws_protocol')
                validate_subprotocol(self._request.ws_protocol, hixie=False)

                self._logger.debug('Subprotocol accepted: %r',
                                   self._request.ws_protocol)
            else:
                if self._request.ws_protocol is not None:
                    raise HandshakeException(
                        'ws_protocol must be None when the client didn\'t '
                        'request any subprotocol')

            self._send_handshake(accept)
        except HandshakeException, e:
            if not e.status:
                # Fallback to 400 bad request by default.
                e.status = common.HTTP_STATUS_BAD_REQUEST
            raise e
Esempio n. 12
0
 def _check_version(self):
     unused_value = validate_mandatory_header(
         self._request, common.SEC_WEBSOCKET_VERSION_HEADER, '8')
Esempio n. 13
0
    def do_handshake(self):
        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        # Parsing.

        check_request_line(self._request)

        validate_mandatory_header(
            self._request,
            common.UPGRADE_HEADER,
            common.WEBSOCKET_UPGRADE_TYPE)

        self._validate_connection_header()

        self._request.ws_resource = self._request.uri

        unused_host = get_mandatory_header(self._request, common.HOST_HEADER)

        self._request.ws_version = self._check_version()

        # This handshake must be based on latest hybi. We are responsible to
        # fallback to HTTP on handshake failure as latest hybi handshake
        # specifies.
        try:
            self._get_origin()
            self._set_protocol()
            self._parse_extensions()

            # Key validation, response generation.

            key = self._get_key()
            (accept, accept_binary) = compute_accept(key)
            self._logger.debug(
                '%s: %r (%s)',
                common.SEC_WEBSOCKET_ACCEPT_HEADER,
                accept,
                util.hexify(accept_binary))

            self._logger.debug('Protocol version is RFC 6455')

            # Setup extension processors.

            processors = []
            if self._request.ws_requested_extensions is not None:
                for extension_request in self._request.ws_requested_extensions:
                    processor = get_extension_processor(extension_request)
                    # Unknown extension requests are just ignored.
                    if processor is not None:
                        processors.append(processor)
            self._request.ws_extension_processors = processors

            # Extra handshake handler may modify/remove processors.
            self._dispatcher.do_extra_handshake(self._request)
            processors = filter(lambda processor: processor is not None,
                                self._request.ws_extension_processors)

            accepted_extensions = []

            # We need to take care of mux extension here. Extensions that
            # are placed before mux should be applied to logical channels.
            mux_index = -1
            for i, processor in enumerate(processors):
                if processor.name() == common.MUX_EXTENSION:
                    mux_index = i
                    break
            if mux_index >= 0:
                mux_processor = processors[mux_index]
                logical_channel_processors = processors[:mux_index]
                processors = processors[mux_index+1:]

                for processor in logical_channel_processors:
                    extension_response = processor.get_extension_response()
                    if extension_response is None:
                        # Rejected.
                        continue
                    accepted_extensions.append(extension_response)
                # Pass a shallow copy of accepted_extensions as extensions for
                # logical channels.
                mux_response = mux_processor.get_extension_response(
                    self._request, accepted_extensions[:])
                if mux_response is not None:
                    accepted_extensions.append(mux_response)

            stream_options = StreamOptions()

            # When there is mux extension, here, |processors| contain only
            # prosessors for extensions placed after mux.
            for processor in processors:

                extension_response = processor.get_extension_response()
                if extension_response is None:
                    # Rejected.
                    continue

                accepted_extensions.append(extension_response)

                processor.setup_stream_options(stream_options)

            if len(accepted_extensions) > 0:
                self._request.ws_extensions = accepted_extensions
                self._logger.debug(
                    'Extensions accepted: %r',
                    map(common.ExtensionParameter.name, accepted_extensions))
            else:
                self._request.ws_extensions = None

            self._request.ws_stream = self._create_stream(stream_options)

            if self._request.ws_requested_protocols is not None:
                if self._request.ws_protocol is None:
                    raise HandshakeException(
                        'do_extra_handshake must choose one subprotocol from '
                        'ws_requested_protocols and set it to ws_protocol')
                validate_subprotocol(self._request.ws_protocol, hixie=False)

                self._logger.debug(
                    'Subprotocol accepted: %r',
                    self._request.ws_protocol)
            else:
                if self._request.ws_protocol is not None:
                    raise HandshakeException(
                        'ws_protocol must be None when the client didn\'t '
                        'request any subprotocol')

            self._send_handshake(accept)
        except HandshakeException, e:
            if not e.status:
                # Fallback to 400 bad request by default.
                e.status = common.HTTP_STATUS_BAD_REQUEST
            raise e