| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "modules/websockets/WebSocketChannel.h" | 5 #include "modules/websockets/WebSocketChannel.h" |
| 6 | 6 |
| 7 #include "core/dom/DOMArrayBuffer.h" | 7 #include "core/dom/DOMArrayBuffer.h" |
| 8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
| 9 #include "core/fileapi/Blob.h" | 9 #include "core/fileapi/Blob.h" |
| 10 #include "core/frame/ConsoleTypes.h" | 10 #include "core/frame/ConsoleTypes.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 { | 75 { |
| 76 return new testing::StrictMock<MockWebSocketHandle>(); | 76 return new testing::StrictMock<MockWebSocketHandle>(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 MockWebSocketHandle() { } | 79 MockWebSocketHandle() { } |
| 80 | 80 |
| 81 ~MockWebSocketHandle() override { } | 81 ~MockWebSocketHandle() override { } |
| 82 | 82 |
| 83 MOCK_METHOD4(connect, void(const WebURL&, const WebVector<WebString>&, const
WebSecurityOrigin&, WebSocketHandleClient*)); | 83 MOCK_METHOD4(connect, void(const WebURL&, const WebVector<WebString>&, const
WebSecurityOrigin&, WebSocketHandleClient*)); |
| 84 MOCK_METHOD4(send, void(bool, WebSocketHandle::MessageType, const char*, siz
e_t)); | 84 MOCK_METHOD4(send, void(bool, WebSocketHandle::MessageType, const char*, siz
e_t)); |
| 85 MOCK_METHOD2(sendBlob, void(const blink::WebString&, uint64_t)); |
| 85 MOCK_METHOD1(flowControl, void(int64_t)); | 86 MOCK_METHOD1(flowControl, void(int64_t)); |
| 86 MOCK_METHOD2(close, void(unsigned short, const WebString&)); | 87 MOCK_METHOD2(close, void(unsigned short, const WebString&)); |
| 87 }; | 88 }; |
| 88 | 89 |
| 89 class DocumentWebSocketChannelTest : public ::testing::Test { | 90 class DocumentWebSocketChannelTest : public ::testing::Test { |
| 90 public: | 91 public: |
| 91 DocumentWebSocketChannelTest() | 92 DocumentWebSocketChannelTest() |
| 92 : m_pageHolder(DummyPageHolder::create()) | 93 : m_pageHolder(DummyPageHolder::create()) |
| 93 , m_channelClient(MockWebSocketChannelClient::create()) | 94 , m_channelClient(MockWebSocketChannelClient::create()) |
| 94 , m_handle(MockWebSocketHandle::create()) | 95 , m_handle(MockWebSocketHandle::create()) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 ::testing::Mock::VerifyAndClearExpectations(this); | 142 ::testing::Mock::VerifyAndClearExpectations(this); |
| 142 } | 143 } |
| 143 | 144 |
| 144 OwnPtr<DummyPageHolder> m_pageHolder; | 145 OwnPtr<DummyPageHolder> m_pageHolder; |
| 145 Persistent<MockWebSocketChannelClient> m_channelClient; | 146 Persistent<MockWebSocketChannelClient> m_channelClient; |
| 146 MockWebSocketHandle* m_handle; | 147 MockWebSocketHandle* m_handle; |
| 147 Persistent<DocumentWebSocketChannel> m_channel; | 148 Persistent<DocumentWebSocketChannel> m_channel; |
| 148 unsigned long m_sumOfConsumedBufferedAmount; | 149 unsigned long m_sumOfConsumedBufferedAmount; |
| 149 }; | 150 }; |
| 150 | 151 |
| 152 // The WebSocket protocol and API ignores the type of the Blob, so put a |
| 153 // default value in that field. |
| 154 PassRefPtr<BlobDataHandle> createBlob(const String& uuid, long long size) |
| 155 { |
| 156 return BlobDataHandle::create(uuid, "unknown/unknown", size); |
| 157 } |
| 158 |
| 151 MATCHER_P2(MemEq, p, len, | 159 MATCHER_P2(MemEq, p, len, |
| 152 std::string("pointing to memory") | 160 std::string("pointing to memory") |
| 153 + (negation ? " not" : "") | 161 + (negation ? " not" : "") |
| 154 + " equal to \"" | 162 + " equal to \"" |
| 155 + std::string(p, len) + "\" (length=" + PrintToString(len) + ")" | 163 + std::string(p, len) + "\" (length=" + PrintToString(len) + ")" |
| 156 ) | 164 ) |
| 157 { | 165 { |
| 158 return memcmp(arg, p, len) == 0; | 166 return memcmp(arg, p, len) == 0; |
| 159 } | 167 } |
| 160 | 168 |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 | 464 |
| 457 RefPtr<DOMArrayBuffer> b = DOMArrayBuffer::create("\xe7\x8b\x90\xe7\x8b\x90\
xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90", 18); | 465 RefPtr<DOMArrayBuffer> b = DOMArrayBuffer::create("\xe7\x8b\x90\xe7\x8b\x90\
xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90", 18); |
| 458 channel()->send(*b, 0, 18); | 466 channel()->send(*b, 0, 18); |
| 459 checkpoint.Call(1); | 467 checkpoint.Call(1); |
| 460 | 468 |
| 461 handleClient()->didReceiveFlowControl(handle(), 16); | 469 handleClient()->didReceiveFlowControl(handle(), 16); |
| 462 | 470 |
| 463 EXPECT_EQ(18ul, m_sumOfConsumedBufferedAmount); | 471 EXPECT_EQ(18ul, m_sumOfConsumedBufferedAmount); |
| 464 } | 472 } |
| 465 | 473 |
| 466 // FIXME: Add tests for WebSocketChannel::send(PassRefPtr<BlobDataHandle>) | 474 TEST_F(DocumentWebSocketChannelTest, sendSingleBlob) |
| 475 { |
| 476 connect(); |
| 477 EXPECT_CALL(*handle(), sendBlob(WebString("uuid"), 10)); |
| 478 handleClient()->didReceiveFlowControl(handle(), 16); |
| 479 channel()->send(createBlob("uuid", 10)); |
| 480 } |
| 481 |
| 482 TEST_F(DocumentWebSocketChannelTest, sendTwoBlobs) |
| 483 { |
| 484 connect(); |
| 485 Checkpoint checkpoint; |
| 486 { |
| 487 InSequence s; |
| 488 EXPECT_CALL(*handle(), sendBlob(WebString("uuid1"), 11)); |
| 489 EXPECT_CALL(checkpoint, Call(1)); |
| 490 EXPECT_CALL(*handle(), sendBlob(WebString("uuid2"), 12)); |
| 491 } |
| 492 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)) |
| 493 .Times(AnyNumber()); |
| 494 handleClient()->didReceiveFlowControl(handle(), 32); |
| 495 channel()->send(createBlob("uuid1", 11)); |
| 496 channel()->send(createBlob("uuid2", 12)); |
| 497 checkpoint.Call(1); |
| 498 handleClient()->didCompleteSendingBlob(handle()); |
| 499 } |
| 500 |
| 501 TEST_F(DocumentWebSocketChannelTest, flowControlReflectedInBufferedAmount) |
| 502 { |
| 503 connect(); |
| 504 EXPECT_CALL(*handle(), sendBlob(WebString("uuid"), 256)); |
| 505 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)) |
| 506 .Times(AnyNumber()); |
| 507 handleClient()->didReceiveFlowControl(handle(), 128); |
| 508 channel()->send(createBlob("uuid", 256)); |
| 509 EXPECT_EQ(0u, m_sumOfConsumedBufferedAmount); |
| 510 handleClient()->didReceiveFlowControl(handle(), 128); |
| 511 EXPECT_EQ(128u, m_sumOfConsumedBufferedAmount); |
| 512 handleClient()->didCompleteSendingBlob(handle()); |
| 513 EXPECT_EQ(256u, m_sumOfConsumedBufferedAmount); |
| 514 } |
| 515 |
| 516 // Verifies that Blobs respect queue ordering. |
| 517 TEST_F(DocumentWebSocketChannelTest, sendTextThenBlob) |
| 518 { |
| 519 connect(); |
| 520 Checkpoint checkpoint; |
| 521 { |
| 522 InSequence s; |
| 523 EXPECT_CALL(checkpoint, Call(1)); |
| 524 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeText, MemE
q("foo", 3), 3)); |
| 525 EXPECT_CALL(*handle(), sendBlob(WebString("uuid"), 16)); |
| 526 } |
| 527 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)) |
| 528 .Times(AnyNumber()); |
| 529 channel()->send("foo"); |
| 530 channel()->send(createBlob("uuid", 16)); |
| 531 checkpoint.Call(1); |
| 532 handleClient()->didReceiveFlowControl(handle(), 128); |
| 533 } |
| 534 |
| 535 // Verifies that "Blob sending mode" is exited correctly. |
| 536 TEST_F(DocumentWebSocketChannelTest, sendBlobThenText) |
| 537 { |
| 538 connect(); |
| 539 Checkpoint checkpoint; |
| 540 { |
| 541 InSequence s; |
| 542 EXPECT_CALL(*handle(), sendBlob(WebString("uuid"), 16)); |
| 543 EXPECT_CALL(checkpoint, Call(1)); |
| 544 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeText, MemE
q("foo", 3), 3)); |
| 545 } |
| 546 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)) |
| 547 .Times(AnyNumber()); |
| 548 handleClient()->didReceiveFlowControl(handle(), 128); |
| 549 channel()->send(createBlob("uuid", 16)); |
| 550 channel()->send("foo"); |
| 551 checkpoint.Call(1); |
| 552 // Exits "Blob sending mode" and allows text message "foo" to be sent. |
| 553 handleClient()->didCompleteSendingBlob(handle()); |
| 554 } |
| 555 |
| 556 // Verifies that other messages are queued during "Blob sending mode", and that |
| 557 // flow control messages do not cause them to be sent prematurely. |
| 558 TEST_F(DocumentWebSocketChannelTest, sendLargeBlobThenText) |
| 559 { |
| 560 connect(); |
| 561 Checkpoint checkpoint; |
| 562 { |
| 563 InSequence s; |
| 564 EXPECT_CALL(*handle(), sendBlob(WebString("uuid"), 256)); |
| 565 EXPECT_CALL(checkpoint, Call(1)); |
| 566 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeText, MemE
q("foo", 3), 3)); |
| 567 } |
| 568 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)) |
| 569 .Times(AnyNumber()); |
| 570 handleClient()->didReceiveFlowControl(handle(), 128); |
| 571 channel()->send(createBlob("uuid", 256)); |
| 572 handleClient()->didReceiveFlowControl(handle(), 128); |
| 573 handleClient()->didReceiveFlowControl(handle(), 128); |
| 574 channel()->send("foo"); |
| 575 checkpoint.Call(1); |
| 576 handleClient()->didCompleteSendingBlob(handle()); |
| 577 } |
| 467 | 578 |
| 468 TEST_F(DocumentWebSocketChannelTest, receiveText) | 579 TEST_F(DocumentWebSocketChannelTest, receiveText) |
| 469 { | 580 { |
| 470 connect(); | 581 connect(); |
| 471 { | 582 { |
| 472 InSequence s; | 583 InSequence s; |
| 473 EXPECT_CALL(*channelClient(), didReceiveTextMessage(String("FOO"))); | 584 EXPECT_CALL(*channelClient(), didReceiveTextMessage(String("FOO"))); |
| 474 EXPECT_CALL(*channelClient(), didReceiveTextMessage(String("BAR"))); | 585 EXPECT_CALL(*channelClient(), didReceiveTextMessage(String("BAR"))); |
| 475 } | 586 } |
| 476 | 587 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 EXPECT_CALL(*channelClient(), didError()); | 790 EXPECT_CALL(*channelClient(), didError()); |
| 680 EXPECT_CALL(*channelClient(), didClose(WebSocketChannelClient::ClosingHa
ndshakeIncomplete, WebSocketChannel::CloseEventCodeAbnormalClosure, String())); | 791 EXPECT_CALL(*channelClient(), didClose(WebSocketChannelClient::ClosingHa
ndshakeIncomplete, WebSocketChannel::CloseEventCodeAbnormalClosure, String())); |
| 681 } | 792 } |
| 682 | 793 |
| 683 channel()->fail("fail message from WebSocket", ErrorMessageLevel, "sourceURL
", 1234); | 794 channel()->fail("fail message from WebSocket", ErrorMessageLevel, "sourceURL
", 1234); |
| 684 } | 795 } |
| 685 | 796 |
| 686 } // namespace | 797 } // namespace |
| 687 | 798 |
| 688 } // namespace blink | 799 } // namespace blink |
| OLD | NEW |