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