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