def _get_key_value(self, key_field):
        key_value = get_mandatory_header(self._request, key_field)

        self._logger.debug('%s: %r', key_field, key_value)

        # 5.2 4. let /key-number_n/ be the digits (characters in the range
        # U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9)) in /key_n/,
        # interpreted as a base ten integer, ignoring all other characters
        # in /key_n/.
        try:
            key_number = int(re.sub("\\D", "", key_value))
        except:
            raise HandshakeException('%s field contains no digit' % key_field)
        # 5.2 5. let /spaces_n/ be the number of U+0020 SPACE characters
        # in /key_n/.
        spaces = re.subn(" ", "", key_value)[1]
        if spaces == 0:
            raise HandshakeException('%s field contains no space' % key_field)

        self._logger.debug(
            '%s: Key-number is %d and number of spaces is %d',
            key_field, key_number, spaces)

        # 5.2 6. if /key-number_n/ is not an integral multiple of /spaces_n/
        # then abort the WebSocket connection.
        if key_number % spaces != 0:
            raise HandshakeException(
                '%s: Key-number (%d) is not an integral multiple of spaces '
                '(%d)' % (key_field, key_number, spaces))
        # 5.2 7. let /part_n/ be /key-number_n/ divided by /spaces_n/.
        part = key_number / spaces
        self._logger.debug('%s: Part is %d', key_field, part)
        return part
示例#2
0
    def _get_key_value(self, key_field):
        key_value = get_mandatory_header(self._request, key_field)

        self._logger.debug('%s: %r', key_field, key_value)

        # 5.2 4. let /key-number_n/ be the digits (characters in the range
        # U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9)) in /key_n/,
        # interpreted as a base ten integer, ignoring all other characters
        # in /key_n/.
        try:
            key_number = int(re.sub("\\D", "", key_value))
        except:
            raise HandshakeException('%s field contains no digit' % key_field)
        # 5.2 5. let /spaces_n/ be the number of U+0020 SPACE characters
        # in /key_n/.
        spaces = re.subn(" ", "", key_value)[1]
        if spaces == 0:
            raise HandshakeException('%s field contains no space' % key_field)

        self._logger.debug('%s: Key-number is %d and number of spaces is %d',
                           key_field, key_number, spaces)

        # 5.2 6. if /key-number_n/ is not an integral multiple of /spaces_n/
        # then abort the WebSocket connection.
        if key_number % spaces != 0:
            raise HandshakeException(
                '%s: Key-number (%d) is not an integral multiple of spaces '
                '(%d)' % (key_field, key_number, spaces))
        # 5.2 7. let /part_n/ be /key-number_n/ divided by /spaces_n/.
        part = key_number / spaces
        self._logger.debug('%s: Part is %d', key_field, part)
        return part
示例#3
0
文件: hybi.py 项目: GhostQ/GitSB
    def _validate_connection_header(self):
        connection = get_mandatory_header(self._request,
                                          common.CONNECTION_HEADER)

        try:
            connection_tokens = parse_token_list(connection)
        except HandshakeException, e:
            raise HandshakeException('Failed to parse %s: %s' %
                                     (common.CONNECTION_HEADER, e))
示例#4
0
文件: hybi.py 项目: cscheid/forte
    def _validate_connection_header(self):
        connection = get_mandatory_header(
            self._request, common.CONNECTION_HEADER)

        try:
            connection_tokens = parse_token_list(connection)
        except HandshakeException, e:
            raise HandshakeException(
                'Failed to parse %s: %s' % (common.CONNECTION_HEADER, e))
示例#5
0
    def _get_key(self):
        key = get_mandatory_header(
            self._request, common.SEC_WEBSOCKET_KEY_HEADER)

        decoded_key = self._validate_key(key)

        self._logger.debug('Sec-WebSocket-Key: %r (%s)',
                           key, util.hexify(decoded_key))

        return key
示例#6
0
    def _get_key(self):
        key = get_mandatory_header(self._request,
                                   common.SEC_WEBSOCKET_KEY_HEADER)

        decoded_key = self._validate_key(key)

        self._logger.debug('Sec-WebSocket-Key: %r (%s)', key,
                           util.hexify(decoded_key))

        return key
示例#7
0
文件: hybi.py 项目: zachlewis2020/wpt
    def _get_key(self):
        key = get_mandatory_header(self._request,
                                   common.SEC_WEBSOCKET_KEY_HEADER)

        decoded_key = self._validate_key(key)

        self._logger.debug('%s: %r (%s)', common.SEC_WEBSOCKET_KEY_HEADER, key,
                           util.hexify(decoded_key))

        return key.encode('UTF-8')
示例#8
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))
示例#9
0
文件: hybi.py 项目: Coder206/servo
    def _check_version(self):
        version = get_mandatory_header(self._request,
                                       common.SEC_WEBSOCKET_VERSION_HEADER)
        if version == _VERSION_LATEST_STRING:
            return _VERSION_LATEST

        if version.find(',') >= 0:
            raise HandshakeException(
                'Multiple versions (%r) are not allowed for header %s' %
                (version, common.SEC_WEBSOCKET_VERSION_HEADER),
                status=common.HTTP_STATUS_BAD_REQUEST)
        raise VersionException(
            'Unsupported version %r for header %s' %
            (version, common.SEC_WEBSOCKET_VERSION_HEADER),
            supported_versions=', '.join(map(str, _SUPPORTED_VERSIONS)))
