| 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 30 matching lines...) Expand all Loading... |
| 41 #include "core/dom/SecurityContext.h" | 41 #include "core/dom/SecurityContext.h" |
| 42 #include "core/events/MessageEvent.h" | 42 #include "core/events/MessageEvent.h" |
| 43 #include "core/fileapi/Blob.h" | 43 #include "core/fileapi/Blob.h" |
| 44 #include "core/frame/ConsoleTypes.h" | 44 #include "core/frame/ConsoleTypes.h" |
| 45 #include "core/frame/LocalDOMWindow.h" | 45 #include "core/frame/LocalDOMWindow.h" |
| 46 #include "core/frame/LocalFrame.h" | 46 #include "core/frame/LocalFrame.h" |
| 47 #include "core/frame/UseCounter.h" | 47 #include "core/frame/UseCounter.h" |
| 48 #include "core/frame/csp/ContentSecurityPolicy.h" | 48 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 49 #include "core/inspector/ConsoleMessage.h" | 49 #include "core/inspector/ConsoleMessage.h" |
| 50 #include "modules/websockets/CloseEvent.h" | 50 #include "modules/websockets/CloseEvent.h" |
| 51 #include "platform/Histogram.h" |
| 51 #include "platform/Logging.h" | 52 #include "platform/Logging.h" |
| 52 #include "platform/blob/BlobData.h" | 53 #include "platform/blob/BlobData.h" |
| 53 #include "platform/heap/Handle.h" | 54 #include "platform/heap/Handle.h" |
| 54 #include "platform/weborigin/SecurityOrigin.h" | 55 #include "platform/weborigin/SecurityOrigin.h" |
| 55 #include "public/platform/Platform.h" | 56 #include "public/platform/Platform.h" |
| 56 #include "wtf/Assertions.h" | 57 #include "wtf/Assertions.h" |
| 57 #include "wtf/HashSet.h" | 58 #include "wtf/HashSet.h" |
| 58 #include "wtf/PassOwnPtr.h" | 59 #include "wtf/PassOwnPtr.h" |
| 59 #include "wtf/StdLibExtras.h" | 60 #include "wtf/StdLibExtras.h" |
| 60 #include "wtf/text/CString.h" | 61 #include "wtf/text/CString.h" |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, encodedMes
sage.data()); | 385 WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, encodedMes
sage.data()); |
| 385 if (m_state == CONNECTING) { | 386 if (m_state == CONNECTING) { |
| 386 setInvalidStateErrorForSendMethod(exceptionState); | 387 setInvalidStateErrorForSendMethod(exceptionState); |
| 387 return; | 388 return; |
| 388 } | 389 } |
| 389 // No exception is raised if the connection was once established but has sub
sequently been closed. | 390 // No exception is raised if the connection was once established but has sub
sequently been closed. |
| 390 if (m_state == CLOSING || m_state == CLOSED) { | 391 if (m_state == CLOSING || m_state == CLOSED) { |
| 391 updateBufferedAmountAfterClose(encodedMessage.length()); | 392 updateBufferedAmountAfterClose(encodedMessage.length()); |
| 392 return; | 393 return; |
| 393 } | 394 } |
| 394 Platform::current()->histogramEnumeration("WebCore.WebSocket.SendType", WebS
ocketSendTypeString, WebSocketSendTypeMax); | 395 |
| 396 recordSendTypeHistogram(WebSocketSendTypeString); |
| 397 |
| 395 ASSERT(m_channel); | 398 ASSERT(m_channel); |
| 396 m_bufferedAmount += encodedMessage.length(); | 399 m_bufferedAmount += encodedMessage.length(); |
| 397 m_channel->send(encodedMessage); | 400 m_channel->send(encodedMessage); |
| 398 } | 401 } |
| 399 | 402 |
| 400 void DOMWebSocket::send(DOMArrayBuffer* binaryData, ExceptionState& exceptionSta
te) | 403 void DOMWebSocket::send(DOMArrayBuffer* binaryData, ExceptionState& exceptionSta
te) |
| 401 { | 404 { |
| 402 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryD
ata); | 405 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryD
ata); |
| 403 ASSERT(binaryData && binaryData->buffer()); | 406 ASSERT(binaryData && binaryData->buffer()); |
| 404 if (m_state == CONNECTING) { | 407 if (m_state == CONNECTING) { |
| 405 setInvalidStateErrorForSendMethod(exceptionState); | 408 setInvalidStateErrorForSendMethod(exceptionState); |
| 406 return; | 409 return; |
| 407 } | 410 } |
| 408 if (m_state == CLOSING || m_state == CLOSED) { | 411 if (m_state == CLOSING || m_state == CLOSED) { |
| 409 updateBufferedAmountAfterClose(binaryData->byteLength()); | 412 updateBufferedAmountAfterClose(binaryData->byteLength()); |
| 410 return; | 413 return; |
| 411 } | 414 } |
| 412 Platform::current()->histogramEnumeration("WebCore.WebSocket.SendType", WebS
ocketSendTypeArrayBuffer, WebSocketSendTypeMax); | 415 recordSendTypeHistogram(WebSocketSendTypeArrayBuffer); |
| 416 |
| 413 ASSERT(m_channel); | 417 ASSERT(m_channel); |
| 414 m_bufferedAmount += binaryData->byteLength(); | 418 m_bufferedAmount += binaryData->byteLength(); |
| 415 m_channel->send(*binaryData, 0, binaryData->byteLength()); | 419 m_channel->send(*binaryData, 0, binaryData->byteLength()); |
| 416 } | 420 } |
| 417 | 421 |
| 418 void DOMWebSocket::send(DOMArrayBufferView* arrayBufferView, ExceptionState& exc
eptionState) | 422 void DOMWebSocket::send(DOMArrayBufferView* arrayBufferView, ExceptionState& exc
eptionState) |
| 419 { | 423 { |
| 420 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arr
ayBufferView); | 424 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arr
ayBufferView); |
| 421 ASSERT(arrayBufferView); | 425 ASSERT(arrayBufferView); |
| 422 if (m_state == CONNECTING) { | 426 if (m_state == CONNECTING) { |
| 423 setInvalidStateErrorForSendMethod(exceptionState); | 427 setInvalidStateErrorForSendMethod(exceptionState); |
| 424 return; | 428 return; |
| 425 } | 429 } |
| 426 if (m_state == CLOSING || m_state == CLOSED) { | 430 if (m_state == CLOSING || m_state == CLOSED) { |
| 427 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); | 431 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); |
| 428 return; | 432 return; |
| 429 } | 433 } |
| 430 Platform::current()->histogramEnumeration("WebCore.WebSocket.SendType", WebS
ocketSendTypeArrayBufferView, WebSocketSendTypeMax); | 434 recordSendTypeHistogram(WebSocketSendTypeArrayBufferView); |
| 435 |
| 431 ASSERT(m_channel); | 436 ASSERT(m_channel); |
| 432 m_bufferedAmount += arrayBufferView->byteLength(); | 437 m_bufferedAmount += arrayBufferView->byteLength(); |
| 433 m_channel->send(*arrayBufferView->buffer(), arrayBufferView->byteOffset(), a
rrayBufferView->byteLength()); | 438 m_channel->send(*arrayBufferView->buffer(), arrayBufferView->byteOffset(), a
rrayBufferView->byteLength()); |
| 434 } | 439 } |
| 435 | 440 |
| 436 void DOMWebSocket::send(Blob* binaryData, ExceptionState& exceptionState) | 441 void DOMWebSocket::send(Blob* binaryData, ExceptionState& exceptionState) |
| 437 { | 442 { |
| 438 WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData->
uuid().utf8().data()); | 443 WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData->
uuid().utf8().data()); |
| 439 ASSERT(binaryData); | 444 ASSERT(binaryData); |
| 440 if (m_state == CONNECTING) { | 445 if (m_state == CONNECTING) { |
| 441 setInvalidStateErrorForSendMethod(exceptionState); | 446 setInvalidStateErrorForSendMethod(exceptionState); |
| 442 return; | 447 return; |
| 443 } | 448 } |
| 444 if (m_state == CLOSING || m_state == CLOSED) { | 449 if (m_state == CLOSING || m_state == CLOSED) { |
| 445 updateBufferedAmountAfterClose(binaryData->size()); | 450 updateBufferedAmountAfterClose(binaryData->size()); |
| 446 return; | 451 return; |
| 447 } | 452 } |
| 448 Platform::current()->histogramEnumeration("WebCore.WebSocket.SendType", WebS
ocketSendTypeBlob, WebSocketSendTypeMax); | 453 recordSendTypeHistogram(WebSocketSendTypeBlob); |
| 454 |
| 449 unsigned long long size = binaryData->size(); | 455 unsigned long long size = binaryData->size(); |
| 450 m_bufferedAmount += size; | 456 m_bufferedAmount += size; |
| 451 ASSERT(m_channel); | 457 ASSERT(m_channel); |
| 452 | 458 |
| 453 // When the runtime type of |binaryData| is File, | 459 // When the runtime type of |binaryData| is File, |
| 454 // binaryData->blobDataHandle()->size() returns -1. However, in order to | 460 // binaryData->blobDataHandle()->size() returns -1. However, in order to |
| 455 // maintain the value of |m_bufferedAmount| correctly, the WebSocket code | 461 // maintain the value of |m_bufferedAmount| correctly, the WebSocket code |
| 456 // needs to fix the size of the File at this point. For this reason, | 462 // needs to fix the size of the File at this point. For this reason, |
| 457 // construct a new BlobDataHandle here with the size that this method | 463 // construct a new BlobDataHandle here with the size that this method |
| 458 // observed. | 464 // observed. |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 m_subprotocol = subprotocol; | 623 m_subprotocol = subprotocol; |
| 618 m_extensions = extensions; | 624 m_extensions = extensions; |
| 619 m_eventQueue->dispatch(Event::create(EventTypeNames::open)); | 625 m_eventQueue->dispatch(Event::create(EventTypeNames::open)); |
| 620 } | 626 } |
| 621 | 627 |
| 622 void DOMWebSocket::didReceiveTextMessage(const String& msg) | 628 void DOMWebSocket::didReceiveTextMessage(const String& msg) |
| 623 { | 629 { |
| 624 WTF_LOG(Network, "WebSocket %p didReceiveTextMessage() Text message '%s'", t
his, msg.utf8().data()); | 630 WTF_LOG(Network, "WebSocket %p didReceiveTextMessage() Text message '%s'", t
his, msg.utf8().data()); |
| 625 if (m_state != OPEN) | 631 if (m_state != OPEN) |
| 626 return; | 632 return; |
| 627 Platform::current()->histogramEnumeration("WebCore.WebSocket.ReceiveType", W
ebSocketReceiveTypeString, WebSocketReceiveTypeMax); | 633 recordReceiveTypeHistogram(WebSocketReceiveTypeString); |
| 634 |
| 628 m_eventQueue->dispatch(MessageEvent::create(msg, SecurityOrigin::create(m_ur
l)->toString())); | 635 m_eventQueue->dispatch(MessageEvent::create(msg, SecurityOrigin::create(m_ur
l)->toString())); |
| 629 } | 636 } |
| 630 | 637 |
| 631 void DOMWebSocket::didReceiveBinaryMessage(PassOwnPtr<Vector<char>> binaryData) | 638 void DOMWebSocket::didReceiveBinaryMessage(PassOwnPtr<Vector<char>> binaryData) |
| 632 { | 639 { |
| 633 WTF_LOG(Network, "WebSocket %p didReceiveBinaryMessage() %lu byte binary mes
sage", this, static_cast<unsigned long>(binaryData->size())); | 640 WTF_LOG(Network, "WebSocket %p didReceiveBinaryMessage() %lu byte binary mes
sage", this, static_cast<unsigned long>(binaryData->size())); |
| 634 switch (m_binaryType) { | 641 switch (m_binaryType) { |
| 635 case BinaryTypeBlob: { | 642 case BinaryTypeBlob: { |
| 636 size_t size = binaryData->size(); | 643 size_t size = binaryData->size(); |
| 637 RefPtr<RawData> rawData = RawData::create(); | 644 RefPtr<RawData> rawData = RawData::create(); |
| 638 binaryData->swap(*rawData->mutableData()); | 645 binaryData->swap(*rawData->mutableData()); |
| 639 OwnPtr<BlobData> blobData = BlobData::create(); | 646 OwnPtr<BlobData> blobData = BlobData::create(); |
| 640 blobData->appendData(rawData.release(), 0, BlobDataItem::toEndOfFile); | 647 blobData->appendData(rawData.release(), 0, BlobDataItem::toEndOfFile); |
| 641 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), siz
e)); | 648 Blob* blob = Blob::create(BlobDataHandle::create(blobData.release(), siz
e)); |
| 642 Platform::current()->histogramEnumeration("WebCore.WebSocket.ReceiveType
", WebSocketReceiveTypeBlob, WebSocketReceiveTypeMax); | 649 recordReceiveTypeHistogram(WebSocketReceiveTypeBlob); |
| 643 m_eventQueue->dispatch(MessageEvent::create(blob, SecurityOrigin::create
(m_url)->toString())); | 650 m_eventQueue->dispatch(MessageEvent::create(blob, SecurityOrigin::create
(m_url)->toString())); |
| 644 break; | 651 break; |
| 645 } | 652 } |
| 646 | 653 |
| 647 case BinaryTypeArrayBuffer: | 654 case BinaryTypeArrayBuffer: |
| 648 RefPtr<DOMArrayBuffer> arrayBuffer = DOMArrayBuffer::create(binaryData->
data(), binaryData->size()); | 655 RefPtr<DOMArrayBuffer> arrayBuffer = DOMArrayBuffer::create(binaryData->
data(), binaryData->size()); |
| 649 Platform::current()->histogramEnumeration("WebCore.WebSocket.ReceiveType
", WebSocketReceiveTypeArrayBuffer, WebSocketReceiveTypeMax); | 656 recordReceiveTypeHistogram(WebSocketReceiveTypeArrayBuffer); |
| 650 m_eventQueue->dispatch(MessageEvent::create(arrayBuffer.release(), Secur
ityOrigin::create(m_url)->toString())); | 657 m_eventQueue->dispatch(MessageEvent::create(arrayBuffer.release(), Secur
ityOrigin::create(m_url)->toString())); |
| 651 break; | 658 break; |
| 652 } | 659 } |
| 653 } | 660 } |
| 654 | 661 |
| 655 void DOMWebSocket::didError() | 662 void DOMWebSocket::didError() |
| 656 { | 663 { |
| 657 WTF_LOG(Network, "WebSocket %p didError()", this); | 664 WTF_LOG(Network, "WebSocket %p didError()", this); |
| 658 m_state = CLOSED; | 665 m_state = CLOSED; |
| 659 m_eventQueue->dispatch(Event::create(EventTypeNames::error)); | 666 m_eventQueue->dispatch(Event::create(EventTypeNames::error)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 684 if (!m_channel) | 691 if (!m_channel) |
| 685 return; | 692 return; |
| 686 bool allDataHasBeenConsumed = m_bufferedAmount == m_consumedBufferedAmount; | 693 bool allDataHasBeenConsumed = m_bufferedAmount == m_consumedBufferedAmount; |
| 687 bool wasClean = m_state == CLOSING && allDataHasBeenConsumed && closingHands
hakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEve
ntCodeAbnormalClosure; | 694 bool wasClean = m_state == CLOSING && allDataHasBeenConsumed && closingHands
hakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEve
ntCodeAbnormalClosure; |
| 688 m_state = CLOSED; | 695 m_state = CLOSED; |
| 689 | 696 |
| 690 m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason)); | 697 m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason)); |
| 691 releaseChannel(); | 698 releaseChannel(); |
| 692 } | 699 } |
| 693 | 700 |
| 701 void DOMWebSocket::recordSendTypeHistogram(WebSocketSendType type) |
| 702 { |
| 703 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, sendTypeHistogram, new
EnumerationHistogram("WebCore.WebSocket.SendType", WebSocketSendTypeMax)); |
| 704 sendTypeHistogram.count(type); |
| 705 } |
| 706 |
| 707 void DOMWebSocket::recordReceiveTypeHistogram(WebSocketReceiveType type) |
| 708 { |
| 709 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, receiveTypeHistogram,
new EnumerationHistogram("WebCore.WebSocket.ReceiveType", WebSocketReceiveTypeMa
x)); |
| 710 receiveTypeHistogram.count(type); |
| 711 } |
| 712 |
| 694 DEFINE_TRACE(DOMWebSocket) | 713 DEFINE_TRACE(DOMWebSocket) |
| 695 { | 714 { |
| 696 visitor->trace(m_channel); | 715 visitor->trace(m_channel); |
| 697 visitor->trace(m_eventQueue); | 716 visitor->trace(m_eventQueue); |
| 698 WebSocketChannelClient::trace(visitor); | 717 WebSocketChannelClient::trace(visitor); |
| 699 RefCountedGarbageCollectedEventTargetWithInlineData<DOMWebSocket>::trace(vis
itor); | 718 RefCountedGarbageCollectedEventTargetWithInlineData<DOMWebSocket>::trace(vis
itor); |
| 700 ActiveDOMObject::trace(visitor); | 719 ActiveDOMObject::trace(visitor); |
| 701 } | 720 } |
| 702 | 721 |
| 703 } // namespace blink | 722 } // namespace blink |
| OLD | NEW |