Example #1
0
    def _send_handshake(self, accept):
        response = []

        response.append('HTTP/1.1 101 Switching Protocols\r\n')

        response.append(format_header(
            common.UPGRADE_HEADER, common.WEBSOCKET_UPGRADE_TYPE))
        response.append(format_header(
            common.CONNECTION_HEADER, common.UPGRADE_CONNECTION_TYPE))
        response.append(format_header(
            common.SEC_WEBSOCKET_ACCEPT_HEADER, accept))
        if self._request.ws_protocol is not None:
            response.append(format_header(
                common.SEC_WEBSOCKET_PROTOCOL_HEADER,
                self._request.ws_protocol))
        if (self._request.ws_extensions is not None and
            len(self._request.ws_extensions) != 0):
            response.append(format_header(
                common.SEC_WEBSOCKET_EXTENSIONS_HEADER,
                format_extensions(self._request.ws_extensions)))
        response.append('\r\n')

        raw_response = ''.join(response)
        self._request.connection.write(raw_response)
        self._logger.debug('Sent server\'s opening handshake: %r',
                           raw_response)
Example #2
0
    def _send_handshake(self, accept):
        response = []

        response.append('HTTP/1.1 101 Switching Protocols\r\n')

        response.append(format_header(
            common.UPGRADE_HEADER, common.WEBSOCKET_UPGRADE_TYPE))
        response.append(format_header(
            common.CONNECTION_HEADER, common.UPGRADE_CONNECTION_TYPE))
        response.append(format_header(
            common.SEC_WEBSOCKET_ACCEPT_HEADER, accept))
        # TODO(tyoshino): Encode value of protocol and extensions if any
        # special character that we have to encode by some manner.
        if self._request.ws_protocol is not None:
            response.append(format_header(
                common.SEC_WEBSOCKET_PROTOCOL_HEADER,
                self._request.ws_protocol))
        if self._request.ws_extensions is not None:
            response.append(format_header(
                common.SEC_WEBSOCKET_EXTENSIONS_HEADER,
                format_extensions(self._request.ws_extensions)))
        response.append('\r\n')

        raw_response = ''.join(response)
        self._logger.debug('Opening handshake response: %r', raw_response)
        self._request.connection.write(raw_response)
Example #3
0
    def _send_handshake(self, accept):
        response = []

        response.append('HTTP/1.1 101 Switching Protocols\r\n')

        response.append(
            format_header(common.UPGRADE_HEADER,
                          common.WEBSOCKET_UPGRADE_TYPE))
        response.append(
            format_header(common.CONNECTION_HEADER,
                          common.UPGRADE_CONNECTION_TYPE))
        response.append(
            format_header(common.SEC_WEBSOCKET_ACCEPT_HEADER, accept))
        if self._request.ws_protocol is not None:
            response.append(
                format_header(common.SEC_WEBSOCKET_PROTOCOL_HEADER,
                              self._request.ws_protocol))
        if (self._request.ws_extensions is not None
                and len(self._request.ws_extensions) != 0):
            response.append(
                format_header(common.SEC_WEBSOCKET_EXTENSIONS_HEADER,
                              format_extensions(self._request.ws_extensions)))
        # MOZILLA: Add HSTS header if requested to
        if self._request.sts is not None:
            response.append(
                format_header("Strict-Transport-Security", self._request.sts))
        # /MOZILLA
        response.append('\r\n')

        raw_response = ''.join(response)
        self._request.connection.write(raw_response)
        self._logger.debug('Sent server\'s opening handshake: %r',
                           raw_response)
Example #4
0
    def _send_handshake(self, accept):
        response = []

        response.append('HTTP/1.1 101 Switching Protocols\r\n')

        response.append(
            format_header(common.UPGRADE_HEADER,
                          common.WEBSOCKET_UPGRADE_TYPE))
        response.append(
            format_header(common.CONNECTION_HEADER,
                          common.UPGRADE_CONNECTION_TYPE))
        response.append(
            format_header(common.SEC_WEBSOCKET_ACCEPT_HEADER, accept))
        # TODO(tyoshino): Encode value of protocol and extensions if any
        # special character that we have to encode by some manner.
        if self._request.ws_protocol is not None:
            response.append(
                format_header(common.SEC_WEBSOCKET_PROTOCOL_HEADER,
                              self._request.ws_protocol))
        if self._request.ws_extensions is not None:
            response.append(
                format_header(common.SEC_WEBSOCKET_EXTENSIONS_HEADER,
                              format_extensions(self._request.ws_extensions)))
        response.append('\r\n')

        raw_response = ''.join(response)
        self._logger.debug('Opening handshake response: %r', raw_response)
        self._request.connection.write(raw_response)
