testing/mochitest/pywebsocket/mod_pywebsocket/common.py

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 # Copyright 2012, Google Inc.
michael@0 2 # All rights reserved.
michael@0 3 #
michael@0 4 # Redistribution and use in source and binary forms, with or without
michael@0 5 # modification, are permitted provided that the following conditions are
michael@0 6 # met:
michael@0 7 #
michael@0 8 # * Redistributions of source code must retain the above copyright
michael@0 9 # notice, this list of conditions and the following disclaimer.
michael@0 10 # * Redistributions in binary form must reproduce the above
michael@0 11 # copyright notice, this list of conditions and the following disclaimer
michael@0 12 # in the documentation and/or other materials provided with the
michael@0 13 # distribution.
michael@0 14 # * Neither the name of Google Inc. nor the names of its
michael@0 15 # contributors may be used to endorse or promote products derived from
michael@0 16 # this software without specific prior written permission.
michael@0 17 #
michael@0 18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 29
michael@0 30
michael@0 31 # Constants indicating WebSocket protocol version.
michael@0 32 VERSION_HIXIE75 = -1
michael@0 33 VERSION_HYBI00 = 0
michael@0 34 VERSION_HYBI01 = 1
michael@0 35 VERSION_HYBI02 = 2
michael@0 36 VERSION_HYBI03 = 2
michael@0 37 VERSION_HYBI04 = 4
michael@0 38 VERSION_HYBI05 = 5
michael@0 39 VERSION_HYBI06 = 6
michael@0 40 VERSION_HYBI07 = 7
michael@0 41 VERSION_HYBI08 = 8
michael@0 42 VERSION_HYBI09 = 8
michael@0 43 VERSION_HYBI10 = 8
michael@0 44 VERSION_HYBI11 = 8
michael@0 45 VERSION_HYBI12 = 8
michael@0 46 VERSION_HYBI13 = 13
michael@0 47 VERSION_HYBI14 = 13
michael@0 48 VERSION_HYBI15 = 13
michael@0 49 VERSION_HYBI16 = 13
michael@0 50 VERSION_HYBI17 = 13
michael@0 51
michael@0 52 # Constants indicating WebSocket protocol latest version.
michael@0 53 VERSION_HYBI_LATEST = VERSION_HYBI13
michael@0 54
michael@0 55 # Port numbers
michael@0 56 DEFAULT_WEB_SOCKET_PORT = 80
michael@0 57 DEFAULT_WEB_SOCKET_SECURE_PORT = 443
michael@0 58
michael@0 59 # Schemes
michael@0 60 WEB_SOCKET_SCHEME = 'ws'
michael@0 61 WEB_SOCKET_SECURE_SCHEME = 'wss'
michael@0 62
michael@0 63 # Frame opcodes defined in the spec.
michael@0 64 OPCODE_CONTINUATION = 0x0
michael@0 65 OPCODE_TEXT = 0x1
michael@0 66 OPCODE_BINARY = 0x2
michael@0 67 OPCODE_CLOSE = 0x8
michael@0 68 OPCODE_PING = 0x9
michael@0 69 OPCODE_PONG = 0xa
michael@0 70
michael@0 71 # UUIDs used by HyBi 04 and later opening handshake and frame masking.
michael@0 72 WEBSOCKET_ACCEPT_UUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
michael@0 73
michael@0 74 # Opening handshake header names and expected values.
michael@0 75 UPGRADE_HEADER = 'Upgrade'
michael@0 76 WEBSOCKET_UPGRADE_TYPE = 'websocket'
michael@0 77 WEBSOCKET_UPGRADE_TYPE_HIXIE75 = 'WebSocket'
michael@0 78 CONNECTION_HEADER = 'Connection'
michael@0 79 UPGRADE_CONNECTION_TYPE = 'Upgrade'
michael@0 80 HOST_HEADER = 'Host'
michael@0 81 ORIGIN_HEADER = 'Origin'
michael@0 82 SEC_WEBSOCKET_ORIGIN_HEADER = 'Sec-WebSocket-Origin'
michael@0 83 SEC_WEBSOCKET_KEY_HEADER = 'Sec-WebSocket-Key'
michael@0 84 SEC_WEBSOCKET_ACCEPT_HEADER = 'Sec-WebSocket-Accept'
michael@0 85 SEC_WEBSOCKET_VERSION_HEADER = 'Sec-WebSocket-Version'
michael@0 86 SEC_WEBSOCKET_PROTOCOL_HEADER = 'Sec-WebSocket-Protocol'
michael@0 87 SEC_WEBSOCKET_EXTENSIONS_HEADER = 'Sec-WebSocket-Extensions'
michael@0 88 SEC_WEBSOCKET_DRAFT_HEADER = 'Sec-WebSocket-Draft'
michael@0 89 SEC_WEBSOCKET_KEY1_HEADER = 'Sec-WebSocket-Key1'
michael@0 90 SEC_WEBSOCKET_KEY2_HEADER = 'Sec-WebSocket-Key2'
michael@0 91 SEC_WEBSOCKET_LOCATION_HEADER = 'Sec-WebSocket-Location'
michael@0 92
michael@0 93 # Extensions
michael@0 94 DEFLATE_STREAM_EXTENSION = 'deflate-stream'
michael@0 95 DEFLATE_FRAME_EXTENSION = 'deflate-frame'
michael@0 96 X_WEBKIT_DEFLATE_FRAME_EXTENSION = 'x-webkit-deflate-frame'
michael@0 97
michael@0 98 # Status codes
michael@0 99 # Code STATUS_NO_STATUS_RECEIVED, STATUS_ABNORMAL_CLOSURE, and
michael@0 100 # STATUS_TLS_HANDSHAKE are pseudo codes to indicate specific error cases.
michael@0 101 # Could not be used for codes in actual closing frames.
michael@0 102 # Application level errors must use codes in the range
michael@0 103 # STATUS_USER_REGISTERED_BASE to STATUS_USER_PRIVATE_MAX. The codes in the
michael@0 104 # range STATUS_USER_REGISTERED_BASE to STATUS_USER_REGISTERED_MAX are managed
michael@0 105 # by IANA. Usually application must define user protocol level errors in the
michael@0 106 # range STATUS_USER_PRIVATE_BASE to STATUS_USER_PRIVATE_MAX.
michael@0 107 STATUS_NORMAL_CLOSURE = 1000
michael@0 108 STATUS_GOING_AWAY = 1001
michael@0 109 STATUS_PROTOCOL_ERROR = 1002
michael@0 110 STATUS_UNSUPPORTED_DATA = 1003
michael@0 111 STATUS_NO_STATUS_RECEIVED = 1005
michael@0 112 STATUS_ABNORMAL_CLOSURE = 1006
michael@0 113 STATUS_INVALID_FRAME_PAYLOAD_DATA = 1007
michael@0 114 STATUS_POLICY_VIOLATION = 1008
michael@0 115 STATUS_MESSAGE_TOO_BIG = 1009
michael@0 116 STATUS_MANDATORY_EXTENSION = 1010
michael@0 117 STATUS_INTERNAL_SERVER_ERROR = 1011
michael@0 118 STATUS_TLS_HANDSHAKE = 1015
michael@0 119 STATUS_USER_REGISTERED_BASE = 3000
michael@0 120 STATUS_USER_REGISTERED_MAX = 3999
michael@0 121 STATUS_USER_PRIVATE_BASE = 4000
michael@0 122 STATUS_USER_PRIVATE_MAX = 4999
michael@0 123 # Following definitions are aliases to keep compatibility. Applications must
michael@0 124 # not use these obsoleted definitions anymore.
michael@0 125 STATUS_NORMAL = STATUS_NORMAL_CLOSURE
michael@0 126 STATUS_UNSUPPORTED = STATUS_UNSUPPORTED_DATA
michael@0 127 STATUS_CODE_NOT_AVAILABLE = STATUS_NO_STATUS_RECEIVED
michael@0 128 STATUS_ABNORMAL_CLOSE = STATUS_ABNORMAL_CLOSURE
michael@0 129 STATUS_INVALID_FRAME_PAYLOAD = STATUS_INVALID_FRAME_PAYLOAD_DATA
michael@0 130 STATUS_MANDATORY_EXT = STATUS_MANDATORY_EXTENSION
michael@0 131
michael@0 132 # HTTP status codes
michael@0 133 HTTP_STATUS_BAD_REQUEST = 400
michael@0 134 HTTP_STATUS_FORBIDDEN = 403
michael@0 135 HTTP_STATUS_NOT_FOUND = 404
michael@0 136
michael@0 137
michael@0 138 def is_control_opcode(opcode):
michael@0 139 return (opcode >> 3) == 1
michael@0 140
michael@0 141
michael@0 142 class ExtensionParameter(object):
michael@0 143 """Holds information about an extension which is exchanged on extension
michael@0 144 negotiation in opening handshake.
michael@0 145 """
michael@0 146
michael@0 147 def __init__(self, name):
michael@0 148 self._name = name
michael@0 149 # TODO(tyoshino): Change the data structure to more efficient one such
michael@0 150 # as dict when the spec changes to say like
michael@0 151 # - Parameter names must be unique
michael@0 152 # - The order of parameters is not significant
michael@0 153 self._parameters = []
michael@0 154
michael@0 155 def name(self):
michael@0 156 return self._name
michael@0 157
michael@0 158 def add_parameter(self, name, value):
michael@0 159 self._parameters.append((name, value))
michael@0 160
michael@0 161 def get_parameters(self):
michael@0 162 return self._parameters
michael@0 163
michael@0 164 def get_parameter_names(self):
michael@0 165 return [name for name, unused_value in self._parameters]
michael@0 166
michael@0 167 def has_parameter(self, name):
michael@0 168 for param_name, param_value in self._parameters:
michael@0 169 if param_name == name:
michael@0 170 return True
michael@0 171 return False
michael@0 172
michael@0 173 def get_parameter_value(self, name):
michael@0 174 for param_name, param_value in self._parameters:
michael@0 175 if param_name == name:
michael@0 176 return param_value
michael@0 177
michael@0 178
michael@0 179 # vi:sts=4 sw=4 et

mercurial