| OLD | NEW |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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/http/http_stream_factory_impl_job_controller.h" | 5 #include "net/http/http_stream_factory_impl_job_controller.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 366 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 367 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, | 367 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, |
| 368 SSLConfig()); | 368 SSLConfig()); |
| 369 | 369 |
| 370 VerifyBrokenAlternateProtocolMapping(request_info, true); | 370 VerifyBrokenAlternateProtocolMapping(request_info, true); |
| 371 // Reset the request as it's been successfully served. | 371 // Reset the request as it's been successfully served. |
| 372 request_.reset(); | 372 request_.reset(); |
| 373 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 373 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 374 } | 374 } |
| 375 | 375 |
| 376 // Tests that if alt job succeeds and main job is blocked, |request_| completion |
| 377 // will clean up JobController. Regression test for crbug.com/678768. |
| 378 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 379 AltJobSucceedsMainJobBlockedControllerDestroyed) { |
| 380 ProxyConfig proxy_config; |
| 381 proxy_config.set_auto_detect(true); |
| 382 MockAsyncProxyResolverFactory* proxy_resolver_factory = |
| 383 new MockAsyncProxyResolverFactory(false); |
| 384 session_deps_.proxy_service.reset( |
| 385 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
| 386 base::WrapUnique(proxy_resolver_factory), nullptr)); |
| 387 Initialize(false); |
| 388 |
| 389 HttpRequestInfo request_info; |
| 390 request_info.method = "GET"; |
| 391 request_info.url = GURL("https://www.google.com"); |
| 392 |
| 393 url::SchemeHostPort server(request_info.url); |
| 394 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 395 SetAlternativeService(request_info, alternative_service); |
| 396 request_.reset( |
| 397 job_controller_->Start(request_info, &request_delegate_, nullptr, |
| 398 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| 399 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| 400 EXPECT_TRUE(job_controller_->main_job()); |
| 401 EXPECT_TRUE(job_controller_->alternative_job()); |
| 402 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| 403 |
| 404 // |alternative_job| succeeds and should report status to Request. |
| 405 HttpStream* http_stream = |
| 406 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| 407 job_factory_.alternative_job()->SetStream(http_stream); |
| 408 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| 409 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 410 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig(), |
| 411 ProxyInfo()); |
| 412 |
| 413 EXPECT_TRUE(job_controller_->main_job()); |
| 414 EXPECT_TRUE(job_controller_->alternative_job()); |
| 415 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| 416 |
| 417 // Invoke OnRequestComplete() which should delete |job_controller_| from |
| 418 // |factory_|. |
| 419 request_.reset(); |
| 420 VerifyBrokenAlternateProtocolMapping(request_info, false); |
| 421 // This fails without the fix for crbug.com/678768. |
| 422 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 423 } |
| 424 |
| 425 // Tests that if an orphaned job completes after |request_| is gone, |
| 426 // JobController will be cleaned up. |
| 427 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 428 OrphanedJobCompletesControllerDestroyed) { |
| 429 ProxyConfig proxy_config; |
| 430 proxy_config.set_auto_detect(true); |
| 431 MockAsyncProxyResolverFactory* proxy_resolver_factory = |
| 432 new MockAsyncProxyResolverFactory(false); |
| 433 session_deps_.proxy_service.reset( |
| 434 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
| 435 base::WrapUnique(proxy_resolver_factory), nullptr)); |
| 436 Initialize(false); |
| 437 |
| 438 HttpRequestInfo request_info; |
| 439 request_info.method = "GET"; |
| 440 request_info.url = GURL("https://www.google.com"); |
| 441 |
| 442 url::SchemeHostPort server(request_info.url); |
| 443 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 444 SetAlternativeService(request_info, alternative_service); |
| 445 // Hack to use different URL for the main job to help differentiate the proxy |
| 446 // requests. |
| 447 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); |
| 448 request_.reset( |
| 449 job_controller_->Start(request_info, &request_delegate_, nullptr, |
| 450 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| 451 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| 452 EXPECT_TRUE(job_controller_->main_job()); |
| 453 EXPECT_TRUE(job_controller_->alternative_job()); |
| 454 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| 455 |
| 456 // Complete main job now. |
| 457 MockAsyncProxyResolver resolver; |
| 458 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( |
| 459 net::OK, &resolver); |
| 460 int main_job_request_id = |
| 461 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; |
| 462 |
| 463 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( |
| 464 "result1:80"); |
| 465 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); |
| 466 |
| 467 HttpStream* http_stream = |
| 468 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| 469 job_factory_.main_job()->SetStream(http_stream); |
| 470 |
| 471 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| 472 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 473 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig(), |
| 474 ProxyInfo()); |
| 475 |
| 476 // Invoke OnRequestComplete() which should not delete |job_controller_| from |
| 477 // |factory_| because alt job is yet to finish. |
| 478 request_.reset(); |
| 479 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 480 EXPECT_FALSE(job_controller_->main_job()); |
| 481 EXPECT_TRUE(job_controller_->alternative_job()); |
| 482 |
| 483 // Make |alternative_job| succeed. |
| 484 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); |
| 485 resolver.pending_jobs()[0]->CompleteNow(net::OK); |
| 486 HttpStream* http_stream2 = |
| 487 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| 488 job_factory_.alternative_job()->SetStream(http_stream2); |
| 489 // This should not call request_delegate_::OnStreamReady. |
| 490 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig(), |
| 491 ProxyInfo()); |
| 492 // Make sure that controller does not leak. |
| 493 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 494 } |
| 495 |
| 376 TEST_F(HttpStreamFactoryImplJobControllerTest, | 496 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 377 AltJobSucceedsAfterMainJobFailed) { | 497 AltJobSucceedsAfterMainJobFailed) { |
| 378 ProxyConfig proxy_config; | 498 ProxyConfig proxy_config; |
| 379 proxy_config.set_auto_detect(true); | 499 proxy_config.set_auto_detect(true); |
| 380 // Use asynchronous proxy resolver. | 500 // Use asynchronous proxy resolver. |
| 381 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 501 MockAsyncProxyResolverFactory* proxy_resolver_factory = |
| 382 new MockAsyncProxyResolverFactory(false); | 502 new MockAsyncProxyResolverFactory(false); |
| 383 session_deps_.proxy_service.reset( | 503 session_deps_.proxy_service.reset( |
| 384 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | 504 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
| 385 base::WrapUnique(proxy_resolver_factory), nullptr)); | 505 base::WrapUnique(proxy_resolver_factory), nullptr)); |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 // Reset the request as it's been successfully served. | 1067 // Reset the request as it's been successfully served. |
| 948 request_.reset(); | 1068 request_.reset(); |
| 949 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1069 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 950 | 1070 |
| 951 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", | 1071 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", |
| 952 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, | 1072 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, |
| 953 1); | 1073 1); |
| 954 } | 1074 } |
| 955 | 1075 |
| 956 } // namespace net | 1076 } // namespace net |
| OLD | NEW |