| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "net/spdy/spdy_session_pool.h" | 5 #include "net/spdy/spdy_session_pool.h" |
| 6 | 6 |
| 7 #include <cstddef> | 7 #include <cstddef> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 | 412 |
| 413 // Verify that we have sessions for everything. | 413 // Verify that we have sessions for everything. |
| 414 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[0].key)); | 414 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[0].key)); |
| 415 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key)); | 415 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key)); |
| 416 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[2].key)); | 416 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[2].key)); |
| 417 | 417 |
| 418 // Grab the session to host 1 and verify that it is the same session | 418 // Grab the session to host 1 and verify that it is the same session |
| 419 // we got with host 0, and that is a different from host 2's session. | 419 // we got with host 0, and that is a different from host 2's session. |
| 420 base::WeakPtr<SpdySession> session1 = | 420 base::WeakPtr<SpdySession> session1 = |
| 421 spdy_session_pool_->FindAvailableSession( | 421 spdy_session_pool_->FindAvailableSession( |
| 422 test_hosts[1].key, GURL(test_hosts[1].url), NetLogWithSource()); | 422 test_hosts[1].key, GURL(test_hosts[1].url), |
| 423 /* enable_ip_based_pooling = */ true, NetLogWithSource()); |
| 423 EXPECT_EQ(session.get(), session1.get()); | 424 EXPECT_EQ(session.get(), session1.get()); |
| 424 EXPECT_NE(session2.get(), session1.get()); | 425 EXPECT_NE(session2.get(), session1.get()); |
| 425 | 426 |
| 426 // Remove the aliases and observe that we still have a session for host1. | 427 // Remove the aliases and observe that we still have a session for host1. |
| 427 SpdySessionPoolPeer pool_peer(spdy_session_pool_); | 428 SpdySessionPoolPeer pool_peer(spdy_session_pool_); |
| 428 pool_peer.RemoveAliases(test_hosts[0].key); | 429 pool_peer.RemoveAliases(test_hosts[0].key); |
| 429 pool_peer.RemoveAliases(test_hosts[1].key); | 430 pool_peer.RemoveAliases(test_hosts[1].key); |
| 430 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key)); | 431 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key)); |
| 431 | 432 |
| 432 // Expire the host cache | 433 // Expire the host cache |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 CreateNetworkSession(); | 554 CreateNetworkSession(); |
| 554 | 555 |
| 555 // Open SpdySession to the first host. | 556 // Open SpdySession to the first host. |
| 556 base::WeakPtr<SpdySession> session0 = CreateSecureSpdySession( | 557 base::WeakPtr<SpdySession> session0 = CreateSecureSpdySession( |
| 557 http_session_.get(), test_hosts[0].key, NetLogWithSource()); | 558 http_session_.get(), test_hosts[0].key, NetLogWithSource()); |
| 558 | 559 |
| 559 // A request to the second host should pool to the existing connection. | 560 // A request to the second host should pool to the existing connection. |
| 560 BoundTestNetLog net_log; | 561 BoundTestNetLog net_log; |
| 561 base::HistogramTester histogram_tester; | 562 base::HistogramTester histogram_tester; |
| 562 base::WeakPtr<SpdySession> session1 = | 563 base::WeakPtr<SpdySession> session1 = |
| 563 spdy_session_pool_->FindAvailableSession(test_hosts[1].key, GURL(), | 564 spdy_session_pool_->FindAvailableSession( |
| 564 net_log.bound()); | 565 test_hosts[1].key, GURL(), |
| 566 /* enable_ip_based_pooling = */ true, net_log.bound()); |
| 565 EXPECT_EQ(session0.get(), session1.get()); | 567 EXPECT_EQ(session0.get(), session1.get()); |
| 566 | 568 |
| 567 ASSERT_EQ(1u, net_log.GetSize()); | 569 ASSERT_EQ(1u, net_log.GetSize()); |
| 568 histogram_tester.ExpectTotalCount("Net.SpdySessionGet", 1); | 570 histogram_tester.ExpectTotalCount("Net.SpdySessionGet", 1); |
| 569 | 571 |
| 570 // A request to the second host should still pool to the existing connection. | 572 // A request to the second host should still pool to the existing connection. |
| 571 session1 = spdy_session_pool_->FindAvailableSession(test_hosts[1].key, GURL(), | 573 session1 = spdy_session_pool_->FindAvailableSession( |
| 572 net_log.bound()); | 574 test_hosts[1].key, GURL(), |
| 575 /* enable_ip_based_pooling = */ true, net_log.bound()); |
| 573 EXPECT_EQ(session0.get(), session1.get()); | 576 EXPECT_EQ(session0.get(), session1.get()); |
| 574 | 577 |
| 575 ASSERT_EQ(2u, net_log.GetSize()); | 578 ASSERT_EQ(2u, net_log.GetSize()); |
| 576 histogram_tester.ExpectTotalCount("Net.SpdySessionGet", 2); | 579 histogram_tester.ExpectTotalCount("Net.SpdySessionGet", 2); |
| 577 | 580 |
| 578 // Both FindAvailableSession() calls should log netlog events | 581 // Both FindAvailableSession() calls should log netlog events |
| 579 // indicating IP pooling. | 582 // indicating IP pooling. |
| 580 TestNetLogEntry::List entry_list; | 583 TestNetLogEntry::List entry_list; |
| 581 net_log.GetEntries(&entry_list); | 584 net_log.GetEntries(&entry_list); |
| 582 EXPECT_EQ( | 585 EXPECT_EQ( |
| 583 NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, | 586 NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, |
| 584 entry_list[0].type); | 587 entry_list[0].type); |
| 585 EXPECT_EQ( | 588 EXPECT_EQ( |
| 586 NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, | 589 NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, |
| 587 entry_list[1].type); | 590 entry_list[1].type); |
| 588 | 591 |
| 589 // Both FindAvailableSession() calls should log histogram entries | 592 // Both FindAvailableSession() calls should log histogram entries |
| 590 // indicating IP pooling. | 593 // indicating IP pooling. |
| 591 histogram_tester.ExpectUniqueSample("Net.SpdySessionGet", 2, 2); | 594 histogram_tester.ExpectUniqueSample("Net.SpdySessionGet", 2, 2); |
| 592 } | 595 } |
| 593 | 596 |
| 597 TEST_F(SpdySessionPoolTest, IPPoolingDisabled) { |
| 598 // Define two hosts with identical IP address. |
| 599 const int kTestPort = 443; |
| 600 struct TestHosts { |
| 601 std::string name; |
| 602 std::string iplist; |
| 603 SpdySessionKey key; |
| 604 AddressList addresses; |
| 605 std::unique_ptr<HostResolver::Request> request; |
| 606 } test_hosts[] = { |
| 607 {"www.example.org", "192.168.0.1"}, {"mail.example.org", "192.168.0.1"}, |
| 608 }; |
| 609 |
| 610 // Populate the HostResolver cache. |
| 611 session_deps_.host_resolver->set_synchronous_mode(true); |
| 612 for (size_t i = 0; i < arraysize(test_hosts); i++) { |
| 613 session_deps_.host_resolver->rules()->AddIPLiteralRule( |
| 614 test_hosts[i].name, test_hosts[i].iplist, std::string()); |
| 615 |
| 616 HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort)); |
| 617 session_deps_.host_resolver->Resolve( |
| 618 info, DEFAULT_PRIORITY, &test_hosts[i].addresses, CompletionCallback(), |
| 619 &test_hosts[i].request, NetLogWithSource()); |
| 620 |
| 621 test_hosts[i].key = |
| 622 SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort), |
| 623 ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
| 624 } |
| 625 |
| 626 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; |
| 627 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 628 MockConnect connect_data(SYNCHRONOUS, OK); |
| 629 data.set_connect_data(connect_data); |
| 630 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 631 AddSSLSocketData(); |
| 632 |
| 633 MockRead reads1[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; |
| 634 StaticSocketDataProvider data1(reads1, arraysize(reads1), nullptr, 0); |
| 635 MockConnect connect_data1(SYNCHRONOUS, OK); |
| 636 data1.set_connect_data(connect_data1); |
| 637 session_deps_.socket_factory->AddSocketDataProvider(&data1); |
| 638 AddSSLSocketData(); |
| 639 |
| 640 CreateNetworkSession(); |
| 641 |
| 642 // Open SpdySession to the first host. |
| 643 base::WeakPtr<SpdySession> session0 = CreateSecureSpdySession( |
| 644 http_session_.get(), test_hosts[0].key, NetLogWithSource()); |
| 645 |
| 646 // A request to the second host should pool to the existing connection. |
| 647 base::WeakPtr<SpdySession> session1 = |
| 648 spdy_session_pool_->FindAvailableSession( |
| 649 test_hosts[1].key, GURL(), |
| 650 /* enable_ip_based_pooling = */ true, NetLogWithSource()); |
| 651 EXPECT_EQ(session0.get(), session1.get()); |
| 652 |
| 653 // A request to the second host should not pool to the existing connection if |
| 654 // IP based pooling is disabled. |
| 655 session1 = spdy_session_pool_->FindAvailableSession( |
| 656 test_hosts[1].key, GURL(), |
| 657 /* enable_ip_based_pooling = */ false, NetLogWithSource()); |
| 658 EXPECT_FALSE(session1); |
| 659 |
| 660 // It should be possible to open a new SpdySession, even if a previous call to |
| 661 // FindAvailableSession() linked the second key to the first connection in the |
| 662 // IP pooled bucket of SpdySessionPool::available_session_map_. |
| 663 session1 = CreateSecureSpdySessionWithIpBasedPoolingDisabled( |
| 664 http_session_.get(), test_hosts[1].key, NetLogWithSource()); |
| 665 EXPECT_TRUE(session1); |
| 666 EXPECT_NE(session0.get(), session1.get()); |
| 667 } |
| 668 |
| 594 // Construct a Pool with SpdySessions in various availability states. Simulate | 669 // Construct a Pool with SpdySessions in various availability states. Simulate |
| 595 // an IP address change. Ensure sessions gracefully shut down. Regression test | 670 // an IP address change. Ensure sessions gracefully shut down. Regression test |
| 596 // for crbug.com/379469. | 671 // for crbug.com/379469. |
| 597 TEST_F(SpdySessionPoolTest, IPAddressChanged) { | 672 TEST_F(SpdySessionPoolTest, IPAddressChanged) { |
| 598 MockConnect connect_data(SYNCHRONOUS, OK); | 673 MockConnect connect_data(SYNCHRONOUS, OK); |
| 599 session_deps_.host_resolver->set_synchronous_mode(true); | 674 session_deps_.host_resolver->set_synchronous_mode(true); |
| 600 | 675 |
| 601 // This isn't testing anything having to do with SPDY frames; we | 676 // This isn't testing anything having to do with SPDY frames; we |
| 602 // can ignore issues of how dependencies are set. We default to | 677 // can ignore issues of how dependencies are set. We default to |
| 603 // setting them (when doing the appropriate protocol) since that's | 678 // setting them (when doing the appropriate protocol) since that's |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 base::WeakPtr<SpdySession> session = | 808 base::WeakPtr<SpdySession> session = |
| 734 CreateSecureSpdySession(http_session_.get(), key, NetLogWithSource()); | 809 CreateSecureSpdySession(http_session_.get(), key, NetLogWithSource()); |
| 735 | 810 |
| 736 // Flush the SpdySession::OnReadComplete() task. | 811 // Flush the SpdySession::OnReadComplete() task. |
| 737 base::RunLoop().RunUntilIdle(); | 812 base::RunLoop().RunUntilIdle(); |
| 738 | 813 |
| 739 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key)); | 814 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key)); |
| 740 | 815 |
| 741 // FindAvailableSession should return |session| if called with empty |url|. | 816 // FindAvailableSession should return |session| if called with empty |url|. |
| 742 base::WeakPtr<SpdySession> session1 = | 817 base::WeakPtr<SpdySession> session1 = |
| 743 spdy_session_pool_->FindAvailableSession(key, GURL(), NetLogWithSource()); | 818 spdy_session_pool_->FindAvailableSession( |
| 819 key, GURL(), |
| 820 /* enable_ip_based_pooling = */ true, NetLogWithSource()); |
| 744 EXPECT_EQ(session.get(), session1.get()); | 821 EXPECT_EQ(session.get(), session1.get()); |
| 745 | 822 |
| 746 // FindAvailableSession should return |session| if called with |url| for which | 823 // FindAvailableSession should return |session| if called with |url| for which |
| 747 // there is no pushed stream on any sessions owned by |spdy_session_pool_|. | 824 // there is no pushed stream on any sessions owned by |spdy_session_pool_|. |
| 748 base::WeakPtr<SpdySession> session2 = | 825 base::WeakPtr<SpdySession> session2 = |
| 749 spdy_session_pool_->FindAvailableSession( | 826 spdy_session_pool_->FindAvailableSession( |
| 750 key, GURL("http://news.example.org/foo.html"), NetLogWithSource()); | 827 key, GURL("http://news.example.org/foo.html"), |
| 828 /* enable_ip_based_pooling = */ true, NetLogWithSource()); |
| 751 EXPECT_EQ(session.get(), session2.get()); | 829 EXPECT_EQ(session.get(), session2.get()); |
| 752 | 830 |
| 753 spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED); | 831 spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED); |
| 754 } | 832 } |
| 755 | 833 |
| 756 class SpdySessionMemoryDumpTest | 834 class SpdySessionMemoryDumpTest |
| 757 : public SpdySessionPoolTest, | 835 : public SpdySessionPoolTest, |
| 758 public testing::WithParamInterface< | 836 public testing::WithParamInterface< |
| 759 base::trace_event::MemoryDumpLevelOfDetail> {}; | 837 base::trace_event::MemoryDumpLevelOfDetail> {}; |
| 760 | 838 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 active_session_count_attr->GetString("value", &active_session_count)); | 892 active_session_count_attr->GetString("value", &active_session_count)); |
| 815 // No created stream so the session should be idle. | 893 // No created stream so the session should be idle. |
| 816 ASSERT_EQ("0", active_session_count); | 894 ASSERT_EQ("0", active_session_count); |
| 817 did_dump = true; | 895 did_dump = true; |
| 818 } | 896 } |
| 819 EXPECT_TRUE(did_dump); | 897 EXPECT_TRUE(did_dump); |
| 820 spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED); | 898 spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED); |
| 821 } | 899 } |
| 822 | 900 |
| 823 } // namespace net | 901 } // namespace net |
| OLD | NEW |