tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_handshake.py (6933B)


      1 #!/usr/bin/env python
      2 #
      3 # Copyright 2012, Google Inc.
      4 # All rights reserved.
      5 #
      6 # Redistribution and use in source and binary forms, with or without
      7 # modification, are permitted provided that the following conditions are
      8 # met:
      9 #
     10 #     * Redistributions of source code must retain the above copyright
     11 # notice, this list of conditions and the following disclaimer.
     12 #     * Redistributions in binary form must reproduce the above
     13 # copyright notice, this list of conditions and the following disclaimer
     14 # in the documentation and/or other materials provided with the
     15 # distribution.
     16 #     * Neither the name of Google Inc. nor the names of its
     17 # contributors may be used to endorse or promote products derived from
     18 # this software without specific prior written permission.
     19 #
     20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     24 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31 """Tests for handshake.base module."""
     32 
     33 from __future__ import absolute_import
     34 
     35 import unittest
     36 
     37 import set_sys_path  # Update sys.path to locate pywebsocket3 module.
     38 from pywebsocket3.common import (
     39    ExtensionParameter,
     40    ExtensionParsingException,
     41    format_extensions,
     42    parse_extensions,
     43 )
     44 from pywebsocket3.handshake.base import HandshakeException, validate_subprotocol
     45 
     46 
     47 class ValidateSubprotocolTest(unittest.TestCase):
     48    """A unittest for validate_subprotocol method."""
     49    def test_validate_subprotocol(self):
     50        # Should succeed.
     51        validate_subprotocol('sample')
     52        validate_subprotocol('Sample')
     53        validate_subprotocol('sample\x7eprotocol')
     54 
     55        # Should fail.
     56        self.assertRaises(HandshakeException, validate_subprotocol, '')
     57        self.assertRaises(HandshakeException, validate_subprotocol,
     58                          'sample\x09protocol')
     59        self.assertRaises(HandshakeException, validate_subprotocol,
     60                          'sample\x19protocol')
     61        self.assertRaises(HandshakeException, validate_subprotocol,
     62                          'sample\x20protocol')
     63        self.assertRaises(HandshakeException, validate_subprotocol,
     64                          'sample\x7fprotocol')
     65        self.assertRaises(
     66            HandshakeException,
     67            validate_subprotocol,
     68            # "Japan" in Japanese
     69            u'\u65e5\u672c')
     70 
     71 
     72 _TEST_TOKEN_EXTENSION_DATA = [
     73    ('foo', [('foo', [])]),
     74    ('foo; bar', [('foo', [('bar', None)])]),
     75    ('foo; bar=baz', [('foo', [('bar', 'baz')])]),
     76    ('foo; bar=baz; car=cdr', [('foo', [('bar', 'baz'), ('car', 'cdr')])]),
     77    ('foo; bar=baz, car; cdr', [('foo', [('bar', 'baz')]),
     78                                ('car', [('cdr', None)])]),
     79    ('a, b, c, d', [('a', []), ('b', []), ('c', []), ('d', [])]),
     80 ]
     81 
     82 _TEST_QUOTED_EXTENSION_DATA = [
     83    ('foo; bar=""', [('foo', [('bar', '')])]),
     84    ('foo; bar=" baz "', [('foo', [('bar', ' baz ')])]),
     85    ('foo; bar=",baz;"', [('foo', [('bar', ',baz;')])]),
     86    ('foo; bar="\\\r\\\nbaz"', [('foo', [('bar', '\r\nbaz')])]),
     87    ('foo; bar="\\"baz"', [('foo', [('bar', '"baz')])]),
     88    ('foo; bar="\xbbbaz"', [('foo', [('bar', '\xbbbaz')])]),
     89 ]
     90 
     91 _TEST_REDUNDANT_TOKEN_EXTENSION_DATA = [
     92    ('foo \t ', [('foo', [])]),
     93    ('foo; \r\n bar', [('foo', [('bar', None)])]),
     94    ('foo; bar=\r\n \r\n baz', [('foo', [('bar', 'baz')])]),
     95    ('foo ;bar = baz ', [('foo', [('bar', 'baz')])]),
     96    ('foo,bar,,baz', [('foo', []), ('bar', []), ('baz', [])]),
     97 ]
     98 
     99 _TEST_REDUNDANT_QUOTED_EXTENSION_DATA = [
    100    ('foo; bar="\r\n \r\n baz"', [('foo', [('bar', '  baz')])]),
    101 ]
    102 
    103 
    104 class ExtensionsParserTest(unittest.TestCase):
    105    def _verify_extension_list(self, expected_list, actual_list):
    106        """Verifies that ExtensionParameter objects in actual_list have the
    107        same members as extension definitions in expected_list. Extension
    108        definition used in this test is a pair of an extension name and a
    109        parameter dictionary.
    110        """
    111 
    112        self.assertEqual(len(expected_list), len(actual_list))
    113        for expected, actual in zip(expected_list, actual_list):
    114            (name, parameters) = expected
    115            self.assertEqual(name, actual._name)
    116            self.assertEqual(parameters, actual._parameters)
    117 
    118    def test_parse(self):
    119        for formatted_string, definition in _TEST_TOKEN_EXTENSION_DATA:
    120            self._verify_extension_list(definition,
    121                                        parse_extensions(formatted_string))
    122 
    123    def test_parse_quoted_data(self):
    124        for formatted_string, definition in _TEST_QUOTED_EXTENSION_DATA:
    125            self._verify_extension_list(definition,
    126                                        parse_extensions(formatted_string))
    127 
    128    def test_parse_redundant_data(self):
    129        for (formatted_string,
    130             definition) in _TEST_REDUNDANT_TOKEN_EXTENSION_DATA:
    131            self._verify_extension_list(definition,
    132                                        parse_extensions(formatted_string))
    133 
    134    def test_parse_redundant_quoted_data(self):
    135        for (formatted_string,
    136             definition) in _TEST_REDUNDANT_QUOTED_EXTENSION_DATA:
    137            self._verify_extension_list(definition,
    138                                        parse_extensions(formatted_string))
    139 
    140    def test_parse_bad_data(self):
    141        _TEST_BAD_EXTENSION_DATA = [
    142            ('foo; ; '),
    143            ('foo; a a'),
    144            ('foo foo'),
    145            (',,,'),
    146            ('foo; bar='),
    147            ('foo; bar="hoge'),
    148            ('foo; bar="a\r"'),
    149            ('foo; bar="\\\xff"'),
    150            ('foo; bar=\ra'),
    151        ]
    152 
    153        for formatted_string in _TEST_BAD_EXTENSION_DATA:
    154            self.assertRaises(ExtensionParsingException, parse_extensions,
    155                              formatted_string)
    156 
    157 
    158 class FormatExtensionsTest(unittest.TestCase):
    159    def test_format_extensions(self):
    160        for formatted_string, definitions in _TEST_TOKEN_EXTENSION_DATA:
    161            extensions = []
    162            for definition in definitions:
    163                (name, parameters) = definition
    164                extension = ExtensionParameter(name)
    165                extension._parameters = parameters
    166                extensions.append(extension)
    167            self.assertEqual(formatted_string, format_extensions(extensions))
    168 
    169 
    170 if __name__ == '__main__':
    171    unittest.main()
    172 
    173 # vi:sts=4 sw=4 et