| 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/testing/DummyPageHolder.h" | 10 #include "core/testing/DummyPageHolder.h" |
| 11 #include "modules/websockets/DocumentWebSocketChannel.h" | 11 #include "modules/websockets/DocumentWebSocketChannel.h" |
| 12 #include "modules/websockets/WebSocketChannelClient.h" | 12 #include "modules/websockets/WebSocketChannelClient.h" |
| 13 #include "platform/heap/Handle.h" | 13 #include "platform/heap/Handle.h" |
| 14 #include "platform/v8_inspector/public/ConsoleTypes.h" | 14 #include "platform/v8_inspector/public/ConsoleTypes.h" |
| 15 #include "platform/weborigin/KURL.h" | 15 #include "platform/weborigin/KURL.h" |
| 16 #include "public/platform/WebSecurityOrigin.h" | 16 #include "public/platform/WebSecurityOrigin.h" |
| 17 #include "public/platform/WebString.h" | 17 #include "public/platform/WebString.h" |
| 18 #include "public/platform/WebURL.h" | 18 #include "public/platform/WebURL.h" |
| 19 #include "public/platform/WebVector.h" | 19 #include "public/platform/WebVector.h" |
| 20 #include "public/platform/modules/websockets/WebSocketHandle.h" | 20 #include "public/platform/modules/websockets/WebSocketHandle.h" |
| 21 #include "public/platform/modules/websockets/WebSocketHandleClient.h" | 21 #include "public/platform/modules/websockets/WebSocketHandleClient.h" |
| 22 #include "testing/gmock/include/gmock/gmock.h" | 22 #include "testing/gmock/include/gmock/gmock.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 24 #include "wtf/OwnPtr.h" | 24 #include "wtf/PtrUtil.h" |
| 25 #include "wtf/Vector.h" | 25 #include "wtf/Vector.h" |
| 26 #include "wtf/text/WTFString.h" | 26 #include "wtf/text/WTFString.h" |
| 27 #include <memory> |
| 27 #include <stdint.h> | 28 #include <stdint.h> |
| 28 | 29 |
| 29 using testing::_; | 30 using testing::_; |
| 30 using testing::InSequence; | 31 using testing::InSequence; |
| 31 using testing::PrintToString; | 32 using testing::PrintToString; |
| 32 using testing::AnyNumber; | 33 using testing::AnyNumber; |
| 33 | 34 |
| 34 | 35 |
| 35 namespace blink { | 36 namespace blink { |
| 36 | 37 |
| 37 namespace { | 38 namespace { |
| 38 | 39 |
| 39 typedef testing::StrictMock< testing::MockFunction<void(int)>> Checkpoint; | 40 typedef testing::StrictMock< testing::MockFunction<void(int)>> Checkpoint; |
| 40 | 41 |
| 41 class MockWebSocketChannelClient : public GarbageCollectedFinalized<MockWebSocke
tChannelClient>, public WebSocketChannelClient { | 42 class MockWebSocketChannelClient : public GarbageCollectedFinalized<MockWebSocke
tChannelClient>, public WebSocketChannelClient { |
| 42 USING_GARBAGE_COLLECTED_MIXIN(MockWebSocketChannelClient); | 43 USING_GARBAGE_COLLECTED_MIXIN(MockWebSocketChannelClient); |
| 43 public: | 44 public: |
| 44 static MockWebSocketChannelClient* create() | 45 static MockWebSocketChannelClient* create() |
| 45 { | 46 { |
| 46 return new testing::StrictMock<MockWebSocketChannelClient>(); | 47 return new testing::StrictMock<MockWebSocketChannelClient>(); |
| 47 } | 48 } |
| 48 | 49 |
| 49 MockWebSocketChannelClient() { } | 50 MockWebSocketChannelClient() { } |
| 50 | 51 |
| 51 ~MockWebSocketChannelClient() override { } | 52 ~MockWebSocketChannelClient() override { } |
| 52 | 53 |
| 53 MOCK_METHOD2(didConnect, void(const String&, const String&)); | 54 MOCK_METHOD2(didConnect, void(const String&, const String&)); |
| 54 MOCK_METHOD1(didReceiveTextMessage, void(const String&)); | 55 MOCK_METHOD1(didReceiveTextMessage, void(const String&)); |
| 55 void didReceiveBinaryMessage(PassOwnPtr<Vector<char>> payload) override | 56 void didReceiveBinaryMessage(std::unique_ptr<Vector<char>> payload) override |
| 56 { | 57 { |
| 57 didReceiveBinaryMessageMock(*payload); | 58 didReceiveBinaryMessageMock(*payload); |
| 58 } | 59 } |
| 59 MOCK_METHOD1(didReceiveBinaryMessageMock, void(const Vector<char>&)); | 60 MOCK_METHOD1(didReceiveBinaryMessageMock, void(const Vector<char>&)); |
| 60 MOCK_METHOD0(didError, void()); | 61 MOCK_METHOD0(didError, void()); |
| 61 MOCK_METHOD1(didConsumeBufferedAmount, void(uint64_t)); | 62 MOCK_METHOD1(didConsumeBufferedAmount, void(uint64_t)); |
| 62 MOCK_METHOD0(didStartClosingHandshake, void()); | 63 MOCK_METHOD0(didStartClosingHandshake, void()); |
| 63 MOCK_METHOD3(didClose, void(ClosingHandshakeCompletionStatus, unsigned short
, const String&)); | 64 MOCK_METHOD3(didClose, void(ClosingHandshakeCompletionStatus, unsigned short
, const String&)); |
| 64 | 65 |
| 65 DEFINE_INLINE_VIRTUAL_TRACE() | 66 DEFINE_INLINE_VIRTUAL_TRACE() |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 InSequence s; | 135 InSequence s; |
| 135 EXPECT_CALL(*handle(), connect(WebURL(KURL(KURL(), "ws://localhost/"
)), _, _, handleClient())); | 136 EXPECT_CALL(*handle(), connect(WebURL(KURL(KURL(), "ws://localhost/"
)), _, _, handleClient())); |
| 136 EXPECT_CALL(*handle(), flowControl(65536)); | 137 EXPECT_CALL(*handle(), flowControl(65536)); |
| 137 EXPECT_CALL(*channelClient(), didConnect(String("a"), String("b"))); | 138 EXPECT_CALL(*channelClient(), didConnect(String("a"), String("b"))); |
| 138 } | 139 } |
| 139 EXPECT_TRUE(channel()->connect(KURL(KURL(), "ws://localhost/"), "x")); | 140 EXPECT_TRUE(channel()->connect(KURL(KURL(), "ws://localhost/"), "x")); |
| 140 handleClient()->didConnect(handle(), WebString("a"), WebString("b")); | 141 handleClient()->didConnect(handle(), WebString("a"), WebString("b")); |
| 141 ::testing::Mock::VerifyAndClearExpectations(this); | 142 ::testing::Mock::VerifyAndClearExpectations(this); |
| 142 } | 143 } |
| 143 | 144 |
| 144 OwnPtr<DummyPageHolder> m_pageHolder; | 145 std::unique_ptr<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 |
| 151 MATCHER_P2(MemEq, p, len, | 152 MATCHER_P2(MemEq, p, len, |
| 152 std::string("pointing to memory") | 153 std::string("pointing to memory") |
| 153 + (negation ? " not" : "") | 154 + (negation ? " not" : "") |
| 154 + " equal to \"" | 155 + " equal to \"" |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 { | 234 { |
| 234 InSequence s; | 235 InSequence s; |
| 235 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("foo", 3), 3)); | 236 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("foo", 3), 3)); |
| 236 } | 237 } |
| 237 | 238 |
| 238 handleClient()->didReceiveFlowControl(handle(), 16); | 239 handleClient()->didReceiveFlowControl(handle(), 16); |
| 239 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); | 240 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); |
| 240 | 241 |
| 241 Vector<char> fooVector; | 242 Vector<char> fooVector; |
| 242 fooVector.append("foo", 3); | 243 fooVector.append("foo", 3); |
| 243 channel()->sendBinaryAsCharVector(adoptPtr(new Vector<char>(fooVector))); | 244 channel()->sendBinaryAsCharVector(wrapUnique(new Vector<char>(fooVector))); |
| 244 | 245 |
| 245 EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount); | 246 EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount); |
| 246 } | 247 } |
| 247 | 248 |
| 248 TEST_F(DocumentWebSocketChannelTest, sendBinaryInVectorWithNullBytes) | 249 TEST_F(DocumentWebSocketChannelTest, sendBinaryInVectorWithNullBytes) |
| 249 { | 250 { |
| 250 connect(); | 251 connect(); |
| 251 { | 252 { |
| 252 InSequence s; | 253 InSequence s; |
| 253 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("\0ar", 3), 3)); | 254 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("\0ar", 3), 3)); |
| 254 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("b\0z", 3), 3)); | 255 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("b\0z", 3), 3)); |
| 255 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("qu\0", 3), 3)); | 256 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("qu\0", 3), 3)); |
| 256 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("\0\0\0", 3), 3)); | 257 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, Me
mEq("\0\0\0", 3), 3)); |
| 257 } | 258 } |
| 258 | 259 |
| 259 handleClient()->didReceiveFlowControl(handle(), 16); | 260 handleClient()->didReceiveFlowControl(handle(), 16); |
| 260 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); | 261 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); |
| 261 | 262 |
| 262 { | 263 { |
| 263 Vector<char> v; | 264 Vector<char> v; |
| 264 v.append("\0ar", 3); | 265 v.append("\0ar", 3); |
| 265 channel()->sendBinaryAsCharVector(adoptPtr(new Vector<char>(v))); | 266 channel()->sendBinaryAsCharVector(wrapUnique(new Vector<char>(v))); |
| 266 } | 267 } |
| 267 { | 268 { |
| 268 Vector<char> v; | 269 Vector<char> v; |
| 269 v.append("b\0z", 3); | 270 v.append("b\0z", 3); |
| 270 channel()->sendBinaryAsCharVector(adoptPtr(new Vector<char>(v))); | 271 channel()->sendBinaryAsCharVector(wrapUnique(new Vector<char>(v))); |
| 271 } | 272 } |
| 272 { | 273 { |
| 273 Vector<char> v; | 274 Vector<char> v; |
| 274 v.append("qu\0", 3); | 275 v.append("qu\0", 3); |
| 275 channel()->sendBinaryAsCharVector(adoptPtr(new Vector<char>(v))); | 276 channel()->sendBinaryAsCharVector(wrapUnique(new Vector<char>(v))); |
| 276 } | 277 } |
| 277 { | 278 { |
| 278 Vector<char> v; | 279 Vector<char> v; |
| 279 v.append("\0\0\0", 3); | 280 v.append("\0\0\0", 3); |
| 280 channel()->sendBinaryAsCharVector(adoptPtr(new Vector<char>(v))); | 281 channel()->sendBinaryAsCharVector(wrapUnique(new Vector<char>(v))); |
| 281 } | 282 } |
| 282 | 283 |
| 283 EXPECT_EQ(12ul, m_sumOfConsumedBufferedAmount); | 284 EXPECT_EQ(12ul, m_sumOfConsumedBufferedAmount); |
| 284 } | 285 } |
| 285 | 286 |
| 286 TEST_F(DocumentWebSocketChannelTest, sendBinaryInVectorNonLatin1UTF8) | 287 TEST_F(DocumentWebSocketChannelTest, sendBinaryInVectorNonLatin1UTF8) |
| 287 { | 288 { |
| 288 connect(); | 289 connect(); |
| 289 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq(
"\xe7\x8b\x90", 3), 3)); | 290 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq(
"\xe7\x8b\x90", 3), 3)); |
| 290 | 291 |
| 291 handleClient()->didReceiveFlowControl(handle(), 16); | 292 handleClient()->didReceiveFlowControl(handle(), 16); |
| 292 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); | 293 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); |
| 293 | 294 |
| 294 Vector<char> v; | 295 Vector<char> v; |
| 295 v.append("\xe7\x8b\x90", 3); | 296 v.append("\xe7\x8b\x90", 3); |
| 296 channel()->sendBinaryAsCharVector(adoptPtr(new Vector<char>(v))); | 297 channel()->sendBinaryAsCharVector(wrapUnique(new Vector<char>(v))); |
| 297 | 298 |
| 298 EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount); | 299 EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount); |
| 299 } | 300 } |
| 300 | 301 |
| 301 TEST_F(DocumentWebSocketChannelTest, sendBinaryInVectorNonUTF8) | 302 TEST_F(DocumentWebSocketChannelTest, sendBinaryInVectorNonUTF8) |
| 302 { | 303 { |
| 303 connect(); | 304 connect(); |
| 304 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq(
"\x80\xff\xe7", 3), 3)); | 305 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq(
"\x80\xff\xe7", 3), 3)); |
| 305 | 306 |
| 306 handleClient()->didReceiveFlowControl(handle(), 16); | 307 handleClient()->didReceiveFlowControl(handle(), 16); |
| 307 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); | 308 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); |
| 308 | 309 |
| 309 Vector<char> v; | 310 Vector<char> v; |
| 310 v.append("\x80\xff\xe7", 3); | 311 v.append("\x80\xff\xe7", 3); |
| 311 channel()->sendBinaryAsCharVector(adoptPtr(new Vector<char>(v))); | 312 channel()->sendBinaryAsCharVector(wrapUnique(new Vector<char>(v))); |
| 312 | 313 |
| 313 EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount); | 314 EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount); |
| 314 } | 315 } |
| 315 | 316 |
| 316 TEST_F(DocumentWebSocketChannelTest, sendBinaryInVectorNonLatin1UTF8Continuation
) | 317 TEST_F(DocumentWebSocketChannelTest, sendBinaryInVectorNonLatin1UTF8Continuation
) |
| 317 { | 318 { |
| 318 connect(); | 319 connect(); |
| 319 Checkpoint checkpoint; | 320 Checkpoint checkpoint; |
| 320 { | 321 { |
| 321 InSequence s; | 322 InSequence s; |
| 322 EXPECT_CALL(*handle(), send(false, WebSocketHandle::MessageTypeBinary, M
emEq("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7", 16), 16
)); | 323 EXPECT_CALL(*handle(), send(false, WebSocketHandle::MessageTypeBinary, M
emEq("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7", 16), 16
)); |
| 323 EXPECT_CALL(checkpoint, Call(1)); | 324 EXPECT_CALL(checkpoint, Call(1)); |
| 324 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeContinuati
on, MemEq("\x8b\x90", 2), 2)); | 325 EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeContinuati
on, MemEq("\x8b\x90", 2), 2)); |
| 325 } | 326 } |
| 326 | 327 |
| 327 handleClient()->didReceiveFlowControl(handle(), 16); | 328 handleClient()->didReceiveFlowControl(handle(), 16); |
| 328 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); | 329 EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber()
); |
| 329 | 330 |
| 330 Vector<char> v; | 331 Vector<char> v; |
| 331 v.append("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x
8b\x90", 18); | 332 v.append("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x
8b\x90", 18); |
| 332 channel()->sendBinaryAsCharVector(adoptPtr(new Vector<char>(v))); | 333 channel()->sendBinaryAsCharVector(wrapUnique(new Vector<char>(v))); |
| 333 checkpoint.Call(1); | 334 checkpoint.Call(1); |
| 334 | 335 |
| 335 handleClient()->didReceiveFlowControl(handle(), 16); | 336 handleClient()->didReceiveFlowControl(handle(), 16); |
| 336 | 337 |
| 337 EXPECT_EQ(18ul, m_sumOfConsumedBufferedAmount); | 338 EXPECT_EQ(18ul, m_sumOfConsumedBufferedAmount); |
| 338 } | 339 } |
| 339 | 340 |
| 340 TEST_F(DocumentWebSocketChannelTest, sendBinaryInArrayBuffer) | 341 TEST_F(DocumentWebSocketChannelTest, sendBinaryInArrayBuffer) |
| 341 { | 342 { |
| 342 connect(); | 343 connect(); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 EXPECT_CALL(*channelClient(), didError()); | 680 EXPECT_CALL(*channelClient(), didError()); |
| 680 EXPECT_CALL(*channelClient(), didClose(WebSocketChannelClient::ClosingHa
ndshakeIncomplete, WebSocketChannel::CloseEventCodeAbnormalClosure, String())); | 681 EXPECT_CALL(*channelClient(), didClose(WebSocketChannelClient::ClosingHa
ndshakeIncomplete, WebSocketChannel::CloseEventCodeAbnormalClosure, String())); |
| 681 } | 682 } |
| 682 | 683 |
| 683 channel()->fail("fail message from WebSocket", ErrorMessageLevel, SourceLoca
tion::create(String(), 0, 0, nullptr)); | 684 channel()->fail("fail message from WebSocket", ErrorMessageLevel, SourceLoca
tion::create(String(), 0, 0, nullptr)); |
| 684 } | 685 } |
| 685 | 686 |
| 686 } // namespace | 687 } // namespace |
| 687 | 688 |
| 688 } // namespace blink | 689 } // namespace blink |
| OLD | NEW |