158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/websockets/websocket_throttle.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket_stream/socket_stream.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_test_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/websockets/websocket_job.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h" 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DummySocketStreamDelegate : public net::SocketStream::Delegate { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DummySocketStreamDelegate() {} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DummySocketStreamDelegate() {} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnConnected( 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::SocketStream* socket, int max_pending_send_allowed) OVERRIDE {} 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnSentData(net::SocketStream* socket, 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int amount_sent) OVERRIDE {} 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnReceivedData(net::SocketStream* socket, 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* data, int len) OVERRIDE {} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnClose(net::SocketStream* socket) OVERRIDE {} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebSocketThrottleTest : public PlatformTest { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static IPEndPoint MakeAddr(int a1, int a2, int a3, int a4) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber ip; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip.push_back(a1); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip.push_back(a2); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip.push_back(a3); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip.push_back(a4); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPEndPoint(ip, 0); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void MockSocketStreamConnect( 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SocketStream* socket, const AddressList& list) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket->set_addresses(list); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(toyoshim): We should introduce additional tests on cases via proxy. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket->proxy_info_.UseDirect(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In SocketStream::Connect(), it adds reference to socket, which is 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // balanced with SocketStream::Finish() that is finally called from 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SocketStream::Close() or SocketStream::DetachDelegate(), when 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // next_state_ is not STATE_NONE. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If next_state_ is STATE_NONE, SocketStream::Close() or 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SocketStream::DetachDelegate() won't call SocketStream::Finish(), 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so Release() won't be called. Thus, we don't need socket->AddRef() 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(socket->next_state_, SocketStream::STATE_NONE); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebSocketThrottleTest, Throttle) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestURLRequestContext context; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DummySocketStreamDelegate delegate; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(toyoshim): We need to consider both spdy-enabled and spdy-disabled 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // configuration. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSocketJob::set_websocket_over_spdy_enabled(true); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For host1: 1.2.3.4, 1.2.3.5, 1.2.3.6 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList addr; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 4)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 5)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 6)); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebSocketJob> w1(new WebSocketJob(&delegate)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SocketStream> s1( 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SocketStream(GURL("ws://host1/"), w1.get())); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s1->set_context(&context); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w1->InitSocketStream(s1.get()); 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebSocketThrottleTest::MockSocketStreamConnect(s1.get(), addr); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket1"; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback_s1; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to open connection to host1 will start without wait. 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(OK, w1->OnStartOpenConnection(s1.get(), callback_s1.callback())); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now connecting to host1, so waiting queue looks like 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w1 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w1 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w1 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For host2: 1.2.3.4 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.clear(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 4)); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebSocketJob> w2(new WebSocketJob(&delegate)); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SocketStream> s2( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SocketStream(GURL("ws://host2/"), w2.get())); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s2->set_context(&context); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w2->InitSocketStream(s2.get()); 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebSocketThrottleTest::MockSocketStreamConnect(s2.get(), addr); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket2"; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback_s2; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to open connection to host2 will wait for w1. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) w2->OnStartOpenConnection(s2.get(), callback_s2.callback())); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now waiting queue looks like 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w1 w2 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w1 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w1 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For host3: 1.2.3.5 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.clear(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 5)); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebSocketJob> w3(new WebSocketJob(&delegate)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SocketStream> s3( 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SocketStream(GURL("ws://host3/"), w3.get())); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s3->set_context(&context); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w3->InitSocketStream(s3.get()); 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebSocketThrottleTest::MockSocketStreamConnect(s3.get(), addr); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket3"; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback_s3; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to open connection to host3 will wait for w1. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) w3->OnStartOpenConnection(s3.get(), callback_s3.callback())); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w1 w2 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w1 w3 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w1 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For host4: 1.2.3.4, 1.2.3.6 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.clear(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 4)); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 6)); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebSocketJob> w4(new WebSocketJob(&delegate)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SocketStream> s4( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SocketStream(GURL("ws://host4/"), w4.get())); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s4->set_context(&context); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w4->InitSocketStream(s4.get()); 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebSocketThrottleTest::MockSocketStreamConnect(s4.get(), addr); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket4"; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback_s4; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to open connection to host4 will wait for w1, w2. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) w4->OnStartOpenConnection(s4.get(), callback_s4.callback())); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w1 w2 w4 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w1 w3 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w1 w4 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For host5: 1.2.3.6 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.clear(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 6)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebSocketJob> w5(new WebSocketJob(&delegate)); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SocketStream> s5( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SocketStream(GURL("ws://host5/"), w5.get())); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s5->set_context(&context); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w5->InitSocketStream(s5.get()); 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebSocketThrottleTest::MockSocketStreamConnect(s5.get(), addr); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket5"; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback_s5; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to open connection to host5 will wait for w1, w4 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) w5->OnStartOpenConnection(s5.get(), callback_s5.callback())); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w1 w2 w4 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w1 w3 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w1 w4 w5 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For host6: 1.2.3.6 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.clear(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(1, 2, 3, 6)); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebSocketJob> w6(new WebSocketJob(&delegate)); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SocketStream> s6( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SocketStream(GURL("ws://host6/"), w6.get())); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s6->set_context(&context); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w6->InitSocketStream(s6.get()); 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebSocketThrottleTest::MockSocketStreamConnect(s6.get(), addr); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket6"; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback_s6; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to open connection to host6 will wait for w1, w4, w5 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) w6->OnStartOpenConnection(s6.get(), callback_s6.callback())); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w1 w2 w4 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w1 w3 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w1 w4 w5 w6 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive partial response on w1, still connecting. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket1 1"; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kHeader[] = "HTTP/1.1 101 WebSocket Protocol\r\n"; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w1->OnReceivedData(s1.get(), kHeader, sizeof(kHeader) - 1); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s2.have_result()); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s3.have_result()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s4.have_result()); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s5.have_result()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s6.have_result()); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive rest of handshake response on w1. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket1 2"; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kHeader2[] = 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Upgrade: WebSocket\r\n" 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Connection: Upgrade\r\n" 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Sec-WebSocket-Origin: http://www.google.com\r\n" 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Sec-WebSocket-Location: ws://websocket.chromium.org\r\n" 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\r\n" 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "8jKS'y:G*Co,Wxa-"; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w1->OnReceivedData(s1.get(), kHeader2, sizeof(kHeader2) - 1); 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now, w1 is open. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(WebSocketJob::OPEN, w1->state()); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So, w2 and w3 can start connecting. w4 needs to wait w2 (1.2.3.4) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(callback_s2.have_result()); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(callback_s3.have_result()); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s4.have_result()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w2 w4 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w3 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w4 w5 w6 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Closing s1 doesn't change waiting queue. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket1 close"; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w1->OnClose(s1.get()); 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s4.have_result()); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s1->DetachDelegate(); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w2 w4 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w3 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w4 w5 w6 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // w5 can close while waiting in queue. 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket5 close"; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // w5 close() closes SocketStream that change state to STATE_CLOSE, calls 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DoLoop(), so OnClose() callback will be called. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w5->OnClose(s5.get()); 24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s4.have_result()); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w2 w4 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w3 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w4 w6 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s5->DetachDelegate(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // w6 close abnormally (e.g. renderer finishes) while waiting in queue. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket6 close abnormally"; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w6->DetachDelegate(); 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(callback_s4.have_result()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w2 w4 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w3 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w4 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Closing s2 kicks w4 to start connecting. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket2 close"; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w2->OnClose(s2.get()); 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(callback_s4.have_result()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Address | head -> tail 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.4 | w4 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.5 | w3 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1.2.3.6 | w4 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s2->DetachDelegate(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket3 close"; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w3->OnClose(s3.get()); 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s3->DetachDelegate(); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w4->OnClose(s4.get()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s4->DetachDelegate(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Done"; 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebSocketThrottleTest, NoThrottleForDuplicateAddress) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestURLRequestContext context; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DummySocketStreamDelegate delegate; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSocketJob::set_websocket_over_spdy_enabled(true); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For localhost: 127.0.0.1, 127.0.0.1 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList addr; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(127, 0, 0, 1)); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.push_back(MakeAddr(127, 0, 0, 1)); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebSocketJob> w1(new WebSocketJob(&delegate)); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SocketStream> s1( 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SocketStream(GURL("ws://localhost/"), w1.get())); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s1->set_context(&context); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w1->InitSocketStream(s1.get()); 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebSocketThrottleTest::MockSocketStreamConnect(s1.get(), addr); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket1"; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback_s1; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to open connection to localhost will start without wait. 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(OK, w1->OnStartOpenConnection(s1.get(), callback_s1.callback())); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "socket1 close"; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w1->OnClose(s1.get()); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s1->DetachDelegate(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Done"; 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A connection should not be blocked by another connection to the same IP 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// with a different port. 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WebSocketThrottleTest, NoThrottleForDistinctPort) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestURLRequestContext context; 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DummySocketStreamDelegate delegate; 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPAddressNumber localhost; 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseIPLiteralToNumber("127.0.0.1", &localhost); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebSocketJob::set_websocket_over_spdy_enabled(false); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // socket1: 127.0.0.1:80 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<WebSocketJob> w1(new WebSocketJob(&delegate)); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SocketStream> s1( 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new SocketStream(GURL("ws://localhost:80/"), w1.get())); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) s1->set_context(&context); 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) w1->InitSocketStream(s1.get()); 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MockSocketStreamConnect(s1.get(), 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddressList::CreateFromIPAddress(localhost, 80)); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "connecting socket1"; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestCompletionCallback callback_s1; 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Trying to open connection to localhost:80 will start without waiting. 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(OK, w1->OnStartOpenConnection(s1.get(), callback_s1.callback())); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // socket2: 127.0.0.1:81 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<WebSocketJob> w2(new WebSocketJob(&delegate)); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SocketStream> s2( 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new SocketStream(GURL("ws://localhost:81/"), w2.get())); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) s2->set_context(&context); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) w2->InitSocketStream(s2.get()); 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MockSocketStreamConnect(s2.get(), 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddressList::CreateFromIPAddress(localhost, 81)); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "connecting socket2"; 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestCompletionCallback callback_s2; 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Trying to open connection to localhost:81 will start without waiting. 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(OK, w2->OnStartOpenConnection(s2.get(), callback_s2.callback())); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "closing socket1"; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) w1->OnClose(s1.get()); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) s1->DetachDelegate(); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "closing socket2"; 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) w2->OnClose(s2.get()); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) s2->DetachDelegate(); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Done"; 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO::current()->RunUntilIdle(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 358