| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 } | 215 } |
| 216 | 216 |
| 217 const char* DOMWebSocket::subprotocolSeperator() | 217 const char* DOMWebSocket::subprotocolSeperator() |
| 218 { | 218 { |
| 219 return ", "; | 219 return ", "; |
| 220 } | 220 } |
| 221 | 221 |
| 222 DOMWebSocket::DOMWebSocket(ExecutionContext* context) | 222 DOMWebSocket::DOMWebSocket(ExecutionContext* context) |
| 223 : ActiveScriptWrappable(this) | 223 : ActiveScriptWrappable(this) |
| 224 , ActiveDOMObject(context) | 224 , ActiveDOMObject(context) |
| 225 , m_state(CONNECTING) | 225 , m_state(kConnecting) |
| 226 , m_bufferedAmount(0) | 226 , m_bufferedAmount(0) |
| 227 , m_consumedBufferedAmount(0) | 227 , m_consumedBufferedAmount(0) |
| 228 , m_bufferedAmountAfterClose(0) | 228 , m_bufferedAmountAfterClose(0) |
| 229 , m_binaryType(BinaryTypeBlob) | 229 , m_binaryType(BinaryTypeBlob) |
| 230 , m_subprotocol("") | 230 , m_subprotocol("") |
| 231 , m_extensions("") | 231 , m_extensions("") |
| 232 , m_eventQueue(EventQueue::create(this)) | 232 , m_eventQueue(EventQueue::create(this)) |
| 233 , m_bufferedAmountConsumeTimer(this, &DOMWebSocket::reflectBufferedAmountCon
sumption) | 233 , m_bufferedAmountConsumeTimer(this, &DOMWebSocket::reflectBufferedAmountCon
sumption) |
| 234 { | 234 { |
| 235 } | 235 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 m_url = KURL(KURL(), url); | 286 m_url = KURL(KURL(), url); |
| 287 | 287 |
| 288 if (getExecutionContext()->securityContext().getInsecureRequestPolicy() & kU
pgradeInsecureRequests && m_url.protocol() == "ws") { | 288 if (getExecutionContext()->securityContext().getInsecureRequestPolicy() & kU
pgradeInsecureRequests && m_url.protocol() == "ws") { |
| 289 UseCounter::count(getExecutionContext(), UseCounter::UpgradeInsecureRequ
estsUpgradedRequest); | 289 UseCounter::count(getExecutionContext(), UseCounter::UpgradeInsecureRequ
estsUpgradedRequest); |
| 290 m_url.setProtocol("wss"); | 290 m_url.setProtocol("wss"); |
| 291 if (m_url.port() == 80) | 291 if (m_url.port() == 80) |
| 292 m_url.setPort(443); | 292 m_url.setPort(443); |
| 293 } | 293 } |
| 294 | 294 |
| 295 if (!m_url.isValid()) { | 295 if (!m_url.isValid()) { |
| 296 m_state = CLOSED; | 296 m_state = kClosed; |
| 297 exceptionState.throwDOMException(SyntaxError, "The URL '" + url + "' is
invalid."); | 297 exceptionState.throwDOMException(SyntaxError, "The URL '" + url + "' is
invalid."); |
| 298 return; | 298 return; |
| 299 } | 299 } |
| 300 if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { | 300 if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { |
| 301 m_state = CLOSED; | 301 m_state = kClosed; |
| 302 exceptionState.throwDOMException(SyntaxError, "The URL's scheme must be
either 'ws' or 'wss'. '" + m_url.protocol() + "' is not allowed."); | 302 exceptionState.throwDOMException(SyntaxError, "The URL's scheme must be
either 'ws' or 'wss'. '" + m_url.protocol() + "' is not allowed."); |
| 303 return; | 303 return; |
| 304 } | 304 } |
| 305 | 305 |
| 306 if (m_url.hasFragmentIdentifier()) { | 306 if (m_url.hasFragmentIdentifier()) { |
| 307 m_state = CLOSED; | 307 m_state = kClosed; |
| 308 exceptionState.throwDOMException(SyntaxError, "The URL contains a fragme
nt identifier ('" + m_url.fragmentIdentifier() + "'). Fragment identifiers are n
ot allowed in WebSocket URLs."); | 308 exceptionState.throwDOMException(SyntaxError, "The URL contains a fragme
nt identifier ('" + m_url.fragmentIdentifier() + "'). Fragment identifiers are n
ot allowed in WebSocket URLs."); |
| 309 return; | 309 return; |
| 310 } | 310 } |
| 311 | 311 |
| 312 if (!isPortAllowedForScheme(m_url)) { | 312 if (!isPortAllowedForScheme(m_url)) { |
| 313 m_state = CLOSED; | 313 m_state = kClosed; |
| 314 exceptionState.throwSecurityError("The port " + String::number(m_url.por
t()) + " is not allowed."); | 314 exceptionState.throwSecurityError("The port " + String::number(m_url.por
t()) + " is not allowed."); |
| 315 return; | 315 return; |
| 316 } | 316 } |
| 317 | 317 |
| 318 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. | 318 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. |
| 319 if (!ContentSecurityPolicy::shouldBypassMainWorld(getExecutionContext()) &&
!getExecutionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { | 319 if (!ContentSecurityPolicy::shouldBypassMainWorld(getExecutionContext()) &&
!getExecutionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { |
| 320 m_state = CLOSED; | 320 m_state = kClosed; |
| 321 // The URL is safe to expose to JavaScript, as this check happens synchr
onously before redirection. | 321 // The URL is safe to expose to JavaScript, as this check happens synchr
onously before redirection. |
| 322 exceptionState.throwSecurityError("Refused to connect to '" + m_url.elid
edString() + "' because it violates the document's Content Security Policy."); | 322 exceptionState.throwSecurityError("Refused to connect to '" + m_url.elid
edString() + "' because it violates the document's Content Security Policy."); |
| 323 return; | 323 return; |
| 324 } | 324 } |
| 325 | 325 |
| 326 // Fail if not all elements in |protocols| are valid. | 326 // Fail if not all elements in |protocols| are valid. |
| 327 for (size_t i = 0; i < protocols.size(); ++i) { | 327 for (size_t i = 0; i < protocols.size(); ++i) { |
| 328 if (!isValidSubprotocolString(protocols[i])) { | 328 if (!isValidSubprotocolString(protocols[i])) { |
| 329 m_state = CLOSED; | 329 m_state = kClosed; |
| 330 exceptionState.throwDOMException(SyntaxError, "The subprotocol '" +
encodeSubprotocolString(protocols[i]) + "' is invalid."); | 330 exceptionState.throwDOMException(SyntaxError, "The subprotocol '" +
encodeSubprotocolString(protocols[i]) + "' is invalid."); |
| 331 return; | 331 return; |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 | 334 |
| 335 // Fail if there're duplicated elements in |protocols|. | 335 // Fail if there're duplicated elements in |protocols|. |
| 336 HashSet<String> visited; | 336 HashSet<String> visited; |
| 337 for (size_t i = 0; i < protocols.size(); ++i) { | 337 for (size_t i = 0; i < protocols.size(); ++i) { |
| 338 if (!visited.add(protocols[i]).isNewEntry) { | 338 if (!visited.add(protocols[i]).isNewEntry) { |
| 339 m_state = CLOSED; | 339 m_state = kClosed; |
| 340 exceptionState.throwDOMException(SyntaxError, "The subprotocol '" +
encodeSubprotocolString(protocols[i]) + "' is duplicated."); | 340 exceptionState.throwDOMException(SyntaxError, "The subprotocol '" +
encodeSubprotocolString(protocols[i]) + "' is duplicated."); |
| 341 return; | 341 return; |
| 342 } | 342 } |
| 343 } | 343 } |
| 344 | 344 |
| 345 String protocolString; | 345 String protocolString; |
| 346 if (!protocols.isEmpty()) | 346 if (!protocols.isEmpty()) |
| 347 protocolString = joinStrings(protocols, subprotocolSeperator()); | 347 protocolString = joinStrings(protocols, subprotocolSeperator()); |
| 348 | 348 |
| 349 m_channel = createChannel(getExecutionContext(), this); | 349 m_channel = createChannel(getExecutionContext(), this); |
| 350 | 350 |
| 351 if (!m_channel->connect(m_url, protocolString)) { | 351 if (!m_channel->connect(m_url, protocolString)) { |
| 352 m_state = CLOSED; | 352 m_state = kClosed; |
| 353 exceptionState.throwSecurityError("An insecure WebSocket connection may
not be initiated from a page loaded over HTTPS."); | 353 exceptionState.throwSecurityError("An insecure WebSocket connection may
not be initiated from a page loaded over HTTPS."); |
| 354 releaseChannel(); | 354 releaseChannel(); |
| 355 return; | 355 return; |
| 356 } | 356 } |
| 357 } | 357 } |
| 358 | 358 |
| 359 void DOMWebSocket::updateBufferedAmountAfterClose(uint64_t payloadSize) | 359 void DOMWebSocket::updateBufferedAmountAfterClose(uint64_t payloadSize) |
| 360 { | 360 { |
| 361 m_bufferedAmountAfterClose += payloadSize; | 361 m_bufferedAmountAfterClose += payloadSize; |
| 362 | 362 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 379 ASSERT(m_channel); | 379 ASSERT(m_channel); |
| 380 m_channel->disconnect(); | 380 m_channel->disconnect(); |
| 381 m_channel = nullptr; | 381 m_channel = nullptr; |
| 382 } | 382 } |
| 383 | 383 |
| 384 void DOMWebSocket::send(const String& message, ExceptionState& exceptionState) | 384 void DOMWebSocket::send(const String& message, ExceptionState& exceptionState) |
| 385 { | 385 { |
| 386 CString encodedMessage = message.utf8(); | 386 CString encodedMessage = message.utf8(); |
| 387 | 387 |
| 388 WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, encodedMes
sage.data()); | 388 WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, encodedMes
sage.data()); |
| 389 if (m_state == CONNECTING) { | 389 if (m_state == kConnecting) { |
| 390 setInvalidStateErrorForSendMethod(exceptionState); | 390 setInvalidStateErrorForSendMethod(exceptionState); |
| 391 return; | 391 return; |
| 392 } | 392 } |
| 393 // No exception is raised if the connection was once established but has sub
sequently been closed. | 393 // No exception is raised if the connection was once established but has sub
sequently been closed. |
| 394 if (m_state == CLOSING || m_state == CLOSED) { | 394 if (m_state == kClosing || m_state == kClosed) { |
| 395 updateBufferedAmountAfterClose(encodedMessage.length()); | 395 updateBufferedAmountAfterClose(encodedMessage.length()); |
| 396 return; | 396 return; |
| 397 } | 397 } |
| 398 | 398 |
| 399 recordSendTypeHistogram(WebSocketSendTypeString); | 399 recordSendTypeHistogram(WebSocketSendTypeString); |
| 400 | 400 |
| 401 ASSERT(m_channel); | 401 ASSERT(m_channel); |
| 402 m_bufferedAmount += encodedMessage.length(); | 402 m_bufferedAmount += encodedMessage.length(); |
| 403 m_channel->send(encodedMessage); | 403 m_channel->send(encodedMessage); |
| 404 } | 404 } |
| 405 | 405 |
| 406 void DOMWebSocket::send(DOMArrayBuffer* binaryData, ExceptionState& exceptionSta
te) | 406 void DOMWebSocket::send(DOMArrayBuffer* binaryData, ExceptionState& exceptionSta
te) |
| 407 { | 407 { |
| 408 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryD
ata); | 408 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryD
ata); |
| 409 ASSERT(binaryData && binaryData->buffer()); | 409 ASSERT(binaryData && binaryData->buffer()); |
| 410 if (m_state == CONNECTING) { | 410 if (m_state == kConnecting) { |
| 411 setInvalidStateErrorForSendMethod(exceptionState); | 411 setInvalidStateErrorForSendMethod(exceptionState); |
| 412 return; | 412 return; |
| 413 } | 413 } |
| 414 if (m_state == CLOSING || m_state == CLOSED) { | 414 if (m_state == kClosing || m_state == kClosed) { |
| 415 updateBufferedAmountAfterClose(binaryData->byteLength()); | 415 updateBufferedAmountAfterClose(binaryData->byteLength()); |
| 416 return; | 416 return; |
| 417 } | 417 } |
| 418 recordSendTypeHistogram(WebSocketSendTypeArrayBuffer); | 418 recordSendTypeHistogram(WebSocketSendTypeArrayBuffer); |
| 419 | 419 |
| 420 ASSERT(m_channel); | 420 ASSERT(m_channel); |
| 421 m_bufferedAmount += binaryData->byteLength(); | 421 m_bufferedAmount += binaryData->byteLength(); |
| 422 m_channel->send(*binaryData, 0, binaryData->byteLength()); | 422 m_channel->send(*binaryData, 0, binaryData->byteLength()); |
| 423 } | 423 } |
| 424 | 424 |
| 425 void DOMWebSocket::send(DOMArrayBufferView* arrayBufferView, ExceptionState& exc
eptionState) | 425 void DOMWebSocket::send(DOMArrayBufferView* arrayBufferView, ExceptionState& exc
eptionState) |
| 426 { | 426 { |
| 427 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arr
ayBufferView); | 427 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arr
ayBufferView); |
| 428 ASSERT(arrayBufferView); | 428 ASSERT(arrayBufferView); |
| 429 if (m_state == CONNECTING) { | 429 if (m_state == kConnecting) { |
| 430 setInvalidStateErrorForSendMethod(exceptionState); | 430 setInvalidStateErrorForSendMethod(exceptionState); |
| 431 return; | 431 return; |
| 432 } | 432 } |
| 433 if (m_state == CLOSING || m_state == CLOSED) { | 433 if (m_state == kClosing || m_state == kClosed) { |
| 434 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); | 434 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); |
| 435 return; | 435 return; |
| 436 } | 436 } |
| 437 recordSendTypeHistogram(WebSocketSendTypeArrayBufferView); | 437 recordSendTypeHistogram(WebSocketSendTypeArrayBufferView); |
| 438 | 438 |
| 439 ASSERT(m_channel); | 439 ASSERT(m_channel); |
| 440 m_bufferedAmount += arrayBufferView->byteLength(); | 440 m_bufferedAmount += arrayBufferView->byteLength(); |
| 441 m_channel->send(*arrayBufferView->buffer(), arrayBufferView->byteOffset(), a
rrayBufferView->byteLength()); | 441 m_channel->send(*arrayBufferView->buffer(), arrayBufferView->byteOffset(), a
rrayBufferView->byteLength()); |
| 442 } | 442 } |
| 443 | 443 |
| 444 void DOMWebSocket::send(Blob* binaryData, ExceptionState& exceptionState) | 444 void DOMWebSocket::send(Blob* binaryData, ExceptionState& exceptionState) |
| 445 { | 445 { |
| 446 WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData->
uuid().utf8().data()); | 446 WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData->
uuid().utf8().data()); |
| 447 ASSERT(binaryData); | 447 ASSERT(binaryData); |
| 448 if (m_state == CONNECTING) { | 448 if (m_state == kConnecting) { |
| 449 setInvalidStateErrorForSendMethod(exceptionState); | 449 setInvalidStateErrorForSendMethod(exceptionState); |
| 450 return; | 450 return; |
| 451 } | 451 } |
| 452 if (m_state == CLOSING || m_state == CLOSED) { | 452 if (m_state == kClosing || m_state == kClosed) { |
| 453 updateBufferedAmountAfterClose(binaryData->size()); | 453 updateBufferedAmountAfterClose(binaryData->size()); |
| 454 return; | 454 return; |
| 455 } | 455 } |
| 456 recordSendTypeHistogram(WebSocketSendTypeBlob); | 456 recordSendTypeHistogram(WebSocketSendTypeBlob); |
| 457 | 457 |
| 458 unsigned long long size = binaryData->size(); | 458 unsigned long long size = binaryData->size(); |
| 459 m_bufferedAmount += size; | 459 m_bufferedAmount += size; |
| 460 ASSERT(m_channel); | 460 ASSERT(m_channel); |
| 461 | 461 |
| 462 // When the runtime type of |binaryData| is File, | 462 // When the runtime type of |binaryData| is File, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 return; | 501 return; |
| 502 } | 502 } |
| 503 if (!reason.isEmpty() && !reason.is8Bit()) { | 503 if (!reason.isEmpty() && !reason.is8Bit()) { |
| 504 ASSERT(utf8.length() > 0); | 504 ASSERT(utf8.length() > 0); |
| 505 // reason might contain unpaired surrogates. Reconstruct it from | 505 // reason might contain unpaired surrogates. Reconstruct it from |
| 506 // utf8. | 506 // utf8. |
| 507 cleansedReason = String::fromUTF8(utf8.data(), utf8.length()); | 507 cleansedReason = String::fromUTF8(utf8.data(), utf8.length()); |
| 508 } | 508 } |
| 509 } | 509 } |
| 510 | 510 |
| 511 if (m_state == CLOSING || m_state == CLOSED) | 511 if (m_state == kClosing || m_state == kClosed) |
| 512 return; | 512 return; |
| 513 if (m_state == CONNECTING) { | 513 if (m_state == kConnecting) { |
| 514 m_state = CLOSING; | 514 m_state = kClosing; |
| 515 m_channel->fail("WebSocket is closed before the connection is establishe
d.", WarningMessageLevel, SourceLocation::create(String(), 0, 0, nullptr)); | 515 m_channel->fail("WebSocket is closed before the connection is establishe
d.", WarningMessageLevel, SourceLocation::create(String(), 0, 0, nullptr)); |
| 516 return; | 516 return; |
| 517 } | 517 } |
| 518 m_state = CLOSING; | 518 m_state = kClosing; |
| 519 if (m_channel) | 519 if (m_channel) |
| 520 m_channel->close(code, cleansedReason); | 520 m_channel->close(code, cleansedReason); |
| 521 } | 521 } |
| 522 | 522 |
| 523 const KURL& DOMWebSocket::url() const | 523 const KURL& DOMWebSocket::url() const |
| 524 { | 524 { |
| 525 return m_url; | 525 return m_url; |
| 526 } | 526 } |
| 527 | 527 |
| 528 DOMWebSocket::State DOMWebSocket::readyState() const | 528 DOMWebSocket::State DOMWebSocket::readyState() const |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 } | 580 } |
| 581 | 581 |
| 582 ExecutionContext* DOMWebSocket::getExecutionContext() const | 582 ExecutionContext* DOMWebSocket::getExecutionContext() const |
| 583 { | 583 { |
| 584 return ActiveDOMObject::getExecutionContext(); | 584 return ActiveDOMObject::getExecutionContext(); |
| 585 } | 585 } |
| 586 | 586 |
| 587 void DOMWebSocket::contextDestroyed() | 587 void DOMWebSocket::contextDestroyed() |
| 588 { | 588 { |
| 589 WTF_LOG(Network, "WebSocket %p contextDestroyed()", this); | 589 WTF_LOG(Network, "WebSocket %p contextDestroyed()", this); |
| 590 ASSERT(!m_channel); | 590 DCHECK(!m_channel); |
| 591 ASSERT(m_state == CLOSED); | 591 DCHECK_EQ(kClosed, m_state); |
| 592 ActiveDOMObject::contextDestroyed(); | 592 ActiveDOMObject::contextDestroyed(); |
| 593 } | 593 } |
| 594 | 594 |
| 595 bool DOMWebSocket::hasPendingActivity() const | 595 bool DOMWebSocket::hasPendingActivity() const |
| 596 { | 596 { |
| 597 return m_channel || !m_eventQueue->isEmpty(); | 597 return m_channel || !m_eventQueue->isEmpty(); |
| 598 } | 598 } |
| 599 | 599 |
| 600 void DOMWebSocket::suspend() | 600 void DOMWebSocket::suspend() |
| 601 { | 601 { |
| 602 m_eventQueue->suspend(); | 602 m_eventQueue->suspend(); |
| 603 } | 603 } |
| 604 | 604 |
| 605 void DOMWebSocket::resume() | 605 void DOMWebSocket::resume() |
| 606 { | 606 { |
| 607 m_eventQueue->resume(); | 607 m_eventQueue->resume(); |
| 608 } | 608 } |
| 609 | 609 |
| 610 void DOMWebSocket::stop() | 610 void DOMWebSocket::stop() |
| 611 { | 611 { |
| 612 m_eventQueue->stop(); | 612 m_eventQueue->stop(); |
| 613 if (m_channel) { | 613 if (m_channel) { |
| 614 m_channel->close(WebSocketChannel::CloseEventCodeGoingAway, String()); | 614 m_channel->close(WebSocketChannel::CloseEventCodeGoingAway, String()); |
| 615 releaseChannel(); | 615 releaseChannel(); |
| 616 } | 616 } |
| 617 m_state = CLOSED; | 617 m_state = kClosed; |
| 618 } | 618 } |
| 619 | 619 |
| 620 void DOMWebSocket::didConnect(const String& subprotocol, const String& extension
s) | 620 void DOMWebSocket::didConnect(const String& subprotocol, const String& extension
s) |
| 621 { | 621 { |
| 622 WTF_LOG(Network, "WebSocket %p didConnect()", this); | 622 WTF_LOG(Network, "WebSocket %p didConnect()", this); |
| 623 if (m_state != CONNECTING) | 623 if (m_state != kConnecting) |
| 624 return; | 624 return; |
| 625 m_state = OPEN; | 625 m_state = kOpen; |
| 626 m_subprotocol = subprotocol; | 626 m_subprotocol = subprotocol; |
| 627 m_extensions = extensions; | 627 m_extensions = extensions; |
| 628 m_eventQueue->dispatch(Event::create(EventTypeNames::open)); | 628 m_eventQueue->dispatch(Event::create(EventTypeNames::open)); |
| 629 } | 629 } |
| 630 | 630 |
| 631 void DOMWebSocket::didReceiveTextMessage(const String& msg) | 631 void DOMWebSocket::didReceiveTextMessage(const String& msg) |
| 632 { | 632 { |
| 633 WTF_LOG(Network, "WebSocket %p didReceiveTextMessage() Text message '%s'", t
his, msg.utf8().data()); | 633 WTF_LOG(Network, "WebSocket %p didReceiveTextMessage() Text message '%s'", t
his, msg.utf8().data()); |
| 634 if (m_state != OPEN) | 634 if (m_state != kOpen) |
| 635 return; | 635 return; |
| 636 recordReceiveTypeHistogram(WebSocketReceiveTypeString); | 636 recordReceiveTypeHistogram(WebSocketReceiveTypeString); |
| 637 | 637 |
| 638 m_eventQueue->dispatch(MessageEvent::create(msg, SecurityOrigin::create(m_ur
l)->toString())); | 638 m_eventQueue->dispatch(MessageEvent::create(msg, SecurityOrigin::create(m_ur
l)->toString())); |
| 639 } | 639 } |
| 640 | 640 |
| 641 void DOMWebSocket::didReceiveBinaryMessage(std::unique_ptr<Vector<char>> binaryD
ata) | 641 void DOMWebSocket::didReceiveBinaryMessage(std::unique_ptr<Vector<char>> binaryD
ata) |
| 642 { | 642 { |
| 643 WTF_LOG(Network, "WebSocket %p didReceiveBinaryMessage() %lu byte binary mes
sage", this, static_cast<unsigned long>(binaryData->size())); | 643 WTF_LOG(Network, "WebSocket %p didReceiveBinaryMessage() %lu byte binary mes
sage", this, static_cast<unsigned long>(binaryData->size())); |
| 644 switch (m_binaryType) { | 644 switch (m_binaryType) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 658 DOMArrayBuffer* arrayBuffer = DOMArrayBuffer::create(binaryData->data(),
binaryData->size()); | 658 DOMArrayBuffer* arrayBuffer = DOMArrayBuffer::create(binaryData->data(),
binaryData->size()); |
| 659 recordReceiveTypeHistogram(WebSocketReceiveTypeArrayBuffer); | 659 recordReceiveTypeHistogram(WebSocketReceiveTypeArrayBuffer); |
| 660 m_eventQueue->dispatch(MessageEvent::create(arrayBuffer, SecurityOrigin:
:create(m_url)->toString())); | 660 m_eventQueue->dispatch(MessageEvent::create(arrayBuffer, SecurityOrigin:
:create(m_url)->toString())); |
| 661 break; | 661 break; |
| 662 } | 662 } |
| 663 } | 663 } |
| 664 | 664 |
| 665 void DOMWebSocket::didError() | 665 void DOMWebSocket::didError() |
| 666 { | 666 { |
| 667 WTF_LOG(Network, "WebSocket %p didError()", this); | 667 WTF_LOG(Network, "WebSocket %p didError()", this); |
| 668 m_state = CLOSED; | 668 m_state = kClosed; |
| 669 m_eventQueue->dispatch(Event::create(EventTypeNames::error)); | 669 m_eventQueue->dispatch(Event::create(EventTypeNames::error)); |
| 670 } | 670 } |
| 671 | 671 |
| 672 void DOMWebSocket::didConsumeBufferedAmount(uint64_t consumed) | 672 void DOMWebSocket::didConsumeBufferedAmount(uint64_t consumed) |
| 673 { | 673 { |
| 674 ASSERT(m_bufferedAmount >= consumed + m_consumedBufferedAmount); | 674 ASSERT(m_bufferedAmount >= consumed + m_consumedBufferedAmount); |
| 675 // Cast to unsigned long long is required since clang doesn't accept | 675 // Cast to unsigned long long is required since clang doesn't accept |
| 676 // combination of %llu and uint64_t (known as unsigned long). | 676 // combination of %llu and uint64_t (known as unsigned long). |
| 677 WTF_LOG(Network, "WebSocket %p didConsumeBufferedAmount(%llu)", this, static
_cast<unsigned long long>(consumed)); | 677 WTF_LOG(Network, "WebSocket %p didConsumeBufferedAmount(%llu)", this, static
_cast<unsigned long long>(consumed)); |
| 678 if (m_state == CLOSED) | 678 if (m_state == kClosed) |
| 679 return; | 679 return; |
| 680 m_consumedBufferedAmount += consumed; | 680 m_consumedBufferedAmount += consumed; |
| 681 if (!m_bufferedAmountConsumeTimer.isActive()) | 681 if (!m_bufferedAmountConsumeTimer.isActive()) |
| 682 m_bufferedAmountConsumeTimer.startOneShot(0, BLINK_FROM_HERE); | 682 m_bufferedAmountConsumeTimer.startOneShot(0, BLINK_FROM_HERE); |
| 683 } | 683 } |
| 684 | 684 |
| 685 void DOMWebSocket::didStartClosingHandshake() | 685 void DOMWebSocket::didStartClosingHandshake() |
| 686 { | 686 { |
| 687 WTF_LOG(Network, "WebSocket %p didStartClosingHandshake()", this); | 687 WTF_LOG(Network, "WebSocket %p didStartClosingHandshake()", this); |
| 688 m_state = CLOSING; | 688 m_state = kClosing; |
| 689 } | 689 } |
| 690 | 690 |
| 691 void DOMWebSocket::didClose(ClosingHandshakeCompletionStatus closingHandshakeCom
pletion, unsigned short code, const String& reason) | 691 void DOMWebSocket::didClose(ClosingHandshakeCompletionStatus closingHandshakeCom
pletion, unsigned short code, const String& reason) |
| 692 { | 692 { |
| 693 WTF_LOG(Network, "WebSocket %p didClose()", this); | 693 WTF_LOG(Network, "WebSocket %p didClose()", this); |
| 694 if (!m_channel) | 694 if (!m_channel) |
| 695 return; | 695 return; |
| 696 bool allDataHasBeenConsumed = m_bufferedAmount == m_consumedBufferedAmount; | 696 bool allDataHasBeenConsumed = m_bufferedAmount == m_consumedBufferedAmount; |
| 697 bool wasClean = m_state == CLOSING && allDataHasBeenConsumed && closingHands
hakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEve
ntCodeAbnormalClosure; | 697 bool wasClean = m_state == kClosing && allDataHasBeenConsumed && closingHand
shakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEv
entCodeAbnormalClosure; |
| 698 m_state = CLOSED; | 698 m_state = kClosed; |
| 699 | 699 |
| 700 m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason)); | 700 m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason)); |
| 701 releaseChannel(); | 701 releaseChannel(); |
| 702 } | 702 } |
| 703 | 703 |
| 704 void DOMWebSocket::recordSendTypeHistogram(WebSocketSendType type) | 704 void DOMWebSocket::recordSendTypeHistogram(WebSocketSendType type) |
| 705 { | 705 { |
| 706 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, sendTypeHistogram, new
EnumerationHistogram("WebCore.WebSocket.SendType", WebSocketSendTypeMax)); | 706 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, sendTypeHistogram, new
EnumerationHistogram("WebCore.WebSocket.SendType", WebSocketSendTypeMax)); |
| 707 sendTypeHistogram.count(type); | 707 sendTypeHistogram.count(type); |
| 708 } | 708 } |
| 709 | 709 |
| 710 void DOMWebSocket::recordReceiveTypeHistogram(WebSocketReceiveType type) | 710 void DOMWebSocket::recordReceiveTypeHistogram(WebSocketReceiveType type) |
| 711 { | 711 { |
| 712 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, receiveTypeHistogram,
new EnumerationHistogram("WebCore.WebSocket.ReceiveType", WebSocketReceiveTypeMa
x)); | 712 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, receiveTypeHistogram,
new EnumerationHistogram("WebCore.WebSocket.ReceiveType", WebSocketReceiveTypeMa
x)); |
| 713 receiveTypeHistogram.count(type); | 713 receiveTypeHistogram.count(type); |
| 714 } | 714 } |
| 715 | 715 |
| 716 DEFINE_TRACE(DOMWebSocket) | 716 DEFINE_TRACE(DOMWebSocket) |
| 717 { | 717 { |
| 718 visitor->trace(m_channel); | 718 visitor->trace(m_channel); |
| 719 visitor->trace(m_eventQueue); | 719 visitor->trace(m_eventQueue); |
| 720 WebSocketChannelClient::trace(visitor); | 720 WebSocketChannelClient::trace(visitor); |
| 721 EventTargetWithInlineData::trace(visitor); | 721 EventTargetWithInlineData::trace(visitor); |
| 722 ActiveDOMObject::trace(visitor); | 722 ActiveDOMObject::trace(visitor); |
| 723 } | 723 } |
| 724 | 724 |
| 725 } // namespace blink | 725 } // namespace blink |
| OLD | NEW |