OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 3686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3697 | 3697 |
3698 // Request and response. | 3698 // Request and response. |
3699 data.RunFor(2); | 3699 data.RunFor(2); |
3700 EXPECT_EQ(1u, spdy_stream->stream_id()); | 3700 EXPECT_EQ(1u, spdy_stream->stream_id()); |
3701 | 3701 |
3702 // Too large data frame causes flow control error, should close stream. | 3702 // Too large data frame causes flow control error, should close stream. |
3703 data.RunFor(1); | 3703 data.RunFor(1); |
3704 EXPECT_EQ(nullptr, spdy_stream.get()); | 3704 EXPECT_EQ(nullptr, spdy_stream.get()); |
3705 } | 3705 } |
3706 | 3706 |
3707 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE | |
3708 // deltas in the receiving window size when checking incoming packets for flow | |
3709 // control errors at session level. | |
3710 TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoPackets) { | |
3711 if (GetParam() < kProtoSPDY31) | |
3712 return; | |
3713 | |
3714 const int32 session_max_recv_window_size = 500; | |
3715 const int32 first_packet_size = 200; | |
3716 const int32 second_packet_size = 400; | |
Ryan Hamilton
2015/04/27 15:27:18
nit: should these be "packet" sizes, or "frame" si
Bence
2015/04/28 13:33:18
These are frame sizes. Good catch. Done.
| |
3717 | |
3718 // First packet should not trigger a WINDOW_UPDATE. | |
3719 ASSERT_GT(session_max_recv_window_size / 2, first_packet_size); | |
3720 // Second packet would be fine had there been a WINDOW_UPDATE. | |
3721 ASSERT_GT(session_max_recv_window_size, second_packet_size); | |
3722 // But in fact, the two packets together overflow the receiving window at | |
3723 // session level. | |
3724 ASSERT_LT(session_max_recv_window_size, | |
3725 first_packet_size + second_packet_size); | |
3726 | |
3727 session_deps_.host_resolver->set_synchronous_mode(true); | |
3728 | |
3729 const std::string first_packet(first_packet_size, 'a'); | |
3730 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame( | |
3731 1, first_packet.data(), first_packet_size, false)); | |
3732 const std::string second_packet(second_packet_size, 'b'); | |
3733 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame( | |
3734 1, second_packet.data(), second_packet_size, false)); | |
3735 MockRead reads[] = { | |
3736 CreateMockRead(*first, 0), | |
3737 CreateMockRead(*second, 1), | |
3738 MockRead(ASYNC, 0, 2), | |
3739 }; | |
3740 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); | |
3741 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
3742 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
3743 | |
3744 CreateDeterministicNetworkSession(); | |
3745 base::WeakPtr<SpdySession> session = | |
3746 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | |
3747 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | |
3748 session->flow_control_state()); | |
3749 // Setting session level receiving window size to smaller than initial is not | |
3750 // possible via SpdySessionPoolPeer. | |
3751 session->session_recv_window_size_ = session_max_recv_window_size; | |
3752 | |
3753 // First packet is immediately consumed and does not trigger WINDOW_UPDATE. | |
3754 data.RunFor(1); | |
3755 EXPECT_EQ(first_packet_size, session->session_unacked_recv_window_bytes_); | |
3756 EXPECT_EQ(session_max_recv_window_size, session->session_recv_window_size_); | |
3757 EXPECT_EQ(SpdySession::STATE_AVAILABLE, session->availability_state_); | |
3758 | |
3759 // Second packet overflows receiving window, causes session to close. | |
3760 data.RunFor(1); | |
3761 EXPECT_EQ(SpdySession::STATE_DRAINING, session->availability_state_); | |
3762 } | |
3763 | |
3764 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE | |
3765 // deltas in the receiving window size when checking incoming packets for flow | |
3766 // control errors at stream level. | |
3767 TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoPackets) { | |
3768 if (GetParam() < kProtoSPDY3) | |
3769 return; | |
3770 | |
3771 const int32 stream_max_recv_window_size = 500; | |
3772 const int32 first_packet_size = 200; | |
3773 const int32 second_packet_size = 400; | |
3774 | |
3775 // First packet should not trigger a WINDOW_UPDATE. | |
3776 ASSERT_GT(stream_max_recv_window_size / 2, first_packet_size); | |
3777 // Second packet would be fine had there been a WINDOW_UPDATE. | |
3778 ASSERT_GT(stream_max_recv_window_size, second_packet_size); | |
3779 // But in fact, they should overflow the receiving window at stream level. | |
3780 ASSERT_LT(stream_max_recv_window_size, | |
3781 first_packet_size + second_packet_size); | |
3782 | |
3783 scoped_ptr<SpdyFrame> req( | |
3784 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | |
3785 scoped_ptr<SpdyFrame> rst( | |
3786 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); | |
3787 MockWrite writes[] = { | |
3788 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), | |
3789 }; | |
3790 | |
3791 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | |
3792 const std::string first_packet(first_packet_size, 'a'); | |
3793 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame( | |
3794 1, first_packet.data(), first_packet_size, false)); | |
3795 const std::string second_packet(second_packet_size, 'b'); | |
3796 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame( | |
3797 1, second_packet.data(), second_packet_size, false)); | |
3798 MockRead reads[] = { | |
3799 CreateMockRead(*resp, 1), | |
3800 CreateMockRead(*first, 2), | |
3801 CreateMockRead(*second, 3), | |
3802 MockRead(ASYNC, 0, 5), | |
3803 }; | |
3804 | |
3805 DeterministicSocketData data(reads, arraysize(reads), writes, | |
3806 arraysize(writes)); | |
3807 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
3808 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
3809 | |
3810 CreateDeterministicNetworkSession(); | |
3811 SpdySessionPoolPeer pool_peer(spdy_session_pool_); | |
3812 pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size); | |
3813 | |
3814 base::WeakPtr<SpdySession> session = | |
3815 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | |
3816 EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state()); | |
3817 | |
3818 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( | |
3819 SPDY_REQUEST_RESPONSE_STREAM, session, test_url_, LOWEST, BoundNetLog()); | |
3820 test::StreamDelegateDoNothing delegate(spdy_stream); | |
3821 spdy_stream->SetDelegate(&delegate); | |
3822 | |
3823 scoped_ptr<SpdyHeaderBlock> headers( | |
3824 spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); | |
3825 EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders( | |
3826 headers.Pass(), NO_MORE_DATA_TO_SEND)); | |
3827 | |
3828 // Request and response. | |
3829 data.RunFor(2); | |
3830 EXPECT_TRUE(spdy_stream->IsLocallyClosed()); | |
3831 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size()); | |
3832 | |
3833 // First packet. | |
3834 data.RunFor(1); | |
3835 EXPECT_TRUE(spdy_stream->IsLocallyClosed()); | |
3836 EXPECT_EQ(stream_max_recv_window_size - first_packet_size, | |
3837 spdy_stream->recv_window_size()); | |
3838 | |
3839 // Consume first packet. This does not trigger a WINDOW_UPDATE. | |
3840 std::string received_data = delegate.TakeReceivedData(); | |
3841 EXPECT_EQ(static_cast<size_t>(first_packet_size), received_data.size()); | |
3842 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size()); | |
3843 | |
3844 // Second packet overflows receiving window, causes the stream to close. | |
3845 data.RunFor(1); | |
3846 EXPECT_FALSE(spdy_stream.get()); | |
3847 | |
3848 // RST_STREAM | |
3849 data.RunFor(1); | |
3850 } | |
3851 | |
3707 // A delegate that drops any received data. | 3852 // A delegate that drops any received data. |
3708 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { | 3853 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { |
3709 public: | 3854 public: |
3710 DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream, | 3855 DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream, |
3711 base::StringPiece data) | 3856 base::StringPiece data) |
3712 : StreamDelegateSendImmediate(stream, data) {} | 3857 : StreamDelegateSendImmediate(stream, data) {} |
3713 | 3858 |
3714 ~DropReceivedDataDelegate() override {} | 3859 ~DropReceivedDataDelegate() override {} |
3715 | 3860 |
3716 // Drop any received data. | 3861 // Drop any received data. |
(...skipping 1481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5198 ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), | 5343 ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), |
5199 "spdy_pooling.pem"); | 5344 "spdy_pooling.pem"); |
5200 ssl_info.is_issued_by_known_root = true; | 5345 ssl_info.is_issued_by_known_root = true; |
5201 ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin)); | 5346 ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin)); |
5202 | 5347 |
5203 EXPECT_TRUE(SpdySession::CanPool( | 5348 EXPECT_TRUE(SpdySession::CanPool( |
5204 &tss, ssl_info, "www.example.org", "mail.example.org")); | 5349 &tss, ssl_info, "www.example.org", "mail.example.org")); |
5205 } | 5350 } |
5206 | 5351 |
5207 } // namespace net | 5352 } // namespace net |
OLD | NEW |