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/quic/quic_session.h" | 5 #include "net/quic/quic_session.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
| 8 #include <vector> |
8 | 9 |
9 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
10 #include "net/quic/crypto/crypto_handshake.h" | 11 #include "net/quic/crypto/crypto_handshake.h" |
11 #include "net/quic/quic_connection.h" | 12 #include "net/quic/quic_connection.h" |
12 #include "net/quic/quic_protocol.h" | 13 #include "net/quic/quic_protocol.h" |
13 #include "net/quic/test_tools/quic_connection_peer.h" | 14 #include "net/quic/test_tools/quic_connection_peer.h" |
14 #include "net/quic/test_tools/quic_test_utils.h" | 15 #include "net/quic/test_tools/quic_test_utils.h" |
| 16 #include "net/spdy/spdy_framer.h" |
15 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
17 | 19 |
18 using base::hash_map; | 20 using base::hash_map; |
19 using std::set; | 21 using std::set; |
| 22 using std::vector; |
20 using testing::_; | 23 using testing::_; |
21 using testing::InSequence; | 24 using testing::InSequence; |
22 | 25 |
23 namespace net { | 26 namespace net { |
24 namespace test { | 27 namespace test { |
25 namespace { | 28 namespace { |
26 | 29 |
27 class TestCryptoStream : public QuicCryptoStream { | 30 class TestCryptoStream : public QuicCryptoStream { |
28 public: | 31 public: |
29 explicit TestCryptoStream(QuicSession* session) | 32 explicit TestCryptoStream(QuicSession* session) |
(...skipping 13 matching lines...) Expand all Loading... |
43 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 46 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
44 } | 47 } |
45 }; | 48 }; |
46 | 49 |
47 class TestStream : public ReliableQuicStream { | 50 class TestStream : public ReliableQuicStream { |
48 public: | 51 public: |
49 TestStream(QuicStreamId id, QuicSession* session) | 52 TestStream(QuicStreamId id, QuicSession* session) |
50 : ReliableQuicStream(id, session) { | 53 : ReliableQuicStream(id, session) { |
51 } | 54 } |
52 | 55 |
| 56 using ReliableQuicStream::CloseWriteSide; |
| 57 |
53 virtual uint32 ProcessData(const char* data, uint32 data_len) { | 58 virtual uint32 ProcessData(const char* data, uint32 data_len) { |
54 return data_len; | 59 return data_len; |
55 } | 60 } |
56 | 61 |
57 MOCK_METHOD0(OnCanWrite, void()); | 62 MOCK_METHOD0(OnCanWrite, void()); |
58 }; | 63 }; |
59 | 64 |
60 class TestSession : public QuicSession { | 65 class TestSession : public QuicSession { |
61 public: | 66 public: |
62 TestSession(QuicConnection* connection, bool is_server) | 67 TestSession(QuicConnection* connection, bool is_server) |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 session_.MarkWriteBlocked(6); | 217 session_.MarkWriteBlocked(6); |
213 session_.MarkWriteBlocked(4); | 218 session_.MarkWriteBlocked(4); |
214 CloseStream(6); | 219 CloseStream(6); |
215 | 220 |
216 InSequence s; | 221 InSequence s; |
217 EXPECT_CALL(*stream2, OnCanWrite()); | 222 EXPECT_CALL(*stream2, OnCanWrite()); |
218 EXPECT_CALL(*stream4, OnCanWrite()); | 223 EXPECT_CALL(*stream4, OnCanWrite()); |
219 EXPECT_TRUE(session_.OnCanWrite()); | 224 EXPECT_TRUE(session_.OnCanWrite()); |
220 } | 225 } |
221 | 226 |
| 227 // Regression test for http://crbug.com/248737 |
| 228 TEST_F(QuicSessionTest, OutOfOrderHeaders) { |
| 229 QuicSpdyCompressor compressor; |
| 230 SpdyHeaderBlock headers; |
| 231 headers[":host"] = "www.google.com"; |
| 232 headers[":path"] = "/index.hml"; |
| 233 headers[":scheme"] = "http"; |
| 234 vector<QuicStreamFrame> frames; |
| 235 QuicPacketHeader header; |
| 236 header.public_header.guid = session_.guid(); |
| 237 |
| 238 TestStream* stream2 = session_.CreateOutgoingReliableStream(); |
| 239 TestStream* stream4 = session_.CreateOutgoingReliableStream(); |
| 240 stream2->CloseWriteSide(); |
| 241 stream4->CloseWriteSide(); |
| 242 |
| 243 // Create frame with headers for stream2. |
| 244 string compressed_headers1 = compressor.CompressHeaders(headers); |
| 245 QuicStreamFrame frame1(stream2->id(), false, 0, compressed_headers1); |
| 246 |
| 247 // Create frame with headers for stream4. |
| 248 string compressed_headers2 = compressor.CompressHeaders(headers); |
| 249 QuicStreamFrame frame2(stream4->id(), true, 0, compressed_headers2); |
| 250 |
| 251 // Process the second frame first. This will cause the headers to |
| 252 // be queued up and processed after the first frame is processed. |
| 253 frames.push_back(frame2); |
| 254 session_.OnPacket(IPEndPoint(), IPEndPoint(), header, frames); |
| 255 |
| 256 // Process the first frame, and un-cork the buffered headers. |
| 257 frames[0] = frame1; |
| 258 session_.OnPacket(IPEndPoint(), IPEndPoint(), header, frames); |
| 259 |
| 260 // Ensure that the streams actually close and we don't DCHECK. |
| 261 session_.ConnectionClose(QUIC_CONNECTION_TIMED_OUT, true); |
| 262 } |
| 263 |
222 TEST_F(QuicSessionTest, SendGoAway) { | 264 TEST_F(QuicSessionTest, SendGoAway) { |
223 // After sending a GoAway, ensure new incoming streams cannot be created and | 265 // After sending a GoAway, ensure new incoming streams cannot be created and |
224 // result in a RST being sent. | 266 // result in a RST being sent. |
225 EXPECT_CALL(*connection_, | 267 EXPECT_CALL(*connection_, |
226 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); | 268 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); |
227 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); | 269 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); |
228 EXPECT_TRUE(session_.goaway_sent()); | 270 EXPECT_TRUE(session_.goaway_sent()); |
229 | 271 |
230 EXPECT_CALL(*connection_, SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY)); | 272 EXPECT_CALL(*connection_, SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY)); |
231 EXPECT_FALSE(session_.GetIncomingReliableStream(3u)); | 273 EXPECT_FALSE(session_.GetIncomingReliableStream(3u)); |
232 } | 274 } |
233 | 275 |
234 TEST_F(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) { | 276 TEST_F(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) { |
235 EXPECT_EQ(kDefaultInitialTimeoutSecs, | 277 EXPECT_EQ(kDefaultInitialTimeoutSecs, |
236 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); | 278 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); |
237 CryptoHandshakeMessage msg; | 279 CryptoHandshakeMessage msg; |
238 session_.crypto_stream_.OnHandshakeMessage(msg); | 280 session_.crypto_stream_.OnHandshakeMessage(msg); |
239 EXPECT_EQ(kDefaultTimeoutSecs, | 281 EXPECT_EQ(kDefaultTimeoutSecs, |
240 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); | 282 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); |
241 } | 283 } |
242 | 284 |
243 } // namespace | 285 } // namespace |
244 } // namespace test | 286 } // namespace test |
245 } // namespace net | 287 } // namespace net |
OLD | NEW |