Example #5
0
 def test_format_extensions(self):
     for formatted_string, definitions in _TEST_TOKEN_EXTENSION_DATA:
         extensions = []
         for definition in definitions:
             (name, parameters) = definition
             extension = ExtensionParameter(name)
             extension._parameters = parameters
             extensions.append(extension)
         self.assertEqual(
             formatted_string, format_extensions(extensions))
Example #6
0
    def handshake(self):
        """Performs opening handshake on the specified socket.

        Raises:
            ClientHandshakeError: handshake failed.
        """

        request_line = _build_method_line(self._options.resource)
        self._logger.debug("Client's opening handshake Request-Line: %r", request_line)
        self._socket.sendall(request_line)

        fields = []
        fields.append(_format_host_header(self._options.server_host, self._options.server_port, self._options.use_tls))
        fields.append(_UPGRADE_HEADER)
        fields.append(_CONNECTION_HEADER)
        if self._options.origin is not None:
            if self._options.protocol_version == _PROTOCOL_VERSION_HYBI08:
                fields.append(_origin_header(common.SEC_WEBSOCKET_ORIGIN_HEADER, self._options.origin))
            else:
                fields.append(_origin_header(common.ORIGIN_HEADER, self._options.origin))

        original_key = os.urandom(16)
        self._key = base64.b64encode(original_key)
        self._logger.debug("%s: %r (%s)", common.SEC_WEBSOCKET_KEY_HEADER, self._key, util.hexify(original_key))
        fields.append("%s: %s\r\n" % (common.SEC_WEBSOCKET_KEY_HEADER, self._key))

        if self._options.version_header > 0:
            fields.append("%s: %d\r\n" % (common.SEC_WEBSOCKET_VERSION_HEADER, self._options.version_header))
        elif self._options.protocol_version == _PROTOCOL_VERSION_HYBI08:
            fields.append("%s: %d\r\n" % (common.SEC_WEBSOCKET_VERSION_HEADER, common.VERSION_HYBI08))
        else:
            fields.append("%s: %d\r\n" % (common.SEC_WEBSOCKET_VERSION_HEADER, common.VERSION_HYBI_LATEST))

        extensions_to_request = []

        if self._options.deflate_stream:
            extensions_to_request.append(common.ExtensionParameter(common.DEFLATE_STREAM_EXTENSION))

        if self._options.deflate_frame:
            extensions_to_request.append(common.ExtensionParameter(common.DEFLATE_FRAME_EXTENSION))

        if len(extensions_to_request) != 0:
            fields.append(
                "%s: %s\r\n" % (common.SEC_WEBSOCKET_EXTENSIONS_HEADER, format_extensions(extensions_to_request))
            )

        for field in fields:
            self._socket.sendall(field)

        self._socket.sendall("\r\n")

        self._logger.debug("Sent client's opening handshake headers: %r", fields)
        self._logger.debug("Start reading Status-Line")

        status_line = ""
        while True:
            ch = _receive_bytes(self._socket, 1)
            status_line += ch
            if ch == "\n":
                break

        m = re.match("HTTP/\\d+\.\\d+ (\\d\\d\\d) .*\r\n", status_line)
        if m is None:
            raise ClientHandshakeError("Wrong status line format: %r" % status_line)
        status_code = m.group(1)
        if status_code != "101":
            self._logger.debug(
                "Unexpected status code %s with following " "headers: %r", status_code, self._read_fields()
            )
            raise ClientHandshakeError("Expected HTTP status code 101 but found %r" % status_code)

        self._logger.debug("Received valid Status-Line")
        self._logger.debug("Start reading headers until we see an empty line")

        fields = self._read_fields()

        ch = _receive_bytes(self._socket, 1)
        if ch != "\n":  # 0x0A
            raise ClientHandshakeError(
                "Expected LF but found %r while reading value %r for header " "name %r" % (ch, value, name)
            )

        self._logger.debug("Received an empty line")
        self._logger.debug("Server's opening handshake headers: %r", fields)

        _validate_mandatory_header(fields, common.UPGRADE_HEADER, common.WEBSOCKET_UPGRADE_TYPE, False)

        _validate_mandatory_header(fields, common.CONNECTION_HEADER, common.UPGRADE_CONNECTION_TYPE, False)

        accept = _get_mandatory_header(fields, common.SEC_WEBSOCKET_ACCEPT_HEADER)

        # Validate
        try:
            binary_accept = base64.b64decode(accept)
        except TypeError, e:
            raise HandshakeError("Illegal value for header %s: %r" % (common.SEC_WEBSOCKET_ACCEPT_HEADER, accept))