Chromium Code Reviews| 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 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 | 29 |
| 30 // Returns parameters associated with the delay of the HTTP stream job. | 30 // Returns parameters associated with the delay of the HTTP stream job. |
| 31 std::unique_ptr<base::Value> NetLogHttpStreamJobDelayCallback( | 31 std::unique_ptr<base::Value> NetLogHttpStreamJobDelayCallback( |
| 32 base::TimeDelta delay, | 32 base::TimeDelta delay, |
| 33 NetLogCaptureMode /* capture_mode */) { | 33 NetLogCaptureMode /* capture_mode */) { |
| 34 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 34 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 35 dict->SetInteger("resume_after_ms", static_cast<int>(delay.InMilliseconds())); | 35 dict->SetInteger("resume_after_ms", static_cast<int>(delay.InMilliseconds())); |
| 36 return std::move(dict); | 36 return std::move(dict); |
| 37 } | 37 } |
| 38 | 38 |
| 39 std::unique_ptr<base::Value> NetLogJobControllerCallback( | |
| 40 const GURL* url, | |
| 41 bool is_preconnect, | |
| 42 NetLogCaptureMode /* capture_mode */) { | |
| 43 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
|
eroman
2017/01/26 23:37:00
[optional] style: MakeUnique
xunjieli
2017/01/27 14:35:30
Done.
| |
| 44 dict->SetString("url", url->possibly_invalid_spec()); | |
| 45 dict->SetBoolean("is_preconnect", is_preconnect); | |
| 46 return std::move(dict); | |
| 47 } | |
| 48 | |
| 39 HttpStreamFactoryImpl::JobController::JobController( | 49 HttpStreamFactoryImpl::JobController::JobController( |
| 40 HttpStreamFactoryImpl* factory, | 50 HttpStreamFactoryImpl* factory, |
| 41 HttpStreamRequest::Delegate* delegate, | 51 HttpStreamRequest::Delegate* delegate, |
| 42 HttpNetworkSession* session, | 52 HttpNetworkSession* session, |
| 43 JobFactory* job_factory) | 53 JobFactory* job_factory, |
| 54 const HttpRequestInfo& request_info, | |
| 55 bool is_preconnect) | |
| 44 : factory_(factory), | 56 : factory_(factory), |
| 45 session_(session), | 57 session_(session), |
| 46 job_factory_(job_factory), | 58 job_factory_(job_factory), |
| 47 request_(nullptr), | 59 request_(nullptr), |
| 48 delegate_(delegate), | 60 delegate_(delegate), |
| 49 is_preconnect_(false), | 61 is_preconnect_(is_preconnect), |
| 50 alternative_job_failed_(false), | 62 alternative_job_failed_(false), |
| 51 job_bound_(false), | 63 job_bound_(false), |
| 52 main_job_is_blocked_(false), | 64 main_job_is_blocked_(false), |
| 53 bound_job_(nullptr), | 65 bound_job_(nullptr), |
| 54 can_start_alternative_proxy_job_(false), | 66 can_start_alternative_proxy_job_(false), |
| 55 privacy_mode_(PRIVACY_MODE_DISABLED), | 67 privacy_mode_(PRIVACY_MODE_DISABLED), |
| 68 net_log_( | |
| 69 NetLogWithSource::Make(session->net_log(), | |
| 70 NetLogSourceType::HTTP_STREAM_JOB_CONTROLLER)), | |
| 56 ptr_factory_(this) { | 71 ptr_factory_(this) { |
| 57 DCHECK(factory); | 72 DCHECK(factory); |
| 73 net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER, | |
| 74 base::Bind(&NetLogJobControllerCallback, | |
| 75 &request_info.url, /*is_preconnect=*/false)); | |
|
Zhongyi Shi
2017/01/27 00:50:32
Why this is always set to false?
xunjieli
2017/01/27 14:35:30
Ah, sorry about that. Done.
| |
| 58 } | 76 } |
| 59 | 77 |
| 60 HttpStreamFactoryImpl::JobController::~JobController() { | 78 HttpStreamFactoryImpl::JobController::~JobController() { |
| 61 main_job_.reset(); | 79 main_job_.reset(); |
| 62 alternative_job_.reset(); | 80 alternative_job_.reset(); |
| 63 bound_job_ = nullptr; | 81 bound_job_ = nullptr; |
| 82 net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER); | |
| 64 } | 83 } |
| 65 | 84 |
| 66 bool HttpStreamFactoryImpl::JobController::for_websockets() { | 85 bool HttpStreamFactoryImpl::JobController::for_websockets() { |
| 67 return factory_->for_websockets_; | 86 return factory_->for_websockets_; |
| 68 } | 87 } |
| 69 | 88 |
| 70 HttpStreamFactoryImpl::Request* HttpStreamFactoryImpl::JobController::Start( | 89 HttpStreamFactoryImpl::Request* HttpStreamFactoryImpl::JobController::Start( |
| 71 const HttpRequestInfo& request_info, | 90 const HttpRequestInfo& request_info, |
| 72 HttpStreamRequest::Delegate* delegate, | 91 HttpStreamRequest::Delegate* delegate, |
| 73 WebSocketHandshakeStreamBase::CreateHelper* | 92 WebSocketHandshakeStreamBase::CreateHelper* |
| 74 websocket_handshake_stream_create_helper, | 93 websocket_handshake_stream_create_helper, |
| 75 const NetLogWithSource& net_log, | 94 const NetLogWithSource& source_net_log, |
| 76 HttpStreamRequest::StreamType stream_type, | 95 HttpStreamRequest::StreamType stream_type, |
| 77 RequestPriority priority, | 96 RequestPriority priority, |
| 78 const SSLConfig& server_ssl_config, | 97 const SSLConfig& server_ssl_config, |
| 79 const SSLConfig& proxy_ssl_config) { | 98 const SSLConfig& proxy_ssl_config) { |
| 80 DCHECK(factory_); | 99 DCHECK(factory_); |
| 81 DCHECK(!request_); | 100 DCHECK(!request_); |
| 82 | 101 |
| 83 privacy_mode_ = request_info.privacy_mode; | 102 privacy_mode_ = request_info.privacy_mode; |
| 84 | 103 |
| 85 request_ = new Request(request_info.url, this, delegate, | 104 request_ = new Request(request_info.url, this, delegate, |
| 86 websocket_handshake_stream_create_helper, net_log, | 105 websocket_handshake_stream_create_helper, |
| 87 stream_type); | 106 source_net_log, stream_type); |
| 107 // Associates |net_log_| with |source_net_log|. | |
| 108 source_net_log.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, | |
| 109 net_log_.source().ToEventParametersCallback()); | |
| 110 net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, | |
| 111 source_net_log.source().ToEventParametersCallback()); | |
| 88 | 112 |
| 89 CreateJobs(request_info, priority, server_ssl_config, proxy_ssl_config, | 113 CreateJobs(request_info, priority, server_ssl_config, proxy_ssl_config, |
| 90 delegate, stream_type, net_log); | 114 delegate, stream_type); |
| 91 | 115 |
| 92 return request_; | 116 return request_; |
| 93 } | 117 } |
| 94 | 118 |
| 95 void HttpStreamFactoryImpl::JobController::Preconnect( | 119 void HttpStreamFactoryImpl::JobController::Preconnect( |
| 96 int num_streams, | 120 int num_streams, |
| 97 const HttpRequestInfo& request_info, | 121 const HttpRequestInfo& request_info, |
| 98 const SSLConfig& server_ssl_config, | 122 const SSLConfig& server_ssl_config, |
| 99 const SSLConfig& proxy_ssl_config) { | 123 const SSLConfig& proxy_ssl_config) { |
| 100 DCHECK(!main_job_); | 124 DCHECK(!main_job_); |
| 101 DCHECK(!alternative_job_); | 125 DCHECK(!alternative_job_); |
| 126 DCHECK(is_preconnect_); | |
| 102 | 127 |
| 103 privacy_mode_ = request_info.privacy_mode; | 128 privacy_mode_ = request_info.privacy_mode; |
| 104 | 129 |
| 105 is_preconnect_ = true; | |
| 106 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | 130 HostPortPair destination(HostPortPair::FromURL(request_info.url)); |
| 107 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | 131 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); |
| 108 | 132 |
| 109 const AlternativeService alternative_service = GetAlternativeServiceFor( | 133 const AlternativeService alternative_service = GetAlternativeServiceFor( |
| 110 request_info, nullptr, HttpStreamRequest::HTTP_STREAM); | 134 request_info, nullptr, HttpStreamRequest::HTTP_STREAM); |
| 111 | 135 |
| 112 if (alternative_service.protocol != kProtoUnknown) { | 136 if (alternative_service.protocol != kProtoUnknown) { |
| 113 if (session_->params().quic_disable_preconnect_if_0rtt && | 137 if (session_->params().quic_disable_preconnect_if_0rtt && |
| 114 alternative_service.protocol == kProtoQUIC && | 138 alternative_service.protocol == kProtoQUIC && |
| 115 session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( | 139 session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 DCHECK(!is_preconnect_); | 456 DCHECK(!is_preconnect_); |
| 433 | 457 |
| 434 bool is_job_orphaned = IsJobOrphaned(job); | 458 bool is_job_orphaned = IsJobOrphaned(job); |
| 435 | 459 |
| 436 // Cache these values in case the job gets deleted. | 460 // Cache these values in case the job gets deleted. |
| 437 const SSLConfig used_ssl_config = job->server_ssl_config(); | 461 const SSLConfig used_ssl_config = job->server_ssl_config(); |
| 438 const ProxyInfo used_proxy_info = job->proxy_info(); | 462 const ProxyInfo used_proxy_info = job->proxy_info(); |
| 439 const bool was_alpn_negotiated = job->was_alpn_negotiated(); | 463 const bool was_alpn_negotiated = job->was_alpn_negotiated(); |
| 440 const NextProto negotiated_protocol = job->negotiated_protocol(); | 464 const NextProto negotiated_protocol = job->negotiated_protocol(); |
| 441 const bool using_spdy = job->using_spdy(); | 465 const bool using_spdy = job->using_spdy(); |
| 442 const NetLogWithSource net_log = job->net_log(); | |
| 443 | 466 |
| 444 // Cache this so we can still use it if the JobController is deleted. | 467 // Cache this so we can still use it if the JobController is deleted. |
| 445 HttpStreamFactoryImpl* factory = factory_; | 468 HttpStreamFactoryImpl* factory = factory_; |
| 446 | 469 |
| 447 // Notify |request_|. | 470 // Notify |request_|. |
| 448 if (!is_preconnect_ && !is_job_orphaned) { | 471 if (!is_preconnect_ && !is_job_orphaned) { |
| 449 if (job->job_type() == MAIN && alternative_job_failed_) | 472 if (job->job_type() == MAIN && alternative_job_failed_) |
| 450 ReportBrokenAlternativeService(); | 473 ReportBrokenAlternativeService(); |
| 451 | 474 |
| 452 DCHECK(request_); | 475 DCHECK(request_); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 476 DCHECK(stream); | 499 DCHECK(stream); |
| 477 delegate_->OnStreamReady(used_ssl_config, used_proxy_info, | 500 delegate_->OnStreamReady(used_ssl_config, used_proxy_info, |
| 478 stream.release()); | 501 stream.release()); |
| 479 } | 502 } |
| 480 } | 503 } |
| 481 | 504 |
| 482 // Notify |factory_|. |request_| and |bounded_job_| might be deleted already. | 505 // Notify |factory_|. |request_| and |bounded_job_| might be deleted already. |
| 483 if (spdy_session && spdy_session->IsAvailable()) { | 506 if (spdy_session && spdy_session->IsAvailable()) { |
| 484 factory->OnNewSpdySessionReady(spdy_session, direct, used_ssl_config, | 507 factory->OnNewSpdySessionReady(spdy_session, direct, used_ssl_config, |
| 485 used_proxy_info, was_alpn_negotiated, | 508 used_proxy_info, was_alpn_negotiated, |
| 486 negotiated_protocol, using_spdy, net_log); | 509 negotiated_protocol, using_spdy); |
| 487 } | 510 } |
| 488 if (is_job_orphaned) { | 511 if (is_job_orphaned) { |
| 489 OnOrphanedJobComplete(job); | 512 OnOrphanedJobComplete(job); |
| 490 } | 513 } |
| 491 } | 514 } |
| 492 | 515 |
| 493 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) { | 516 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) { |
| 494 DCHECK_EQ(main_job_.get(), job); | 517 DCHECK_EQ(main_job_.get(), job); |
| 495 main_job_.reset(); | 518 main_job_.reset(); |
| 496 factory_->OnPreconnectsCompleteInternal(); | 519 factory_->OnPreconnectsCompleteInternal(); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 DCHECK(base::ContainsKey(request_set, request_)); | 637 DCHECK(base::ContainsKey(request_set, request_)); |
| 615 request_set.erase(request_); | 638 request_set.erase(request_); |
| 616 if (request_set.empty()) | 639 if (request_set.empty()) |
| 617 spdy_session_request_map.erase(*spdy_session_key); | 640 spdy_session_request_map.erase(*spdy_session_key); |
| 618 request_->ResetSpdySessionKey(); | 641 request_->ResetSpdySessionKey(); |
| 619 } | 642 } |
| 620 } | 643 } |
| 621 | 644 |
| 622 const NetLogWithSource* HttpStreamFactoryImpl::JobController::GetNetLog( | 645 const NetLogWithSource* HttpStreamFactoryImpl::JobController::GetNetLog( |
| 623 Job* job) const { | 646 Job* job) const { |
| 624 if (is_preconnect_ || (job_bound_ && bound_job_ != job)) | 647 return &net_log_; |
|
Zhongyi Shi
2017/01/27 00:50:32
nit: you might want o move the implementation of t
xunjieli
2017/01/27 14:35:30
Done.
xunjieli
2017/01/27 15:01:34
Hmm.. actually this is a virtual function so I can
| |
| 625 return nullptr; | |
| 626 DCHECK(request_); | |
| 627 return &request_->net_log(); | |
| 628 } | 648 } |
| 629 | 649 |
| 630 void HttpStreamFactoryImpl::JobController::MaybeSetWaitTimeForMainJob( | 650 void HttpStreamFactoryImpl::JobController::MaybeSetWaitTimeForMainJob( |
| 631 const base::TimeDelta& delay) { | 651 const base::TimeDelta& delay) { |
| 632 if (main_job_is_blocked_) | 652 if (main_job_is_blocked_) |
| 633 main_job_wait_time_ = delay; | 653 main_job_wait_time_ = delay; |
| 634 } | 654 } |
| 635 | 655 |
| 636 bool HttpStreamFactoryImpl::JobController::HasPendingMainJob() const { | 656 bool HttpStreamFactoryImpl::JobController::HasPendingMainJob() const { |
| 637 return main_job_.get() != nullptr; | 657 return main_job_.get() != nullptr; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 655 DCHECK(request_); | 675 DCHECK(request_); |
| 656 return request_->websocket_handshake_stream_create_helper(); | 676 return request_->websocket_handshake_stream_create_helper(); |
| 657 } | 677 } |
| 658 | 678 |
| 659 void HttpStreamFactoryImpl::JobController::CreateJobs( | 679 void HttpStreamFactoryImpl::JobController::CreateJobs( |
| 660 const HttpRequestInfo& request_info, | 680 const HttpRequestInfo& request_info, |
| 661 RequestPriority priority, | 681 RequestPriority priority, |
| 662 const SSLConfig& server_ssl_config, | 682 const SSLConfig& server_ssl_config, |
| 663 const SSLConfig& proxy_ssl_config, | 683 const SSLConfig& proxy_ssl_config, |
| 664 HttpStreamRequest::Delegate* delegate, | 684 HttpStreamRequest::Delegate* delegate, |
| 665 HttpStreamRequest::StreamType stream_type, | 685 HttpStreamRequest::StreamType stream_type) { |
| 666 const NetLogWithSource& net_log) { | |
| 667 DCHECK(!main_job_); | 686 DCHECK(!main_job_); |
| 668 DCHECK(!alternative_job_); | 687 DCHECK(!alternative_job_); |
| 669 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | 688 HostPortPair destination(HostPortPair::FromURL(request_info.url)); |
| 670 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | 689 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); |
| 671 | 690 |
| 672 main_job_.reset(job_factory_->CreateJob( | 691 main_job_.reset(job_factory_->CreateJob( |
| 673 this, MAIN, session_, request_info, priority, server_ssl_config, | 692 this, MAIN, session_, request_info, priority, server_ssl_config, |
| 674 proxy_ssl_config, destination, origin_url, net_log.net_log())); | 693 proxy_ssl_config, destination, origin_url, net_log_.net_log())); |
| 675 AttachJob(main_job_.get()); | 694 AttachJob(main_job_.get()); |
| 676 | 695 |
| 677 // Create an alternative job if alternative service is set up for this domain. | 696 // Create an alternative job if alternative service is set up for this domain. |
| 678 const AlternativeService alternative_service = | 697 const AlternativeService alternative_service = |
| 679 GetAlternativeServiceFor(request_info, delegate, stream_type); | 698 GetAlternativeServiceFor(request_info, delegate, stream_type); |
| 680 | 699 |
| 681 if (alternative_service.protocol != kProtoUnknown) { | 700 if (alternative_service.protocol != kProtoUnknown) { |
| 682 // Never share connection with other jobs for FTP requests. | 701 // Never share connection with other jobs for FTP requests. |
| 683 DVLOG(1) << "Selected alternative service (host: " | 702 DVLOG(1) << "Selected alternative service (host: " |
| 684 << alternative_service.host_port_pair().host() | 703 << alternative_service.host_port_pair().host() |
| 685 << " port: " << alternative_service.host_port_pair().port() << ")"; | 704 << " port: " << alternative_service.host_port_pair().port() << ")"; |
| 686 | 705 |
| 687 DCHECK(!request_info.url.SchemeIs(url::kFtpScheme)); | 706 DCHECK(!request_info.url.SchemeIs(url::kFtpScheme)); |
| 688 HostPortPair alternative_destination(alternative_service.host_port_pair()); | 707 HostPortPair alternative_destination(alternative_service.host_port_pair()); |
| 689 ignore_result( | 708 ignore_result( |
| 690 ApplyHostMappingRules(request_info.url, &alternative_destination)); | 709 ApplyHostMappingRules(request_info.url, &alternative_destination)); |
| 691 | 710 |
| 692 alternative_job_.reset(job_factory_->CreateJob( | 711 alternative_job_.reset(job_factory_->CreateJob( |
| 693 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config, | 712 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config, |
| 694 proxy_ssl_config, alternative_destination, origin_url, | 713 proxy_ssl_config, alternative_destination, origin_url, |
| 695 alternative_service, net_log.net_log())); | 714 alternative_service, net_log_.net_log())); |
| 696 AttachJob(alternative_job_.get()); | 715 AttachJob(alternative_job_.get()); |
| 697 | 716 |
| 698 main_job_is_blocked_ = true; | 717 main_job_is_blocked_ = true; |
| 699 alternative_job_->Start(request_->stream_type()); | 718 alternative_job_->Start(request_->stream_type()); |
| 700 } else { | 719 } else { |
| 701 can_start_alternative_proxy_job_ = true; | 720 can_start_alternative_proxy_job_ = true; |
| 702 } | 721 } |
| 703 // Even if |alternative_job| has already finished, it will not have notified | 722 // Even if |alternative_job| has already finished, it will not have notified |
| 704 // the request yet, since we defer that to the next iteration of the | 723 // the request yet, since we defer that to the next iteration of the |
| 705 // MessageLoop, so starting |main_job_| is always safe. | 724 // MessageLoop, so starting |main_job_| is always safe. |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1119 return; | 1138 return; |
| 1120 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); | 1139 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); |
| 1121 alternative_job_->Start(request_->stream_type()); | 1140 alternative_job_->Start(request_->stream_type()); |
| 1122 } | 1141 } |
| 1123 | 1142 |
| 1124 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { | 1143 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { |
| 1125 return !request_ || (job_bound_ && bound_job_ != job); | 1144 return !request_ || (job_bound_ && bound_job_ != job); |
| 1126 } | 1145 } |
| 1127 | 1146 |
| 1128 } // namespace net | 1147 } // namespace net |
| OLD | NEW |