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 |