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/tools/quic/quic_simple_server_stream.h" | 5 #include "net/tools/quic/quic_simple_server_stream.h" |
6 | 6 |
7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/string_piece.h" | 8 #include "base/strings/string_piece.h" |
9 #include "net/quic/quic_connection.h" | 9 #include "net/quic/quic_connection.h" |
10 #include "net/quic/quic_flags.h" | 10 #include "net/quic/quic_flags.h" |
11 #include "net/quic/quic_protocol.h" | 11 #include "net/quic/quic_protocol.h" |
12 #include "net/quic/quic_utils.h" | 12 #include "net/quic/quic_utils.h" |
13 #include "net/quic/spdy_utils.h" | 13 #include "net/quic/spdy_utils.h" |
| 14 #include "net/quic/test_tools/crypto_test_utils.h" |
14 #include "net/quic/test_tools/quic_test_utils.h" | 15 #include "net/quic/test_tools/quic_test_utils.h" |
15 #include "net/quic/test_tools/reliable_quic_stream_peer.h" | 16 #include "net/quic/test_tools/reliable_quic_stream_peer.h" |
16 #include "net/test/gtest_util.h" | 17 #include "net/test/gtest_util.h" |
17 #include "net/tools/epoll_server/epoll_server.h" | 18 #include "net/tools/epoll_server/epoll_server.h" |
18 #include "net/tools/quic/quic_in_memory_cache.h" | 19 #include "net/tools/quic/quic_in_memory_cache.h" |
| 20 #include "net/tools/quic/quic_simple_server_session.h" |
19 #include "net/tools/quic/spdy_balsa_utils.h" | 21 #include "net/tools/quic/spdy_balsa_utils.h" |
20 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h" | 22 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h" |
21 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 25 #include "url/gurl.h" |
23 | 26 |
24 using base::StringPiece; | 27 using base::StringPiece; |
25 using net::test::MockConnection; | 28 using net::test::MockConnection; |
26 using net::test::MockConnectionHelper; | 29 using net::test::MockConnectionHelper; |
27 using net::test::MockQuicSpdySession; | 30 using net::test::MockQuicSpdySession; |
28 using net::test::ReliableQuicStreamPeer; | 31 using net::test::ReliableQuicStreamPeer; |
29 using net::test::SupportedVersions; | 32 using net::test::SupportedVersions; |
30 using net::test::kInitialSessionFlowControlWindowForTest; | 33 using net::test::kInitialSessionFlowControlWindowForTest; |
31 using net::test::kInitialStreamFlowControlWindowForTest; | 34 using net::test::kInitialStreamFlowControlWindowForTest; |
32 using std::string; | 35 using std::string; |
33 using testing::_; | 36 using testing::_; |
34 using testing::AnyNumber; | 37 using testing::AnyNumber; |
35 using testing::Invoke; | 38 using testing::Invoke; |
36 using testing::InvokeArgument; | 39 using testing::InvokeArgument; |
37 using testing::InSequence; | 40 using testing::InSequence; |
38 using testing::Return; | 41 using testing::Return; |
39 using testing::StrictMock; | 42 using testing::StrictMock; |
40 using testing::WithArgs; | 43 using testing::WithArgs; |
41 | 44 |
42 namespace net { | 45 namespace net { |
43 namespace tools { | 46 namespace tools { |
44 namespace test { | 47 namespace test { |
45 | 48 |
46 class QuicSimpleServerStreamPeer : public QuicSimpleServerStream { | 49 class QuicSimpleServerStreamPeer : public QuicSimpleServerStream { |
47 public: | 50 public: |
48 QuicSimpleServerStreamPeer(QuicStreamId stream_id, QuicSpdySession* session) | 51 QuicSimpleServerStreamPeer(QuicStreamId stream_id, QuicSpdySession* session) |
49 : QuicSimpleServerStream(stream_id, session) {} | 52 : QuicSimpleServerStream(stream_id, session) {} |
50 | 53 |
| 54 ~QuicSimpleServerStreamPeer() override{}; |
| 55 |
51 using QuicSimpleServerStream::SendResponse; | 56 using QuicSimpleServerStream::SendResponse; |
52 using QuicSimpleServerStream::SendErrorResponse; | 57 using QuicSimpleServerStream::SendErrorResponse; |
53 | 58 |
54 SpdyHeaderBlock* mutable_headers() { return &request_headers_; } | 59 SpdyHeaderBlock* mutable_headers() { return &request_headers_; } |
55 | 60 |
56 static void SendResponse(QuicSimpleServerStream* stream) { | 61 static void SendResponse(QuicSimpleServerStream* stream) { |
57 stream->SendResponse(); | 62 stream->SendResponse(); |
58 } | 63 } |
59 | 64 |
60 static void SendErrorResponse(QuicSimpleServerStream* stream) { | 65 static void SendErrorResponse(QuicSimpleServerStream* stream) { |
61 stream->SendErrorResponse(); | 66 stream->SendErrorResponse(); |
62 } | 67 } |
63 | 68 |
64 static const string& body(QuicSimpleServerStream* stream) { | 69 static const string& body(QuicSimpleServerStream* stream) { |
65 return stream->body_; | 70 return stream->body_; |
66 } | 71 } |
67 | 72 |
68 static int content_length(QuicSimpleServerStream* stream) { | 73 static int content_length(QuicSimpleServerStream* stream) { |
69 return stream->content_length_; | 74 return stream->content_length_; |
70 } | 75 } |
71 | 76 |
72 static SpdyHeaderBlock& headers(QuicSimpleServerStream* stream) { | 77 static SpdyHeaderBlock& headers(QuicSimpleServerStream* stream) { |
73 return stream->request_headers_; | 78 return stream->request_headers_; |
74 } | 79 } |
75 }; | 80 }; |
76 | 81 |
| 82 class MockQuicSimpleServerSession : public QuicSimpleServerSession { |
| 83 public: |
| 84 const size_t kMaxStreamsForTest = 100; |
| 85 |
| 86 explicit MockQuicSimpleServerSession(QuicConnection* connection, |
| 87 MockQuicServerSessionVisitor* owner, |
| 88 QuicCryptoServerConfig* crypto_config) |
| 89 : QuicSimpleServerSession(::net::test::DefaultQuicConfig(), |
| 90 connection, |
| 91 owner, |
| 92 crypto_config) { |
| 93 set_max_open_streams(kMaxStreamsForTest); |
| 94 ON_CALL(*this, WritevData(_, _, _, _, _, _)) |
| 95 .WillByDefault(testing::Return(QuicConsumedData(0, false))); |
| 96 } |
| 97 |
| 98 ~MockQuicSimpleServerSession() override {} |
| 99 |
| 100 MOCK_METHOD2(OnConnectionClosed, void(QuicErrorCode error, bool from_peer)); |
| 101 MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id)); |
| 102 MOCK_METHOD6(WritevData, |
| 103 QuicConsumedData(QuicStreamId id, |
| 104 QuicIOVector data, |
| 105 QuicStreamOffset offset, |
| 106 bool fin, |
| 107 FecProtection fec_protection, |
| 108 QuicAckListenerInterface*)); |
| 109 MOCK_METHOD2(OnStreamHeaders, |
| 110 void(QuicStreamId stream_id, StringPiece headers_data)); |
| 111 MOCK_METHOD2(OnStreamHeadersPriority, |
| 112 void(QuicStreamId stream_id, SpdyPriority priority)); |
| 113 MOCK_METHOD3(OnStreamHeadersComplete, |
| 114 void(QuicStreamId stream_id, bool fin, size_t frame_len)); |
| 115 MOCK_METHOD5(WriteHeaders, |
| 116 size_t(QuicStreamId id, |
| 117 const SpdyHeaderBlock& headers, |
| 118 bool fin, |
| 119 SpdyPriority priority, |
| 120 QuicAckListenerInterface* ack_notifier_delegate)); |
| 121 MOCK_METHOD3(SendRstStream, |
| 122 void(QuicStreamId stream_id, |
| 123 QuicRstStreamErrorCode error, |
| 124 QuicStreamOffset bytes_written)); |
| 125 MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta)); |
| 126 MOCK_METHOD4(PromisePushResources, |
| 127 void(const string&, |
| 128 const list<QuicInMemoryCache::ServerPushInfo>&, |
| 129 QuicStreamId, |
| 130 const SpdyHeaderBlock&)); |
| 131 |
| 132 using QuicSession::ActivateStream; |
| 133 |
| 134 private: |
| 135 DISALLOW_COPY_AND_ASSIGN(MockQuicSimpleServerSession); |
| 136 }; |
| 137 |
77 namespace { | 138 namespace { |
78 | 139 |
79 class QuicSimpleServerStreamTest | 140 class QuicSimpleServerStreamTest |
80 : public ::testing::TestWithParam<QuicVersion> { | 141 : public ::testing::TestWithParam<QuicVersion> { |
81 public: | 142 public: |
82 QuicSimpleServerStreamTest() | 143 QuicSimpleServerStreamTest() |
83 : connection_( | 144 : connection_( |
84 new StrictMock<MockConnection>(&helper_, | 145 new StrictMock<MockConnection>(&helper_, |
85 Perspective::IS_SERVER, | 146 Perspective::IS_SERVER, |
86 SupportedVersions(GetParam()))), | 147 SupportedVersions(GetParam()))), |
87 session_(connection_), | 148 session_owner_(new StrictMock<MockQuicServerSessionVisitor>()), |
| 149 crypto_config_(new QuicCryptoServerConfig( |
| 150 QuicCryptoServerConfig::TESTING, |
| 151 QuicRandom::GetInstance(), |
| 152 ::net::test::CryptoTestUtils::ProofSourceForTesting())), |
| 153 session_(connection_, session_owner_, crypto_config_.get()), |
88 body_("hello world") { | 154 body_("hello world") { |
89 SpdyHeaderBlock request_headers; | 155 SpdyHeaderBlock request_headers; |
90 request_headers[":host"] = ""; | 156 request_headers[":host"] = ""; |
91 request_headers[":authority"] = "www.google.com"; | 157 request_headers[":authority"] = "www.google.com"; |
92 request_headers[":path"] = "/"; | 158 request_headers[":path"] = "/"; |
93 request_headers[":method"] = "POST"; | 159 request_headers[":method"] = "POST"; |
94 request_headers[":version"] = "HTTP/1.1"; | 160 request_headers[":version"] = "HTTP/1.1"; |
95 request_headers["content-length"] = "11"; | 161 request_headers["content-length"] = "11"; |
96 | 162 |
97 headers_string_ = | 163 headers_string_ = |
(...skipping 21 matching lines...) Expand all Loading... |
119 return QuicSimpleServerStreamPeer::body(stream_); | 185 return QuicSimpleServerStreamPeer::body(stream_); |
120 } | 186 } |
121 | 187 |
122 StringPiece StreamHeadersValue(const string& key) { | 188 StringPiece StreamHeadersValue(const string& key) { |
123 return (*stream_->mutable_headers())[key]; | 189 return (*stream_->mutable_headers())[key]; |
124 } | 190 } |
125 | 191 |
126 SpdyHeaderBlock response_headers_; | 192 SpdyHeaderBlock response_headers_; |
127 MockConnectionHelper helper_; | 193 MockConnectionHelper helper_; |
128 StrictMock<MockConnection>* connection_; | 194 StrictMock<MockConnection>* connection_; |
129 StrictMock<MockQuicSpdySession> session_; | 195 StrictMock<MockQuicServerSessionVisitor>* session_owner_; |
| 196 std::unique_ptr<QuicCryptoServerConfig> crypto_config_; |
| 197 StrictMock<MockQuicSimpleServerSession> session_; |
130 QuicSimpleServerStreamPeer* stream_; // Owned by session_. | 198 QuicSimpleServerStreamPeer* stream_; // Owned by session_. |
131 string headers_string_; | 199 string headers_string_; |
132 string body_; | 200 string body_; |
133 }; | 201 }; |
134 | 202 |
135 INSTANTIATE_TEST_CASE_P(Tests, | 203 INSTANTIATE_TEST_CASE_P(Tests, |
136 QuicSimpleServerStreamTest, | 204 QuicSimpleServerStreamTest, |
137 ::testing::ValuesIn(QuicSupportedVersions())); | 205 ::testing::ValuesIn(QuicSupportedVersions())); |
138 | 206 |
139 TEST_P(QuicSimpleServerStreamTest, TestFraming) { | 207 TEST_P(QuicSimpleServerStreamTest, TestFraming) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) | 354 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
287 .Times(1) | 355 .Times(1) |
288 .WillOnce(Return(QuicConsumedData(body.length(), true))); | 356 .WillOnce(Return(QuicConsumedData(body.length(), true))); |
289 | 357 |
290 QuicSimpleServerStreamPeer::SendResponse(stream_); | 358 QuicSimpleServerStreamPeer::SendResponse(stream_); |
291 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); | 359 EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_)); |
292 EXPECT_TRUE(stream_->reading_stopped()); | 360 EXPECT_TRUE(stream_->reading_stopped()); |
293 EXPECT_TRUE(stream_->write_side_closed()); | 361 EXPECT_TRUE(stream_->write_side_closed()); |
294 } | 362 } |
295 | 363 |
| 364 TEST_P(QuicSimpleServerStreamTest, SendReponseWithPushResources) { |
| 365 // Tests that if a reponse has push resources to be send, SendResponse() will |
| 366 // call PromisePushResources() to handle these resources. |
| 367 |
| 368 // Add a request and response with valid headers into cache. |
| 369 string host = "www.google.com"; |
| 370 string request_path = "/foo"; |
| 371 string body = "Yummm"; |
| 372 SpdyHeaderBlock response_headers; |
| 373 string url = host + "/bar"; |
| 374 QuicInMemoryCache::ServerPushInfo push_info( |
| 375 GURL(url), response_headers, kDefaultPriority, "Push body"); |
| 376 list<QuicInMemoryCache::ServerPushInfo> push_resources; |
| 377 push_resources.push_back(push_info); |
| 378 QuicInMemoryCache::GetInstance()->AddSimpleResponseWithServerPushResources( |
| 379 host, request_path, 200, body, push_resources); |
| 380 |
| 381 SpdyHeaderBlock* request_headers = stream_->mutable_headers(); |
| 382 (*request_headers)[":path"] = request_path; |
| 383 (*request_headers)[":authority"] = host; |
| 384 (*request_headers)[":version"] = "HTTP/1.1"; |
| 385 (*request_headers)[":method"] = "GET"; |
| 386 |
| 387 stream_->set_fin_received(true); |
| 388 InSequence s; |
| 389 EXPECT_CALL(session_, |
| 390 PromisePushResources(host + request_path, _, |
| 391 ::net::test::kClientDataStreamId1, |
| 392 *request_headers)); |
| 393 EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr)); |
| 394 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) |
| 395 .Times(1) |
| 396 .WillOnce(Return(QuicConsumedData(body.length(), true))); |
| 397 QuicSimpleServerStreamPeer::SendResponse(stream_); |
| 398 } |
| 399 |
296 TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) { | 400 TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) { |
297 // Calling PushResponse() on a client initialted stream is never supposed to | 401 // Calling PushResponse() on a client initialted stream is never supposed to |
298 // happen. | 402 // happen. |
299 SpdyHeaderBlock headers; | 403 SpdyHeaderBlock headers; |
300 EXPECT_DFATAL(stream_->PushResponse(headers), | 404 EXPECT_DFATAL(stream_->PushResponse(headers), |
301 "Client initiated stream" | 405 "Client initiated stream" |
302 " shouldn't be used as promised stream."); | 406 " shouldn't be used as promised stream."); |
303 } | 407 } |
304 | 408 |
305 TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) { | 409 TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) { |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 StringPiece data(arr, arraysize(arr)); | 593 StringPiece data(arr, arraysize(arr)); |
490 QuicStreamFrame frame(stream_->id(), true, 0, data); | 594 QuicStreamFrame frame(stream_->id(), true, 0, data); |
491 // Verify that we don't crash when we get a invalid headers in stream frame. | 595 // Verify that we don't crash when we get a invalid headers in stream frame. |
492 stream_->OnStreamFrame(frame); | 596 stream_->OnStreamFrame(frame); |
493 } | 597 } |
494 | 598 |
495 } // namespace | 599 } // namespace |
496 } // namespace test | 600 } // namespace test |
497 } // namespace tools | 601 } // namespace tools |
498 } // namespace net | 602 } // namespace net |
OLD | NEW |