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 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_stream_factory.h" 6 7 #include "base/run_loop.h" 8 #include "base/strings/string_util.h" 9 #include "net/cert/cert_verifier.h" 10 #include "net/dns/mock_host_resolver.h" 11 #include "net/http/http_response_headers.h" 12 #include "net/http/http_response_info.h" 13 #include "net/http/http_util.h" 14 #include "net/quic/crypto/quic_decrypter.h" 15 #include "net/quic/crypto/quic_encrypter.h" 16 #include "net/quic/quic_http_stream.h" 17 #include "net/quic/test_tools/mock_clock.h" 18 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" 19 #include "net/quic/test_tools/mock_random.h" 20 #include "net/quic/test_tools/quic_test_utils.h" 21 #include "net/socket/socket_test_util.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 namespace net { 25 namespace test { 26 27 class QuicStreamFactoryTest : public ::testing::Test { 28 protected: 29 QuicStreamFactoryTest() 30 : clock_(new MockClock()), 31 factory_(&host_resolver_, &socket_factory_, 32 &crypto_client_stream_factory_, 33 &random_generator_, clock_), 34 host_port_proxy_pair_(HostPortPair("www.google.com", 443), 35 ProxyServer::Direct()), 36 is_https_(false), 37 cert_verifier_(CertVerifier::CreateDefault()) { 38 } 39 40 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket( 41 QuicPacketSequenceNumber num, 42 QuicStreamId stream_id) { 43 QuicPacketHeader header; 44 header.public_header.guid = 0xDEADBEEF; 45 header.public_header.reset_flag = false; 46 header.public_header.version_flag = true; 47 header.packet_sequence_number = num; 48 header.entropy_flag = false; 49 header.fec_flag = false; 50 header.fec_group = 0; 51 52 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR); 53 return scoped_ptr<QuicEncryptedPacket>( 54 ConstructPacket(header, QuicFrame(&rst))); 55 } 56 57 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( 58 QuicPacketSequenceNumber largest_received, 59 QuicPacketSequenceNumber least_unacked) { 60 QuicPacketHeader header; 61 header.public_header.guid = 0xDEADBEEF; 62 header.public_header.reset_flag = false; 63 header.public_header.version_flag = false; 64 header.packet_sequence_number = 2; 65 header.entropy_flag = false; 66 header.fec_flag = false; 67 header.fec_group = 0; 68 69 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked); 70 QuicCongestionFeedbackFrame feedback; 71 feedback.type = kTCP; 72 feedback.tcp.accumulated_number_of_lost_packets = 0; 73 feedback.tcp.receive_window = 16000; 74 75 QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false); 76 QuicFrames frames; 77 frames.push_back(QuicFrame(&ack)); 78 frames.push_back(QuicFrame(&feedback)); 79 scoped_ptr<QuicPacket> packet( 80 framer.BuildUnsizedDataPacket(header, frames).packet); 81 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket( 82 ENCRYPTION_NONE, header.packet_sequence_number, *packet)); 83 } 84 85 // Returns a newly created packet to send congestion feedback data. 86 scoped_ptr<QuicEncryptedPacket> ConstructFeedbackPacket( 87 QuicPacketSequenceNumber sequence_number) { 88 QuicPacketHeader header; 89 header.public_header.guid = 0xDEADBEEF; 90 header.public_header.reset_flag = false; 91 header.public_header.version_flag = false; 92 header.packet_sequence_number = sequence_number; 93 header.entropy_flag = false; 94 header.fec_flag = false; 95 header.fec_group = 0; 96 97 QuicCongestionFeedbackFrame frame; 98 frame.type = kTCP; 99 frame.tcp.accumulated_number_of_lost_packets = 0; 100 frame.tcp.receive_window = 16000; 101 102 return scoped_ptr<QuicEncryptedPacket>( 103 ConstructPacket(header, QuicFrame(&frame))); 104 } 105 106 scoped_ptr<QuicEncryptedPacket> ConstructPacket( 107 const QuicPacketHeader& header, 108 const QuicFrame& frame) { 109 QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false); 110 QuicFrames frames; 111 frames.push_back(frame); 112 scoped_ptr<QuicPacket> packet( 113 framer.BuildUnsizedDataPacket(header, frames).packet); 114 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket( 115 ENCRYPTION_NONE, header.packet_sequence_number, *packet)); 116 } 117 118 MockHostResolver host_resolver_; 119 DeterministicMockClientSocketFactory socket_factory_; 120 MockCryptoClientStreamFactory crypto_client_stream_factory_; 121 MockRandom random_generator_; 122 MockClock* clock_; // Owned by factory_. 123 QuicStreamFactory factory_; 124 HostPortProxyPair host_port_proxy_pair_; 125 bool is_https_; 126 scoped_ptr<CertVerifier> cert_verifier_; 127 BoundNetLog net_log_; 128 TestCompletionCallback callback_; 129 }; 130 131 TEST_F(QuicStreamFactoryTest, CreateIfSessionExists) { 132 EXPECT_EQ(NULL, factory_.CreateIfSessionExists(host_port_proxy_pair_, 133 net_log_).get()); 134 } 135 136 TEST_F(QuicStreamFactoryTest, Create) { 137 MockRead reads[] = { 138 MockRead(ASYNC, OK, 0) // EOF 139 }; 140 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0); 141 socket_factory_.AddSocketDataProvider(&socket_data); 142 socket_data.StopAfter(1); 143 144 QuicStreamRequest request(&factory_); 145 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_, 146 cert_verifier_.get(), net_log_, 147 callback_.callback())); 148 149 EXPECT_EQ(OK, callback_.WaitForResult()); 150 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); 151 EXPECT_TRUE(stream.get()); 152 153 // Will reset stream 3. 154 stream = factory_.CreateIfSessionExists(host_port_proxy_pair_, net_log_); 155 EXPECT_TRUE(stream.get()); 156 157 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result 158 // in streams on different sessions. 159 QuicStreamRequest request2(&factory_); 160 EXPECT_EQ(OK, request2.Request(host_port_proxy_pair_, is_https_, 161 cert_verifier_.get(), net_log_, 162 callback_.callback())); 163 stream = request2.ReleaseStream(); // Will reset stream 5. 164 stream.reset(); // Will reset stream 7. 165 166 EXPECT_TRUE(socket_data.at_read_eof()); 167 EXPECT_TRUE(socket_data.at_write_eof()); 168 } 169 170 TEST_F(QuicStreamFactoryTest, MaxOpenStream) { 171 MockRead reads[] = { 172 MockRead(ASYNC, OK, 0) // EOF 173 }; 174 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0); 175 socket_factory_.AddSocketDataProvider(&socket_data); 176 socket_data.StopAfter(1); 177 178 HttpRequestInfo request_info; 179 std::vector<QuicHttpStream*> streams; 180 // The MockCryptoClientStream sets max_open_streams to be 181 // 2 * kDefaultMaxStreamsPerConnection. 182 for (size_t i = 0; i < 2 * kDefaultMaxStreamsPerConnection; i++) { 183 QuicStreamRequest request(&factory_); 184 int rv = request.Request(host_port_proxy_pair_, is_https_, 185 cert_verifier_.get(), net_log_, 186 callback_.callback()); 187 if (i == 0) { 188 EXPECT_EQ(ERR_IO_PENDING, rv); 189 EXPECT_EQ(OK, callback_.WaitForResult()); 190 } else { 191 EXPECT_EQ(OK, rv); 192 } 193 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); 194 EXPECT_TRUE(stream); 195 EXPECT_EQ(OK, stream->InitializeStream( 196 &request_info, DEFAULT_PRIORITY, net_log_, CompletionCallback())); 197 streams.push_back(stream.release()); 198 } 199 200 QuicStreamRequest request(&factory_); 201 EXPECT_EQ(OK, request.Request(host_port_proxy_pair_, is_https_, 202 cert_verifier_.get(), net_log_, 203 CompletionCallback())); 204 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); 205 EXPECT_TRUE(stream); 206 EXPECT_EQ(ERR_IO_PENDING, stream->InitializeStream( 207 &request_info, DEFAULT_PRIORITY, net_log_, callback_.callback())); 208 209 // Close the first stream. 210 streams.front()->Close(false); 211 212 ASSERT_TRUE(callback_.have_result()); 213 214 EXPECT_EQ(OK, callback_.WaitForResult()); 215 216 EXPECT_TRUE(socket_data.at_read_eof()); 217 EXPECT_TRUE(socket_data.at_write_eof()); 218 STLDeleteElements(&streams); 219 } 220 221 TEST_F(QuicStreamFactoryTest, CreateError) { 222 DeterministicSocketData socket_data(NULL, 0, NULL, 0); 223 socket_factory_.AddSocketDataProvider(&socket_data); 224 225 host_resolver_.rules()->AddSimulatedFailure("www.google.com"); 226 227 QuicStreamRequest request(&factory_); 228 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_, 229 cert_verifier_.get(), net_log_, 230 callback_.callback())); 231 232 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult()); 233 234 EXPECT_TRUE(socket_data.at_read_eof()); 235 EXPECT_TRUE(socket_data.at_write_eof()); 236 } 237 238 TEST_F(QuicStreamFactoryTest, CancelCreate) { 239 MockRead reads[] = { 240 MockRead(ASYNC, OK, 0) // EOF 241 }; 242 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0); 243 socket_factory_.AddSocketDataProvider(&socket_data); 244 { 245 QuicStreamRequest request(&factory_); 246 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_, 247 cert_verifier_.get(), net_log_, 248 callback_.callback())); 249 } 250 251 socket_data.StopAfter(1); 252 base::RunLoop run_loop; 253 run_loop.RunUntilIdle(); 254 255 scoped_ptr<QuicHttpStream> stream( 256 factory_.CreateIfSessionExists(host_port_proxy_pair_, net_log_)); 257 EXPECT_TRUE(stream.get()); 258 stream.reset(); 259 260 EXPECT_TRUE(socket_data.at_read_eof()); 261 EXPECT_TRUE(socket_data.at_write_eof()); 262 } 263 264 TEST_F(QuicStreamFactoryTest, CloseAllSessions) { 265 MockRead reads[] = { 266 MockRead(ASYNC, 0, 0) // EOF 267 }; 268 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0); 269 socket_factory_.AddSocketDataProvider(&socket_data); 270 socket_data.StopAfter(1); 271 272 MockRead reads2[] = { 273 MockRead(ASYNC, 0, 0) // EOF 274 }; 275 DeterministicSocketData socket_data2(reads2, arraysize(reads2), NULL, 0); 276 socket_factory_.AddSocketDataProvider(&socket_data2); 277 socket_data2.StopAfter(1); 278 279 QuicStreamRequest request(&factory_); 280 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_, 281 cert_verifier_.get(), net_log_, 282 callback_.callback())); 283 284 EXPECT_EQ(OK, callback_.WaitForResult()); 285 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); 286 HttpRequestInfo request_info; 287 EXPECT_EQ(OK, stream->InitializeStream(&request_info, 288 DEFAULT_PRIORITY, 289 net_log_, CompletionCallback())); 290 291 // Close the session and verify that stream saw the error. 292 factory_.CloseAllSessions(ERR_INTERNET_DISCONNECTED); 293 EXPECT_EQ(ERR_INTERNET_DISCONNECTED, 294 stream->ReadResponseHeaders(callback_.callback())); 295 296 // Now attempting to request a stream to the same origin should create 297 // a new session. 298 299 QuicStreamRequest request2(&factory_); 300 EXPECT_EQ(ERR_IO_PENDING, request2.Request(host_port_proxy_pair_, is_https_, 301 cert_verifier_.get(), net_log_, 302 callback_.callback())); 303 304 EXPECT_EQ(OK, callback_.WaitForResult()); 305 stream = request2.ReleaseStream(); 306 stream.reset(); // Will reset stream 3. 307 308 EXPECT_TRUE(socket_data.at_read_eof()); 309 EXPECT_TRUE(socket_data.at_write_eof()); 310 EXPECT_TRUE(socket_data2.at_read_eof()); 311 EXPECT_TRUE(socket_data2.at_write_eof()); 312 } 313 314 TEST_F(QuicStreamFactoryTest, OnIPAddressChanged) { 315 MockRead reads[] = { 316 MockRead(ASYNC, 0, 0) // EOF 317 }; 318 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0); 319 socket_factory_.AddSocketDataProvider(&socket_data); 320 socket_data.StopAfter(1); 321 322 MockRead reads2[] = { 323 MockRead(ASYNC, 0, 0) // EOF 324 }; 325 DeterministicSocketData socket_data2(reads2, arraysize(reads2), NULL, 0); 326 socket_factory_.AddSocketDataProvider(&socket_data2); 327 socket_data2.StopAfter(1); 328 329 QuicStreamRequest request(&factory_); 330 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_, 331 cert_verifier_.get(), net_log_, 332 callback_.callback())); 333 334 EXPECT_EQ(OK, callback_.WaitForResult()); 335 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); 336 HttpRequestInfo request_info; 337 EXPECT_EQ(OK, stream->InitializeStream(&request_info, 338 DEFAULT_PRIORITY, 339 net_log_, CompletionCallback())); 340 341 // Change the IP address and verify that stream saw the error. 342 factory_.OnIPAddressChanged(); 343 EXPECT_EQ(ERR_NETWORK_CHANGED, 344 stream->ReadResponseHeaders(callback_.callback())); 345 346 // Now attempting to request a stream to the same origin should create 347 // a new session. 348 349 QuicStreamRequest request2(&factory_); 350 EXPECT_EQ(ERR_IO_PENDING, request2.Request(host_port_proxy_pair_, is_https_, 351 cert_verifier_.get(), net_log_, 352 callback_.callback())); 353 354 EXPECT_EQ(OK, callback_.WaitForResult()); 355 stream = request2.ReleaseStream(); 356 stream.reset(); // Will reset stream 3. 357 358 EXPECT_TRUE(socket_data.at_read_eof()); 359 EXPECT_TRUE(socket_data.at_write_eof()); 360 EXPECT_TRUE(socket_data2.at_read_eof()); 361 EXPECT_TRUE(socket_data2.at_write_eof()); 362 } 363 364 } // namespace test 365 } // namespace net 366