Changeset 90979 in webkit
- Timestamp:
- Jul 13, 2011 10:32:44 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r90976 r90979 1 2011-07-13 Yuta Kitamura <yutak@chromium.org> 2 3 WebSocket: Implement hybi handshake 4 https://bugs.webkit.org/show_bug.cgi?id=64344 5 6 Reviewed by Kent Tamura. 7 8 Fix existing tests so they match the new handshake format, and add tests for new header fields. 9 10 There are several changes in the format of handshake response, such as: 11 - Reason string in HTTP status line has been changed to "Switching Protocols". 12 - The value of "Upgrade" header has been changed to "websocket" (lower-case only). 13 - Sec-WebSocket-Location and Sec-WebSocket-Origin are gone. 14 - "Challenge response" value (16-byte data after the response header fields) is removed, and 15 Sec-WebSocket-Accept header is added instead. 16 17 The value of Sec-WebSocket-Accept header is computed using compute_accept() function 18 located in mod_pywebsocket.handshake.hybi06 module. Although the module name contains 19 "hybi06", this function can be used to calculate the value of Sec-WebSocket-Accept header 20 for hybi-10 (calculation method has not been changed since hybi-06). 21 22 Note: Tests under hybi/ directory (including the new ones) are skipped and cannot be enabled 23 yet, because pywebsocket does not accept requests from half-baked client implementation 24 (i.e. hybi handshake + hixie-76 framing). They will be unskipped when hybi framing is landed 25 in WebCore. 26 27 * http/tests/websocket/tests/handler_map.txt: 28 There must be only one handler that can handle requests to "/". hybi/echo-location_wsh.py 29 is modified to accept requests of both protocol versions. 30 * http/tests/websocket/tests/hybi/bad-handshake-crash_wsh.py: 31 * http/tests/websocket/tests/hybi/echo-challenge_wsh.py: 32 * http/tests/websocket/tests/hybi/echo-location_wsh.py: 33 * http/tests/websocket/tests/hybi/handshake-fail-by-extensions-header-expected.txt: Added. 34 * http/tests/websocket/tests/hybi/handshake-fail-by-extensions-header.html: Added. 35 * http/tests/websocket/tests/hybi/handshake-fail-by-extensions-header_wsh.py: Added. 36 * http/tests/websocket/tests/hybi/handshake-fail-by-maxlength_wsh.py: 37 * http/tests/websocket/tests/hybi/handshake-fail-by-no-accept-header-expected.txt: Added. 38 * http/tests/websocket/tests/hybi/handshake-fail-by-no-accept-header.html: Added. 39 * http/tests/websocket/tests/hybi/handshake-fail-by-no-accept-header_wsh.py: Added. 40 * http/tests/websocket/tests/hybi/handshake-fail-by-no-connection-header_wsh.py: 41 * http/tests/websocket/tests/hybi/handshake-fail-by-no-cr_wsh.py: 42 * http/tests/websocket/tests/hybi/handshake-fail-by-no-upgrade-header_wsh.py: 43 * http/tests/websocket/tests/hybi/handshake-fail-by-prepended-null_wsh.py: 44 * http/tests/websocket/tests/hybi/handshake-fail-by-wrong-accept-header-expected.txt: Added. 45 * http/tests/websocket/tests/hybi/handshake-fail-by-wrong-accept-header.html: Added. 46 * http/tests/websocket/tests/hybi/handshake-fail-by-wrong-accept-header_wsh.py: Added. 47 * http/tests/websocket/tests/hybi/long-invalid-header_wsh.py: 48 * http/tests/websocket/tests/hybi/workers/resources/echo-challenge_wsh.py: 49 1 50 2011-07-13 MORITA Hajime <morrita@google.com> 2 51 -
trunk/LayoutTests/http/tests/websocket/tests/handler_map.txt
r90445 r90979 1 1 # websocket handler map file. 2 2 # request to '/' will be handled by echo-location_wsh.py 3 / /websocket/tests/hixie76/echo-location 3 # hybi/echo-location_wsh.py can handle both hixie-76 and hybi-10 protocols. 4 / /websocket/tests/hybi/echo-location -
trunk/LayoutTests/http/tests/websocket/tests/hybi/bad-handshake-crash_wsh.py
r90726 r90979 1 from mod_pywebsocket.handshake.hybi06 import compute_accept 2 3 1 4 def web_socket_do_extra_handshake(request): 2 msg = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"3 msg += "Upgrade: WebSocket\r\n"5 msg = "HTTP/1.1 101 Switching Protocols\r\n" 6 msg += "Upgrade: websocket\r\n" 4 7 msg += "Connection: Upgrade\r\n" 5 msg += "Sec-WebSocket-Location: " + request.ws_location + "\r\n" 6 msg += "Sec-WebSocket-Origin: " + request.ws_origin + "\r\n" 8 msg += "Sec-WebSocket-Accept: %s\r\n" % compute_accept(request.headers_in["Sec-WebSocket-Key"])[0] 7 9 msg += "\xa5:\r\n" 8 10 msg += "\r\n" 9 msg += request.ws_challenge_md510 11 request.connection.write(msg) 11 12 print msg -
trunk/LayoutTests/http/tests/websocket/tests/hybi/echo-challenge_wsh.py
r90726 r90979 7 7 8 8 def web_socket_transfer_data(request): 9 msgutil.send_message(request, _hexify(request.ws_challenge)) 10 11 12 def _hexify(bytes): 13 return ':'.join(['%02X' % ord(byte) for byte in bytes]) 9 msgutil.send_message(request, request.headers_in['Sec-WebSocket-Key']) -
trunk/LayoutTests/http/tests/websocket/tests/hybi/echo-location_wsh.py
r90726 r90979 1 # Copyright (C) 20 09Google Inc. All rights reserved.1 # Copyright (C) 2011 Google Inc. All rights reserved. 2 2 # 3 3 # Redistribution and use in source and binary forms, with or without … … 29 29 30 30 from mod_pywebsocket import msgutil 31 from mod_pywebsocket.handshake._base import build_location 31 32 32 33 … … 36 37 37 38 def web_socket_transfer_data(request): 38 print request.ws_location 39 msgutil.send_message(request, request.ws_location) 39 if hasattr(request, 'ws_location'): 40 location = request.ws_location 41 else: 42 # When hybi protocol is used, pywebsocket does not provide 43 # ws_location attribute because servers are not required to send 44 # Sec-WebSocket-Location header according to the protocol 45 # specification. If ws_location attribute is not available, 46 # we use pywebsocket's internal function "build_function" 47 # to obtain the identical value. 48 location = build_location(request) 49 msgutil.send_message(request, location) -
trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-maxlength_wsh.py
r90726 r90979 21 21 22 22 23 from mod_pywebsocket.handshake.hybi06 import compute_accept 24 25 23 26 def web_socket_do_extra_handshake(request): 24 27 # This will cause the handshake to fail because it pushes the length of the 25 28 # status line past 1024 characters 26 29 msg = '.' * 1024 27 msg += 'HTTP/1.1 101 WebSocket Protocol Handshake\r\n'28 msg += 'Upgrade: WebSocket\r\n'30 msg += 'HTTP/1.1 101 Switching Protocols\r\n' 31 msg += 'Upgrade: websocket\r\n' 29 32 msg += 'Connection: Upgrade\r\n' 30 msg += 'Sec-WebSocket-Location: ' + request.ws_location + '\r\n' 31 msg += 'Sec-WebSocket-Origin: ' + request.ws_origin + '\r\n' 33 msg += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0] 32 34 msg += '\r\n' 33 msg += request.ws_challenge_md534 35 request.connection.write(msg) 35 36 raise Exception('abort the connection') # Prevents pywebsocket from sending its own handshake message. -
trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-no-connection-header_wsh.py
r90726 r90979 1 from mod_pywebsocket.handshake.hybi06 import compute_accept 2 3 1 4 def web_socket_do_extra_handshake(request): 2 msg = 'HTTP/1.1 101 WebSocket Protocol Handshake\r\n'3 msg += 'Upgrade: WebSocket\r\n'5 msg = 'HTTP/1.1 101 Switching Protocols\r\n' 6 msg += 'Upgrade: websocket\r\n' 4 7 # Missing 'Connection: Upgrade\r\n' 5 msg += 'Sec-WebSocket-Location: ' + request.ws_location + '\r\n' 6 msg += 'Sec-WebSocket-Origin: ' + request.ws_origin + '\r\n' 8 msg += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0] 7 9 msg += '\r\n' 8 msg += request.ws_challenge_md59 10 request.connection.write(msg) 10 11 print msg -
trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-no-cr_wsh.py
r90726 r90979 1 from mod_pywebsocket.handshake.hybi06 import compute_accept 2 3 1 4 def web_socket_do_extra_handshake(request): 2 msg = 'HTTP/1.1 101 WebSocket Protocol Handshake\n' # Does not end with "\r\n".3 msg += 'Upgrade: WebSocket\r\n'5 msg = 'HTTP/1.1 101 Switching Protocols\n' # Does not end with "\r\n". 6 msg += 'Upgrade: websocket\r\n' 4 7 msg += 'Connection: Upgrade\r\n' 5 msg += 'Sec-WebSocket-Location: ' + request.ws_location + '\r\n' 6 msg += 'Sec-WebSocket-Origin: ' + request.ws_origin + '\r\n' 8 msg += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0] 7 9 msg += '\r\n' 8 msg += request.ws_challenge_md59 10 request.connection.write(msg) 10 11 print msg -
trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-no-upgrade-header_wsh.py
r90726 r90979 1 from mod_pywebsocket.handshake.hybi06 import compute_accept 2 3 1 4 def web_socket_do_extra_handshake(request): 2 msg = 'HTTP/1.1 101 WebSocket Protocol Handshake\r\n'3 # Missing 'Upgrade: WebSocket\r\n'5 msg = 'HTTP/1.1 101 Switching Protocols\r\n' 6 # Missing 'Upgrade: websocket\r\n' 4 7 msg += 'Connection: Upgrade\r\n' 5 msg += 'Sec-WebSocket-Location: ' + request.ws_location + '\r\n' 6 msg += 'Sec-WebSocket-Origin: ' + request.ws_origin + '\r\n' 8 msg += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0] 7 9 msg += '\r\n' 8 msg += request.ws_challenge_md59 10 request.connection.write(msg) 10 11 print msg -
trunk/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-prepended-null_wsh.py
r90726 r90979 20 20 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 21 22 22 23 import time 24 from mod_pywebsocket import stream 25 from mod_pywebsocket.handshake.hybi06 import compute_accept 23 26 24 27 … … 29 32 # to send more data - it should abort after reading a reasonable number of 30 33 # bytes (set arbitrarily to 1024). 31 frame = '\0Frame-contains-thirty-two-bytes'34 frame = stream.create_text_frame('\0Frame-contains-thirty-two-bytes') 32 35 33 36 msg = frame 34 msg += 'HTTP/1.1 101 WebSocket Protocol Handshake\r\n'35 msg += 'Upgrade: WebSocket\r\n'37 msg += 'HTTP/1.1 101 Switching Protocols\r\n' 38 msg += 'Upgrade: websocket\r\n' 36 39 msg += 'Connection: Upgrade\r\n' 37 msg += 'Sec-WebSocket-Location: ' + request.ws_location + '\r\n' 38 msg += 'Sec-WebSocket-Origin: ' + request.ws_origin + '\r\n' 40 msg += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0] 39 41 msg += '\r\n' 40 msg += request.ws_challenge_md541 42 request.connection.write(msg) 42 43 # continue writing data until the client disconnects -
trunk/LayoutTests/http/tests/websocket/tests/hybi/long-invalid-header_wsh.py
r90726 r90979 3 3 msg += ("p" * 1024) + "\r\n" 4 4 msg += "\r\n" 5 msg += request.ws_challenge_md56 5 request.connection.write(msg) 7 6 raise Exception("Abort the connection") # Prevents pywebsocket from sending its own handshake message. -
trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/echo-challenge_wsh.py
r90726 r90979 7 7 8 8 def web_socket_transfer_data(request): 9 msgutil.send_message(request, _hexify(request.ws_challenge)) 10 11 12 def _hexify(bytes): 13 return ':'.join(['%02X' % ord(byte) for byte in bytes]) 9 msgutil.send_message(request, request.headers_in['Sec-WebSocket-Key']) -
trunk/Source/WebCore/ChangeLog
r90976 r90979 1 2011-07-13 Yuta Kitamura <yutak@chromium.org> 2 3 WebSocket: Implement hybi handshake 4 https://bugs.webkit.org/show_bug.cgi?id=64344 5 6 Reviewed by Kent Tamura. 7 8 Implement WebSocket handshake which is described at 9 <http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#section-5.1>. 10 11 Notable differences from hixie-76 protocol are: 12 - Challenge-response scheme has been changed dramatically. 13 - Servers do not send Sec-WebSocket-Location and Sec-WebSocket-Origin anymore. 14 - The value of "Upgrade" header has been changed to "websocket" (lower-case only). 15 - "Origin" header in client's request is renamed to "Sec-WebSocket-Origin". 16 17 New tests: http/tests/websocket/tests/hybi/handshake-fail-by-extensions-header.html 18 http/tests/websocket/tests/hybi/handshake-fail-by-no-accept-header.html 19 http/tests/websocket/tests/hybi/handshake-fail-by-wrong-accept-header.html 20 21 Note: Tests under hybi/ directory (including the new ones) are skipped and cannot be enabled 22 yet, because pywebsocket does not accept requests from half-baked client implementation 23 (i.e. hybi handshake + hixie-76 framing). They will be unskipped when hybi framing is landed 24 in WebCore. 25 26 * websockets/WebSocketHandshake.cpp: 27 Functions and members only used for hixie-76 handshake are renamed so that they are not confused 28 with hybi-10's ones. 29 (WebCore::generateHixie76SecWebSocketKey): 30 (WebCore::generateHixie76Key3): 31 (WebCore::generateHixie76ExpectedChallengeResponse): 32 (WebCore::generateSecWebSocketKey): 33 Generates a value for Sec-WebSocket-Key as stated in hybi-10. 34 (WebCore::getExpectedWebSocketAccept): 35 Calculates the expected value of Sec-WebSocket-Accept. 36 (WebCore::WebSocketHandshake::WebSocketHandshake): 37 (WebCore::WebSocketHandshake::clientHandshakeMessage): 38 (WebCore::WebSocketHandshake::clientHandshakeRequest): 39 (WebCore::WebSocketHandshake::readServerHandshake): 40 (WebCore::WebSocketHandshake::serverWebSocketAccept): 41 (WebCore::WebSocketHandshake::serverWebSocketExtensions): 42 (WebCore::WebSocketHandshake::checkResponseHeaders): 43 * websockets/WebSocketHandshake.h: 44 1 45 2011-07-13 MORITA Hajime <morrita@google.com> 2 46 -
trunk/Source/WebCore/websockets/WebSocketHandshake.cpp
r90704 r90979 36 36 #include "WebSocketHandshake.h" 37 37 38 #include "Base64.h" 38 39 #include "Cookie.h" 39 40 #include "CookieJar.h" … … 47 48 #include <wtf/CryptographicallyRandomNumber.h> 48 49 #include <wtf/MD5.h> 50 #include <wtf/SHA1.h> 49 51 #include <wtf/StdLibExtras.h> 50 52 #include <wtf/StringExtras.h> … … 107 109 } 108 110 109 static void generate SecWebSocketKey(uint32_t& number, String& key)111 static void generateHixie76SecWebSocketKey(uint32_t& number, String& key) 110 112 { 111 113 uint32_t space = randomNumberLessThan(12) + 1; … … 132 134 } 133 135 134 static void generate Key3(unsigned char key3[8])136 static void generateHixie76Key3(unsigned char key3[8]) 135 137 { 136 138 cryptographicallyRandomValues(key3, 8); … … 147 149 } 148 150 149 static void generate ExpectedChallengeResponse(uint32_t number1, uint32_t number2, unsigned char key3[8], unsigned char expectedChallenge[16])151 static void generateHixie76ExpectedChallengeResponse(uint32_t number1, uint32_t number2, unsigned char key3[8], unsigned char expectedChallenge[16]) 150 152 { 151 153 unsigned char challenge[16]; … … 160 162 } 161 163 164 static String generateSecWebSocketKey() 165 { 166 static const size_t nonceSize = 16; 167 unsigned char key[nonceSize]; 168 cryptographicallyRandomValues(key, nonceSize); 169 return base64Encode(reinterpret_cast<char*>(key), nonceSize); 170 } 171 172 static String getExpectedWebSocketAccept(const String& secWebSocketKey) 173 { 174 static const char* const webSocketKeyGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 175 static const size_t sha1HashSize = 20; // FIXME: This should be defined in SHA1.h. 176 SHA1 sha1; 177 CString keyData = secWebSocketKey.ascii(); 178 sha1.addBytes(reinterpret_cast<const uint8_t*>(keyData.data()), keyData.length()); 179 sha1.addBytes(reinterpret_cast<const uint8_t*>(webSocketKeyGUID), strlen(webSocketKeyGUID)); 180 Vector<uint8_t, sha1HashSize> hash; 181 sha1.computeHash(hash); 182 return base64Encode(reinterpret_cast<const char*>(hash.data()), sha1HashSize); 183 } 184 162 185 WebSocketHandshake::WebSocketHandshake(const KURL& url, const String& protocol, ScriptExecutionContext* context, bool useHixie76Protocol) 163 186 : m_url(url) … … 168 191 , m_mode(Incomplete) 169 192 { 170 uint32_t number1; 171 uint32_t number2; 172 generateSecWebSocketKey(number1, m_secWebSocketKey1); 173 generateSecWebSocketKey(number2, m_secWebSocketKey2); 174 generateKey3(m_key3); 175 generateExpectedChallengeResponse(number1, number2, m_key3, m_expectedChallengeResponse); 193 if (m_useHixie76Protocol) { 194 uint32_t number1; 195 uint32_t number2; 196 generateHixie76SecWebSocketKey(number1, m_hixie76SecWebSocketKey1); 197 generateHixie76SecWebSocketKey(number2, m_hixie76SecWebSocketKey2); 198 generateHixie76Key3(m_hixie76Key3); 199 generateHixie76ExpectedChallengeResponse(number1, number2, m_hixie76Key3, m_hixie76ExpectedChallengeResponse); 200 } else { 201 m_secWebSocketKey = generateSecWebSocketKey(); 202 m_expectedAccept = getExpectedWebSocketAccept(m_secWebSocketKey); 203 } 176 204 } 177 205 … … 235 263 236 264 Vector<String> fields; 237 fields.append("Upgrade: WebSocket"); 265 if (m_useHixie76Protocol) 266 fields.append("Upgrade: WebSocket"); 267 else 268 fields.append("Upgrade: websocket"); 238 269 fields.append("Connection: Upgrade"); 239 270 fields.append("Host: " + hostName(m_url, m_secure)); 240 fields.append("Origin: " + clientOrigin()); 271 if (m_useHixie76Protocol) 272 fields.append("Origin: " + clientOrigin()); 273 else 274 fields.append("Sec-WebSocket-Origin: " + clientOrigin()); 241 275 if (!m_clientProtocol.isEmpty()) 242 276 fields.append("Sec-WebSocket-Protocol: " + m_clientProtocol); … … 251 285 } 252 286 253 fields.append("Sec-WebSocket-Key1: " + m_secWebSocketKey1); 254 fields.append("Sec-WebSocket-Key2: " + m_secWebSocketKey2); 287 if (m_useHixie76Protocol) { 288 fields.append("Sec-WebSocket-Key1: " + m_hixie76SecWebSocketKey1); 289 fields.append("Sec-WebSocket-Key2: " + m_hixie76SecWebSocketKey2); 290 } else { 291 fields.append("Sec-WebSocket-Key: " + m_secWebSocketKey); 292 // FIXME: Current version of pywebsocket only accepts version value of 7, 293 // while hybi-10 requires this value to be 8. Should be fixed when 294 // a new version of pywebsocket is released. 295 fields.append("Sec-WebSocket-Version: 7"); 296 } 255 297 256 298 // Fields in the handshake are sent by the client in a random order; the … … 266 308 267 309 CString handshakeHeader = builder.toString().utf8(); 310 // Hybi-10 handshake is complete at this point. 311 if (!m_useHixie76Protocol) 312 return handshakeHeader; 313 // Hixie-76 protocol requires sending eight-byte data (so-called "key3") after the request header fields. 268 314 char* characterBuffer = 0; 269 CString msg = CString::newUninitialized(handshakeHeader.length() + sizeof(m_ key3), characterBuffer);315 CString msg = CString::newUninitialized(handshakeHeader.length() + sizeof(m_hixie76Key3), characterBuffer); 270 316 memcpy(characterBuffer, handshakeHeader.data(), handshakeHeader.length()); 271 memcpy(characterBuffer + handshakeHeader.length(), m_ key3, sizeof(m_key3));317 memcpy(characterBuffer + handshakeHeader.length(), m_hixie76Key3, sizeof(m_hixie76Key3)); 272 318 return msg; 273 319 } … … 279 325 // m_key3 in WebSocketHandshakeRequest? 280 326 WebSocketHandshakeRequest request("GET", m_url); 281 request.addHeaderField("Upgrade", "WebSocket"); 327 if (m_useHixie76Protocol) 328 request.addHeaderField("Upgrade", "WebSocket"); 329 else 330 request.addHeaderField("Upgrade", "websocket"); 282 331 request.addHeaderField("Connection", "Upgrade"); 283 332 request.addHeaderField("Host", hostName(m_url, m_secure)); 284 request.addHeaderField("Origin", clientOrigin()); 333 if (m_useHixie76Protocol) 334 request.addHeaderField("Origin", clientOrigin()); 335 else 336 request.addHeaderField("Sec-WebSocket-Origin", clientOrigin()); 285 337 if (!m_clientProtocol.isEmpty()) 286 338 request.addHeaderField("Sec-WebSocket-Protocol:", m_clientProtocol); … … 295 347 } 296 348 297 request.addHeaderField("Sec-WebSocket-Key1", m_secWebSocketKey1); 298 request.addHeaderField("Sec-WebSocket-Key2", m_secWebSocketKey2); 299 request.setKey3(m_key3); 349 if (m_useHixie76Protocol) { 350 request.addHeaderField("Sec-WebSocket-Key1", m_hixie76SecWebSocketKey1); 351 request.addHeaderField("Sec-WebSocket-Key2", m_hixie76SecWebSocketKey2); 352 request.setKey3(m_hixie76Key3); 353 } else { 354 request.addHeaderField("Sec-WebSocket-Key", m_secWebSocketKey); 355 request.addHeaderField("Sec-WebSocket-Version", "7"); // FIXME: See FIXME in clientHandshakeMessage(). 356 } 300 357 301 358 return request; … … 349 406 return p - header; 350 407 } 351 if (len < static_cast<size_t>(p - header + sizeof(m_expectedChallengeResponse))) { 408 409 if (!m_useHixie76Protocol) { // Hybi-10 handshake is complete at this point. 410 m_mode = Connected; 411 return p - header; 412 } 413 414 // In hixie-76 protocol, server's handshake contains sixteen-byte data (called "challenge response") 415 // after the header fields. 416 if (len < static_cast<size_t>(p - header + sizeof(m_hixie76ExpectedChallengeResponse))) { 352 417 // Just hasn't been received /expected/ yet. 353 418 m_mode = Incomplete; 354 419 return -1; 355 420 } 421 356 422 m_response.setChallengeResponse(static_cast<const unsigned char*>(static_cast<const void*>(p))); 357 if (memcmp(p, m_ expectedChallengeResponse, sizeof(m_expectedChallengeResponse))) {423 if (memcmp(p, m_hixie76ExpectedChallengeResponse, sizeof(m_hixie76ExpectedChallengeResponse))) { 358 424 m_mode = Failed; 359 return (p - header) + sizeof(m_ expectedChallengeResponse);425 return (p - header) + sizeof(m_hixie76ExpectedChallengeResponse); 360 426 } 361 427 m_mode = Connected; 362 return (p - header) + sizeof(m_ expectedChallengeResponse);428 return (p - header) + sizeof(m_hixie76ExpectedChallengeResponse); 363 429 } 364 430 … … 406 472 { 407 473 return m_response.headerFields().get("connection"); 474 } 475 476 String WebSocketHandshake::serverWebSocketAccept() const 477 { 478 return m_response.headerFields().get("sec-websocket-accept"); 479 } 480 481 String WebSocketHandshake::serverWebSocketExtensions() const 482 { 483 return m_response.headerFields().get("sec-websocket-extensions"); 408 484 } 409 485 … … 572 648 const String& serverUpgrade = this->serverUpgrade(); 573 649 const String& serverConnection = this->serverConnection(); 650 const String& serverWebSocketAccept = this->serverWebSocketAccept(); 651 const String& serverWebSocketExtensions = this->serverWebSocketExtensions(); 574 652 575 653 if (serverUpgrade.isNull()) { … … 581 659 return false; 582 660 } 583 if (serverWebSocketOrigin.isNull()) { 584 m_failureReason = "Error during WebSocket handshake: 'Sec-WebSocket-Origin' header is missing"; 585 return false; 586 } 587 if (serverWebSocketLocation.isNull()) { 588 m_failureReason = "Error during WebSocket handshake: 'Sec-WebSocket-Location' header is missing"; 589 return false; 661 if (m_useHixie76Protocol) { 662 if (serverWebSocketOrigin.isNull()) { 663 m_failureReason = "Error during WebSocket handshake: 'Sec-WebSocket-Origin' header is missing"; 664 return false; 665 } 666 if (serverWebSocketLocation.isNull()) { 667 m_failureReason = "Error during WebSocket handshake: 'Sec-WebSocket-Location' header is missing"; 668 return false; 669 } 670 } else { 671 if (serverWebSocketAccept.isNull()) { 672 m_failureReason = "Error during WebSocket handshake: 'Sec-WebSocket-Accept' header is missing"; 673 return false; 674 } 590 675 } 591 676 … … 599 684 } 600 685 601 if (clientOrigin() != serverWebSocketOrigin) { 602 m_failureReason = "Error during WebSocket handshake: origin mismatch: " + clientOrigin() + " != " + serverWebSocketOrigin; 603 return false; 604 } 605 if (clientLocation() != serverWebSocketLocation) { 606 m_failureReason = "Error during WebSocket handshake: location mismatch: " + clientLocation() + " != " + serverWebSocketLocation; 607 return false; 608 } 609 if (!m_clientProtocol.isEmpty() && m_clientProtocol != serverWebSocketProtocol) { 610 m_failureReason = "Error during WebSocket handshake: protocol mismatch: " + m_clientProtocol + " != " + serverWebSocketProtocol; 611 return false; 686 if (m_useHixie76Protocol) { 687 if (clientOrigin() != serverWebSocketOrigin) { 688 m_failureReason = "Error during WebSocket handshake: origin mismatch: " + clientOrigin() + " != " + serverWebSocketOrigin; 689 return false; 690 } 691 if (clientLocation() != serverWebSocketLocation) { 692 m_failureReason = "Error during WebSocket handshake: location mismatch: " + clientLocation() + " != " + serverWebSocketLocation; 693 return false; 694 } 695 if (!m_clientProtocol.isEmpty() && m_clientProtocol != serverWebSocketProtocol) { 696 m_failureReason = "Error during WebSocket handshake: protocol mismatch: " + m_clientProtocol + " != " + serverWebSocketProtocol; 697 return false; 698 } 699 } else { 700 if (serverWebSocketAccept != m_expectedAccept) { 701 m_failureReason = "Error during WebSocket handshake: Sec-WebSocket-Accept mismatch"; 702 return false; 703 } 704 if (!serverWebSocketExtensions.isNull()) { 705 // WebSocket protocol extensions are not supported yet. 706 // We do not send Sec-WebSocket-Extensions header in our request, thus 707 // servers should not return this header, either. 708 m_failureReason = "Error during WebSocket handshake: Sec-WebSocket-Extensions header is invalid"; 709 return false; 710 } 612 711 } 613 712 return true; -
trunk/Source/WebCore/websockets/WebSocketHandshake.h
r90704 r90979 1 1 /* 2 * Copyright (C) 20 09Google Inc. All rights reserved.2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 74 74 String failureReason() const; // Returns a string indicating the reason of failure if mode() == Failed. 75 75 76 String serverWebSocketOrigin() const; 77 String serverWebSocketLocation() const; 76 String serverWebSocketOrigin() const; // Only for hixie-76 handshake. 77 String serverWebSocketLocation() const; // Only for hixie-76 handshake. 78 78 String serverWebSocketProtocol() const; 79 79 String serverSetCookie() const; … … 81 81 String serverUpgrade() const; 82 82 String serverConnection() const; 83 String serverWebSocketAccept() const; // Only for hybi-10 handshake. 84 String serverWebSocketExtensions() const; // Only for hybi-10 handshake. 83 85 84 86 const WebSocketHandshakeResponse& serverHandshakeResponse() const; … … 102 104 Mode m_mode; 103 105 104 String m_secWebSocketKey1;105 String m_secWebSocketKey2;106 unsigned char m_key3[8];107 unsigned char m_expectedChallengeResponse[16];108 109 106 WebSocketHandshakeResponse m_response; 110 107 111 108 String m_failureReason; 109 110 // For hixie-76 handshake. 111 String m_hixie76SecWebSocketKey1; 112 String m_hixie76SecWebSocketKey2; 113 unsigned char m_hixie76Key3[8]; 114 unsigned char m_hixie76ExpectedChallengeResponse[16]; 115 116 // For hybi-10 handshake. 117 String m_secWebSocketKey; 118 String m_expectedAccept; 112 119 }; 113 120
Note: See TracChangeset
for help on using the changeset viewer.