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 |