Changeset 61671 in webkit
- Timestamp:
- Jun 23, 2010 12:37:50 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/websocket/tests/long-invalid-header-expected.txt
r59903 r61671 1 CONSOLE MESSAGE: line 0: Unexpected CR in name at pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp ...1 CONSOLE MESSAGE: line 0: Unexpected CR in name at pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp… 2 2 Make sure WebSocket gives errors on long invalid upgrade header. 3 3 -
trunk/WebCore/ChangeLog
r61670 r61671 1 2010-06-22 Yuta Kitamura <yutak@chromium.org> 2 3 Reviewed by Alexey Proskuryakov. 4 5 Add a new class that stores information about WebSocket handshake response. 6 7 In the future, instances of the new class will be passed to the Web Inspector 8 so that it will be able to display information about WebSocket handshake 9 response. 10 11 WebSocket: Add WebSocketHandshakeResponse 12 https://bugs.webkit.org/show_bug.cgi?id=38728 13 14 Test: websocket/tests/handshake-fail-by-no-cr.html 15 16 * GNUmakefile.am: 17 * WebCore.gypi: 18 * WebCore.pro: 19 * WebCore.vcproj/WebCore.vcproj: 20 * WebCore.xcodeproj/project.pbxproj: 21 * websockets/WebSocketHandshake.cpp: 22 (WebCore::trimConsoleMessage): 23 (WebCore::WebSocketHandshake::readServerHandshake): 24 (WebCore::WebSocketHandshake::serverHandshakeResponse): 25 (WebCore::WebSocketHandshake::readStatusLine): Moved from extractResponseCode. 26 Add more error checks and make error messages more descriptive. 27 (WebCore::WebSocketHandshake::readHTTPHeaders): 28 (WebCore::WebSocketHandshake::processHeaders): 29 * websockets/WebSocketHandshake.h: 30 * websockets/WebSocketHandshakeResponse.cpp: Added. 31 (WebCore::WebSocketHandshakeResponse::ChallengeResponse::ChallengeResponse): 32 (WebCore::WebSocketHandshakeResponse::ChallengeResponse::set): 33 (WebCore::WebSocketHandshakeResponse::WebSocketHandshakeResponse): 34 (WebCore::WebSocketHandshakeResponse::~WebSocketHandshakeResponse): 35 (WebCore::WebSocketHandshakeResponse::statusCode): 36 (WebCore::WebSocketHandshakeResponse::setStatusCode): 37 (WebCore::WebSocketHandshakeResponse::statusText): 38 (WebCore::WebSocketHandshakeResponse::setStatusText): 39 (WebCore::WebSocketHandshakeResponse::headerFields): 40 (WebCore::WebSocketHandshakeResponse::addHeaderField): 41 (WebCore::WebSocketHandshakeResponse::clearHeaderFields): 42 (WebCore::WebSocketHandshakeResponse::challengeResponse): 43 (WebCore::WebSocketHandshakeResponse::setChallengeResponse): 44 * websockets/WebSocketHandshakeResponse.h: Added. 45 1 46 2010-06-23 Yuzo Fujishima <yuzo@google.com> 2 47 -
trunk/WebCore/GNUmakefile.am
r61665 r61671 3778 3778 WebCore/websockets/WebSocketHandshake.h \ 3779 3779 WebCore/websockets/WebSocketHandshakeRequest.cpp \ 3780 WebCore/websockets/WebSocketHandshakeRequest.h 3780 WebCore/websockets/WebSocketHandshakeRequest.h \ 3781 WebCore/websockets/WebSocketHandshakeResponse.cpp \ 3782 WebCore/websockets/WebSocketHandshakeResponse.h 3781 3783 3782 3784 if ENABLE_WORKERS -
trunk/WebCore/WebCore.gypi
r61665 r61671 3806 3806 'websockets/WebSocketHandshakeRequest.cpp', 3807 3807 'websockets/WebSocketHandshakeRequest.h', 3808 'websockets/WebSocketHandshakeResponse.cpp', 3809 'websockets/WebSocketHandshakeResponse.h', 3808 3810 'websockets/WorkerThreadableWebSocketChannel.cpp', 3809 3811 'websockets/WorkerThreadableWebSocketChannel.h', -
trunk/WebCore/WebCore.pro
r61665 r61671 2893 2893 websockets/WebSocketHandshake.h \ 2894 2894 websockets/WebSocketHandshakeRequest.h \ 2895 websockets/WebSocketHandshakeResponse.h \ 2895 2896 platform/network/qt/SocketStreamHandlePrivate.h 2896 2897 … … 2900 2901 websockets/WebSocketHandshake.cpp \ 2901 2902 websockets/WebSocketHandshakeRequest.cpp \ 2903 websockets/WebSocketHandshakeResponse.cpp \ 2902 2904 websockets/ThreadableWebSocketChannel.cpp \ 2903 2905 platform/network/SocketStreamErrorBase.cpp \ -
trunk/WebCore/WebCore.vcproj/WebCore.vcproj
r61665 r61671 47730 47730 </File> 47731 47731 <File 47732 RelativePath="..\websockets\WebSocketHandshakeResponse.cpp" 47733 > 47734 </File> 47735 <File 47736 RelativePath="..\websockets\WebSocketHandshakeResponse.h" 47737 > 47738 </File> 47739 <File 47732 47740 RelativePath="..\websockets\WorkerThreadableWebSocketChannel.cpp" 47733 47741 > -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r61665 r61671 1322 1322 7637C541112E7B74003D6CDC /* WebSocketHandshakeRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7637C540112E7B74003D6CDC /* WebSocketHandshakeRequest.cpp */; }; 1323 1323 7637C543112E7B7E003D6CDC /* WebSocketHandshakeRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 7637C542112E7B7E003D6CDC /* WebSocketHandshakeRequest.h */; }; 1324 767F99BE11A1194A0080C51D /* WebSocketHandshakeResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 767F99BD11A1194A0080C51D /* WebSocketHandshakeResponse.cpp */; }; 1325 767F99C011A119560080C51D /* WebSocketHandshakeResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 767F99BF11A119560080C51D /* WebSocketHandshakeResponse.h */; }; 1324 1326 7693BAD2106C2DCA007B0823 /* HaltablePlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 7693BACE106C2DCA007B0823 /* HaltablePlugin.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1325 1327 7693BAD3106C2DCA007B0823 /* PluginHalter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7693BACF106C2DCA007B0823 /* PluginHalter.cpp */; }; … … 6993 6995 7637C540112E7B74003D6CDC /* WebSocketHandshakeRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketHandshakeRequest.cpp; sourceTree = "<group>"; }; 6994 6996 7637C542112E7B7E003D6CDC /* WebSocketHandshakeRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketHandshakeRequest.h; sourceTree = "<group>"; }; 6997 767F99BD11A1194A0080C51D /* WebSocketHandshakeResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketHandshakeResponse.cpp; sourceTree = "<group>"; }; 6998 767F99BF11A119560080C51D /* WebSocketHandshakeResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketHandshakeResponse.h; sourceTree = "<group>"; }; 6995 6999 7693BACE106C2DCA007B0823 /* HaltablePlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HaltablePlugin.h; sourceTree = "<group>"; }; 6996 7000 7693BACF106C2DCA007B0823 /* PluginHalter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginHalter.cpp; sourceTree = "<group>"; }; … … 11793 11797 7637C540112E7B74003D6CDC /* WebSocketHandshakeRequest.cpp */, 11794 11798 7637C542112E7B7E003D6CDC /* WebSocketHandshakeRequest.h */, 11799 767F99BD11A1194A0080C51D /* WebSocketHandshakeResponse.cpp */, 11800 767F99BF11A119560080C51D /* WebSocketHandshakeResponse.h */, 11795 11801 5112247710CFB8F4008099D7 /* WorkerThreadableWebSocketChannel.cpp */, 11796 11802 5112247910CFB8FF008099D7 /* WorkerThreadableWebSocketChannel.h */, … … 19415 19421 51ABAE451043AB4A008C5260 /* WebSocketHandshake.h in Headers */, 19416 19422 7637C543112E7B7E003D6CDC /* WebSocketHandshakeRequest.h in Headers */, 19423 767F99C011A119560080C51D /* WebSocketHandshakeResponse.h in Headers */, 19417 19424 0FCF332D0F2B9A25004B6795 /* WebTiledLayer.h in Headers */, 19418 19425 85031B510A44EFC700F992E0 /* WheelEvent.h in Headers */, … … 21742 21749 51ABAE441043AB4A008C5260 /* WebSocketHandshake.cpp in Sources */, 21743 21750 7637C541112E7B74003D6CDC /* WebSocketHandshakeRequest.cpp in Sources */, 21751 767F99BE11A1194A0080C51D /* WebSocketHandshakeResponse.cpp in Sources */, 21744 21752 0FCF332C0F2B9A25004B6795 /* WebTiledLayer.mm in Sources */, 21745 21753 85031B500A44EFC700F992E0 /* WheelEvent.cpp in Sources */, -
trunk/WebCore/websockets/WebSocketHandshake.cpp
r61611 r61671 36 36 37 37 #include "AtomicString.h" 38 #include "CharacterNames.h" 38 39 #include "Cookie.h" 39 40 #include "CookieJar.h" … … 57 58 static const char randomCharacterInSecWebSocketKey[] = "!\"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; 58 59 59 static String extractResponseCode(const char* header, int len, size_t& lineLength)60 {61 const char* space1 = 0;62 const char* space2 = 0;63 const char* p;64 lineLength = 0;65 for (p = header; p - header < len; p++, lineLength++) {66 if (*p == ' ') {67 if (!space1)68 space1 = p;69 else if (!space2)70 space2 = p;71 } else if (*p == '\n')72 break;73 }74 if (p - header == len)75 return String();76 if (!space1 || !space2)77 return "";78 return String(space1 + 1, space2 - space1 - 1);79 }80 81 60 static String resourceName(const KURL& url) 82 61 { … … 103 82 } 104 83 84 static const size_t maxConsoleMessageSize = 128; 105 85 static String trimConsoleMessage(const char* p, size_t len) 106 86 { 107 String s = String(p, std::min<size_t>(len, 128));108 if (len > 128)109 s += "...";87 String s = String(p, std::min<size_t>(len, maxConsoleMessageSize)); 88 if (len > maxConsoleMessageSize) 89 s.append(horizontalEllipsis); 110 90 return s; 111 91 } … … 323 303 { 324 304 m_mode = Incomplete; 325 size_t lineLength;326 const String& code = extractResponseCode(header, len, lineLength);327 i f (code.isNull()) {328 // Just hasn't been received yet.305 int statusCode; 306 String statusText; 307 int lineLength = readStatusLine(header, len, statusCode, statusText); 308 if (lineLength == -1) 329 309 return -1; 330 } 331 if (code.isEmpty()) { 310 if (statusCode == -1) { 332 311 m_mode = Failed; 333 m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "No response code found: " + trimConsoleMessage(header, lineLength), 0, clientOrigin());334 312 return len; 335 313 } 336 LOG(Network, "response code: %s", code.utf8().data()); 337 if (code != "101") { 314 LOG(Network, "response code: %d", statusCode); 315 m_response.setStatusCode(statusCode); 316 m_response.setStatusText(statusText); 317 if (statusCode != 101) { 338 318 m_mode = Failed; 339 m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected response code:" + code, 0, clientOrigin());319 m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, String::format("Unexpected response code: %d", statusCode), 0, clientOrigin()); 340 320 return len; 341 321 } … … 346 326 return -1; 347 327 } 348 HTTPHeaderMap headers; 349 const char* headerFields = strnstr(header, "\r\n", len); // skip status line 350 ASSERT(headerFields); 351 headerFields += 2; // skip "\r\n". 352 const char* p = readHTTPHeaders(headerFields, header + len, &headers); 328 const char* p = readHTTPHeaders(header + lineLength, header + len); 353 329 if (!p) { 354 330 LOG(Network, "readHTTPHeaders failed"); … … 356 332 return len; 357 333 } 358 if (!processHeaders(headers) || !checkResponseHeaders()) { 334 processHeaders(); 335 if (!checkResponseHeaders()) { 359 336 LOG(Network, "header process failed"); 360 337 m_mode = Failed; … … 366 343 return -1; 367 344 } 345 m_response.setChallengeResponse(static_cast<const unsigned char*>(static_cast<const void*>(p))); 368 346 if (memcmp(p, m_expectedChallengeResponse, sizeof(m_expectedChallengeResponse))) { 369 347 m_mode = Failed; … … 427 405 { 428 406 m_setCookie2 = setCookie2; 407 } 408 409 const WebSocketHandshakeResponse& WebSocketHandshake::serverHandshakeResponse() const 410 { 411 return m_response; 429 412 } 430 413 … … 437 420 } 438 421 439 const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* end, HTTPHeaderMap* headers) 440 { 422 // Returns the header length (including "\r\n"), or -1 if we have not received enough data yet. 423 // If the line is malformed or the status code is not a 3-digit number, 424 // statusCode and statusText will be set to -1 and a null string, respectively. 425 int WebSocketHandshake::readStatusLine(const char* header, size_t headerLength, int& statusCode, String& statusText) 426 { 427 statusCode = -1; 428 statusText = String(); 429 430 const char* space1 = 0; 431 const char* space2 = 0; 432 const char* p; 433 size_t consumedLength; 434 435 for (p = header, consumedLength = 0; consumedLength < headerLength; p++, consumedLength++) { 436 if (*p == ' ') { 437 if (!space1) 438 space1 = p; 439 else if (!space2) 440 space2 = p; 441 } else if (*p == '\n') 442 break; 443 } 444 if (consumedLength == headerLength) 445 return -1; // We have not received '\n' yet. 446 447 const char* end = p + 1; 448 if (end - header > INT_MAX) { 449 m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line is too long: " + trimConsoleMessage(header, maxConsoleMessageSize + 1), 0, clientOrigin()); 450 return INT_MAX; 451 } 452 int lineLength = end - header; 453 454 if (!space1 || !space2) { 455 m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "No response code found: " + trimConsoleMessage(header, lineLength - 1), 0, clientOrigin()); 456 return lineLength; 457 } 458 459 // The line must end with "\r\n". 460 if (*(end - 2) != '\r') { 461 m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line does not end with CRLF", 0, clientOrigin()); 462 return lineLength; 463 } 464 465 String statusCodeString(space1 + 1, space2 - space1 - 1); 466 if (statusCodeString.length() != 3) // Status code must consist of three digits. 467 return lineLength; 468 for (int i = 0; i < 3; ++i) 469 if (statusCodeString[i] < '0' || statusCodeString[i] > '9') { 470 m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Invalid status code: " + statusCodeString, 0, clientOrigin()); 471 return lineLength; 472 } 473 474 bool ok = false; 475 statusCode = statusCodeString.toInt(&ok); 476 ASSERT(ok); 477 478 statusText = String(space2 + 1, end - space2 - 3); // Exclude "\r\n". 479 return lineLength; 480 } 481 482 const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* end) 483 { 484 m_response.clearHeaderFields(); 485 441 486 Vector<char> name; 442 487 Vector<char> value; … … 462 507 break; 463 508 default: 464 if (*p >= 0x41 && *p <= 0x5a) 465 name.append(*p + 0x20); 466 else 467 name.append(*p); 509 name.append(*p); 468 510 continue; 469 511 } … … 506 548 } 507 549 LOG(Network, "name=%s value=%s", nameStr.string().utf8().data(), valueStr.utf8().data()); 508 headers->add(nameStr, valueStr);550 m_response.addHeaderField(nameStr, valueStr); 509 551 } 510 552 ASSERT_NOT_REACHED(); … … 512 554 } 513 555 514 bool WebSocketHandshake::processHeaders(const HTTPHeaderMap& headers) 515 { 516 for (HTTPHeaderMap::const_iterator it = headers.begin(); it != headers.end(); ++it) { 517 switch (m_mode) { 518 case Normal: 519 if (it->first == "sec-websocket-origin") 520 m_wsOrigin = it->second; 521 else if (it->first == "sec-websocket-location") 522 m_wsLocation = it->second; 523 else if (it->first == "sec-websocket-protocol") 524 m_wsProtocol = it->second; 525 else if (it->first == "set-cookie") 526 m_setCookie = it->second; 527 else if (it->first == "set-cookie2") 528 m_setCookie2 = it->second; 529 continue; 530 case Incomplete: 531 case Failed: 532 case Connected: 533 ASSERT_NOT_REACHED(); 534 } 535 ASSERT_NOT_REACHED(); 536 } 537 return true; 556 void WebSocketHandshake::processHeaders() 557 { 558 ASSERT(m_mode == Normal); 559 const HTTPHeaderMap& headers = m_response.headerFields(); 560 m_wsOrigin = headers.get("sec-websocket-origin"); 561 m_wsLocation = headers.get("sec-websocket-location"); 562 m_wsProtocol = headers.get("sec-websocket-protocol"); 563 m_setCookie = headers.get("set-cookie"); 564 m_setCookie2 = headers.get("set-cookie2"); 538 565 } 539 566 -
trunk/WebCore/websockets/WebSocketHandshake.h
r59903 r61671 37 37 #include "PlatformString.h" 38 38 #include "WebSocketHandshakeRequest.h" 39 #include "WebSocketHandshakeResponse.h" 39 40 #include <wtf/Noncopyable.h> 40 41 41 42 namespace WebCore { 42 43 43 class HTTPHeaderMap;44 44 class ScriptExecutionContext; 45 45 … … 87 87 void setServerSetCookie2(const String& setCookie2); 88 88 89 const WebSocketHandshakeResponse& serverHandshakeResponse() const; 90 89 91 private: 90 92 KURL httpURLForAuthenticationAndCookies() const; 91 93 94 int readStatusLine(const char* header, size_t headerLength, int& statusCode, String& statusText); 95 92 96 // Reads all headers except for the two predefined ones. 93 const char* readHTTPHeaders(const char* start, const char* end , HTTPHeaderMap* headers);94 bool processHeaders(const HTTPHeaderMap& headers);97 const char* readHTTPHeaders(const char* start, const char* end); 98 void processHeaders(); 95 99 bool checkResponseHeaders(); 96 100 … … 112 116 unsigned char m_key3[8]; 113 117 unsigned char m_expectedChallengeResponse[16]; 118 119 WebSocketHandshakeResponse m_response; 114 120 }; 115 121
Note: See TracChangeset
for help on using the changeset viewer.