示例#10
0
    def _check_version(self):
        sec_websocket_version_header = 'sec-websocket-version'
        version = get_mandatory_header(self._request, sec_websocket_version_header)
        if version == _VERSION_LATEST_STRING:
            return _VERSION_LATEST

        if version.find(',') >= 0:
            raise HandshakeException(
                'Multiple versions (%r) are not allowed for header %s' %
                (version, sec_websocket_version_header),
                status=common.HTTP_STATUS_BAD_REQUEST)
        raise VersionException('Unsupported version %r for header %s' %
                               (version, sec_websocket_version_header),
                               supported_versions=', '.join(
                                   map(str, _SUPPORTED_VERSIONS)))
示例#11
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))
示例#12
0
文件: hybi.py 项目: GhostQ/GitSB
    def _check_version(self):
        version = get_mandatory_header(self._request,
                                       common.SEC_WEBSOCKET_VERSION_HEADER)
        if version == _VERSION_HYBI08_STRING:
            return _VERSION_HYBI08
        if version == _VERSION_LATEST_STRING:
            return _VERSION_LATEST

        if version.find(',') >= 0:
            raise HandshakeException(
                'Multiple versions (%r) are not allowed for header %s' %
                (version, common.SEC_WEBSOCKET_VERSION_HEADER),
                status=common.HTTP_STATUS_BAD_REQUEST)
        raise VersionException('Unsupported version %r for header %s' %
                               (version, common.SEC_WEBSOCKET_VERSION_HEADER),
                               supported_versions=', '.join(
                                   map(str, _SUPPORTED_VERSIONS)))
示例#13
0
    def do_handshake(self):
        check_header_lines(self._request, _MANDATORY_HEADERS)
        self._request.ws_resource = self._request.uri

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

        self._get_origin()
        self._check_version()
        self._set_protocol()
        self._set_extensions()

        key = self._get_key()
        (accept, accept_binary) = compute_accept(key)
        self._logger.debug('Sec-WebSocket-Accept: %r (%s)', accept,
                           util.hexify(accept_binary))

        self._logger.debug('IETF HyBi 07 protocol')
        self._request.ws_version = common.VERSION_HYBI07
        stream_options = StreamOptions()
        stream_options.deflate = self._request.ws_deflate
        self._request.ws_stream = Stream(self._request, stream_options)

        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        self._dispatcher.do_extra_handshake(self._request)

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

            # TODO(tyoshino): Validate selected subprotocol value.

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

        self._send_handshake(accept)

        self._logger.debug('Sent opening handshake response')
示例#14
0
文件: hybi.py 项目: zachlewis2020/wpt
    def _validate_connection_header(self):
        connection = get_mandatory_header(self._request,
                                          common.CONNECTION_HEADER)

        try:
            connection_tokens = parse_token_list(connection)
        except HandshakeException as e:
            raise HandshakeException('Failed to parse %s: %s' %
                                     (common.CONNECTION_HEADER, e))

        connection_is_valid = False
        for token in connection_tokens:
            if token.lower() == common.UPGRADE_CONNECTION_TYPE.lower():
                connection_is_valid = True
                break
        if not connection_is_valid:
            raise HandshakeException(
                '%s header doesn\'t contain "%s"' %
                (common.CONNECTION_HEADER, common.UPGRADE_CONNECTION_TYPE))
示例#15
0
文件: hybi.py 项目: Coder206/servo
    def _validate_connection_header(self):
        connection = get_mandatory_header(
            self._request, common.CONNECTION_HEADER)

        try:
            connection_tokens = parse_token_list(connection)
        except HandshakeException as e:
            raise HandshakeException(
                'Failed to parse %s: %s' % (common.CONNECTION_HEADER, e))

        connection_is_valid = False
        for token in connection_tokens:
            if token.lower() == common.UPGRADE_CONNECTION_TYPE.lower():
                connection_is_valid = True
                break
        if not connection_is_valid:
            raise HandshakeException(
                '%s header doesn\'t contain "%s"' %
                (common.CONNECTION_HEADER, common.UPGRADE_CONNECTION_TYPE))
示例#16
0
文件: hybi.py 项目: cscheid/forte
    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
示例#17
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
示例#18
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
示例#19
0
class Handshaker(object):
    """This class performs WebSocket handshake."""
    def __init__(self, request, dispatcher):
        """Construct an instance.

        Args:
            request: mod_python request.
            dispatcher: Dispatcher (dispatch.Dispatcher).

        Handshaker will add attributes such as ws_resource during handshake.
        """

        self._logger = util.get_class_logger(self)

        self._request = request
        self._dispatcher = dispatcher

    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))

        connection_is_valid = False
        for token in connection_tokens:
            if token.lower() == common.UPGRADE_CONNECTION_TYPE.lower():
                connection_is_valid = True
                break
        if not connection_is_valid:
            raise HandshakeError(
                '%s header doesn\'t contain "%s"' %
                (common.CONNECTION_HEADER, common.UPGRADE_CONNECTION_TYPE))

        self._request.ws_resource = self._request.uri

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

        self._get_origin()
        self._check_version()
        self._set_protocol()
        self._set_extensions()

        key = self._get_key()
        (accept, accept_binary) = compute_accept(key)
        self._logger.debug('Sec-WebSocket-Accept: %r (%s)', accept,
                           util.hexify(accept_binary))

        self._logger.debug('IETF HyBi 07 protocol')
        self._request.ws_version = common.VERSION_HYBI07
        stream_options = StreamOptions()
        stream_options.deflate = self._request.ws_deflate
        self._request.ws_stream = Stream(self._request, stream_options)

        self._request.ws_close_code = None
        self._request.ws_close_reason = None

        self._dispatcher.do_extra_handshake(self._request)

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

            # TODO(tyoshino): Validate selected subprotocol value.

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

        self._send_handshake(accept)

        self._logger.debug('Sent opening handshake response')
示例#20
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
示例#21
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
示例#22
0
文件: hybi.py 项目: 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
示例#23
0
文件: hybi.py 项目: zachlewis2020/wpt
    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