| 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 22 matching lines...) Expand all Loading... |
| 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 HttpStreamFactoryImpl::JobController::JobController( | 39 HttpStreamFactoryImpl::JobController::JobController( |
| 40 HttpStreamFactoryImpl* factory, | 40 HttpStreamFactoryImpl* factory, |
| 41 HttpStreamRequest::Delegate* delegate, | 41 HttpStreamRequest::Delegate* delegate, |
| 42 HttpNetworkSession* session, | 42 HttpNetworkSession* session, |
| 43 JobFactory* job_factory) | 43 JobFactory* job_factory, |
| 44 bool is_preconnect) |
| 44 : factory_(factory), | 45 : factory_(factory), |
| 45 session_(session), | 46 session_(session), |
| 46 job_factory_(job_factory), | 47 job_factory_(job_factory), |
| 47 request_(nullptr), | 48 request_(nullptr), |
| 48 delegate_(delegate), | 49 delegate_(delegate), |
| 49 is_preconnect_(false), | 50 is_preconnect_(is_preconnect), |
| 50 alternative_job_failed_(false), | 51 alternative_job_failed_(false), |
| 51 job_bound_(false), | 52 job_bound_(false), |
| 52 main_job_is_blocked_(false), | 53 main_job_is_blocked_(false), |
| 53 bound_job_(nullptr), | 54 bound_job_(nullptr), |
| 54 can_start_alternative_proxy_job_(false), | 55 can_start_alternative_proxy_job_(false), |
| 55 privacy_mode_(PRIVACY_MODE_DISABLED), | 56 privacy_mode_(PRIVACY_MODE_DISABLED), |
| 57 net_log_( |
| 58 NetLogWithSource::Make(session->net_log(), |
| 59 NetLogSourceType::HTTP_STREAM_JOB_CONTROLLER)), |
| 56 ptr_factory_(this) { | 60 ptr_factory_(this) { |
| 57 DCHECK(factory); | 61 DCHECK(factory); |
| 62 net_log_.BeginEvent( |
| 63 NetLogEventType::HTTP_STREAM_JOB_CONTROLLER, |
| 64 net::NetLog::BoolCallback("is_preconnect", is_preconnect)); |
| 58 } | 65 } |
| 59 | 66 |
| 60 HttpStreamFactoryImpl::JobController::~JobController() { | 67 HttpStreamFactoryImpl::JobController::~JobController() { |
| 61 main_job_.reset(); | 68 main_job_.reset(); |
| 62 alternative_job_.reset(); | 69 alternative_job_.reset(); |
| 63 bound_job_ = nullptr; | 70 bound_job_ = nullptr; |
| 71 net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER); |
| 64 } | 72 } |
| 65 | 73 |
| 66 bool HttpStreamFactoryImpl::JobController::for_websockets() { | 74 bool HttpStreamFactoryImpl::JobController::for_websockets() { |
| 67 return factory_->for_websockets_; | 75 return factory_->for_websockets_; |
| 68 } | 76 } |
| 69 | 77 |
| 78 void HttpStreamFactoryImpl::JobController::AssociateWithNetLogSource( |
| 79 const NetLogWithSource& source_net_log) { |
| 80 source_net_log.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, |
| 81 net_log_.source().ToEventParametersCallback()); |
| 82 net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, |
| 83 source_net_log.source().ToEventParametersCallback()); |
| 84 } |
| 85 |
| 70 HttpStreamFactoryImpl::Request* HttpStreamFactoryImpl::JobController::Start( | 86 HttpStreamFactoryImpl::Request* HttpStreamFactoryImpl::JobController::Start( |
| 71 const HttpRequestInfo& request_info, | 87 const HttpRequestInfo& request_info, |
| 72 HttpStreamRequest::Delegate* delegate, | 88 HttpStreamRequest::Delegate* delegate, |
| 73 WebSocketHandshakeStreamBase::CreateHelper* | 89 WebSocketHandshakeStreamBase::CreateHelper* |
| 74 websocket_handshake_stream_create_helper, | 90 websocket_handshake_stream_create_helper, |
| 75 const NetLogWithSource& net_log, | 91 const NetLogWithSource& source_net_log, |
| 76 HttpStreamRequest::StreamType stream_type, | 92 HttpStreamRequest::StreamType stream_type, |
| 77 RequestPriority priority, | 93 RequestPriority priority, |
| 78 const SSLConfig& server_ssl_config, | 94 const SSLConfig& server_ssl_config, |
| 79 const SSLConfig& proxy_ssl_config) { | 95 const SSLConfig& proxy_ssl_config) { |
| 80 DCHECK(factory_); | 96 DCHECK(factory_); |
| 81 DCHECK(!request_); | 97 DCHECK(!request_); |
| 82 | 98 |
| 83 privacy_mode_ = request_info.privacy_mode; | 99 privacy_mode_ = request_info.privacy_mode; |
| 84 | 100 |
| 85 request_ = new Request(request_info.url, this, delegate, | 101 request_ = new Request(request_info.url, this, delegate, |
| 86 websocket_handshake_stream_create_helper, net_log, | 102 websocket_handshake_stream_create_helper, |
| 87 stream_type); | 103 source_net_log, stream_type); |
| 88 | 104 |
| 89 CreateJobs(request_info, priority, server_ssl_config, proxy_ssl_config, | 105 CreateJobs(request_info, priority, server_ssl_config, proxy_ssl_config, |
| 90 delegate, stream_type, net_log); | 106 delegate, stream_type); |
| 91 | 107 |
| 92 return request_; | 108 return request_; |
| 93 } | 109 } |
| 94 | 110 |
| 95 void HttpStreamFactoryImpl::JobController::Preconnect( | 111 void HttpStreamFactoryImpl::JobController::Preconnect( |
| 96 int num_streams, | 112 int num_streams, |
| 97 const HttpRequestInfo& request_info, | 113 const HttpRequestInfo& request_info, |
| 98 const SSLConfig& server_ssl_config, | 114 const SSLConfig& server_ssl_config, |
| 99 const SSLConfig& proxy_ssl_config) { | 115 const SSLConfig& proxy_ssl_config) { |
| 100 DCHECK(!main_job_); | 116 DCHECK(!main_job_); |
| 101 DCHECK(!alternative_job_); | 117 DCHECK(!alternative_job_); |
| 118 DCHECK(is_preconnect_); |
| 102 | 119 |
| 103 privacy_mode_ = request_info.privacy_mode; | 120 privacy_mode_ = request_info.privacy_mode; |
| 104 | 121 |
| 105 is_preconnect_ = true; | |
| 106 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | 122 HostPortPair destination(HostPortPair::FromURL(request_info.url)); |
| 107 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | 123 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); |
| 108 | 124 |
| 109 const AlternativeService alternative_service = GetAlternativeServiceFor( | 125 const AlternativeService alternative_service = GetAlternativeServiceFor( |
| 110 request_info, nullptr, HttpStreamRequest::HTTP_STREAM); | 126 request_info, nullptr, HttpStreamRequest::HTTP_STREAM); |
| 111 | 127 |
| 112 if (alternative_service.protocol != kProtoUnknown) { | 128 if (alternative_service.protocol != kProtoUnknown) { |
| 113 if (session_->params().quic_disable_preconnect_if_0rtt && | 129 if (session_->params().quic_disable_preconnect_if_0rtt && |
| 114 alternative_service.protocol == kProtoQUIC && | 130 alternative_service.protocol == kProtoQUIC && |
| 115 session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( | 131 session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 DCHECK(!is_preconnect_); | 448 DCHECK(!is_preconnect_); |
| 433 | 449 |
| 434 bool is_job_orphaned = IsJobOrphaned(job); | 450 bool is_job_orphaned = IsJobOrphaned(job); |
| 435 | 451 |
| 436 // Cache these values in case the job gets deleted. | 452 // Cache these values in case the job gets deleted. |
| 437 const SSLConfig used_ssl_config = job->server_ssl_config(); | 453 const SSLConfig used_ssl_config = job->server_ssl_config(); |
| 438 const ProxyInfo used_proxy_info = job->proxy_info(); | 454 const ProxyInfo used_proxy_info = job->proxy_info(); |
| 439 const bool was_alpn_negotiated = job->was_alpn_negotiated(); | 455 const bool was_alpn_negotiated = job->was_alpn_negotiated(); |
| 440 const NextProto negotiated_protocol = job->negotiated_protocol(); | 456 const NextProto negotiated_protocol = job->negotiated_protocol(); |
| 441 const bool using_spdy = job->using_spdy(); | 457 const bool using_spdy = job->using_spdy(); |
| 442 const NetLogWithSource net_log = job->net_log(); | |
| 443 | 458 |
| 444 // Cache this so we can still use it if the JobController is deleted. | 459 // Cache this so we can still use it if the JobController is deleted. |
| 445 HttpStreamFactoryImpl* factory = factory_; | 460 HttpStreamFactoryImpl* factory = factory_; |
| 446 | 461 |
| 447 // Notify |request_|. | 462 // Notify |request_|. |
| 448 if (!is_preconnect_ && !is_job_orphaned) { | 463 if (!is_preconnect_ && !is_job_orphaned) { |
| 449 if (job->job_type() == MAIN && alternative_job_failed_) | 464 if (job->job_type() == MAIN && alternative_job_failed_) |
| 450 ReportBrokenAlternativeService(); | 465 ReportBrokenAlternativeService(); |
| 451 | 466 |
| 452 DCHECK(request_); | 467 DCHECK(request_); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 476 DCHECK(stream); | 491 DCHECK(stream); |
| 477 delegate_->OnStreamReady(used_ssl_config, used_proxy_info, | 492 delegate_->OnStreamReady(used_ssl_config, used_proxy_info, |
| 478 stream.release()); | 493 stream.release()); |
| 479 } | 494 } |
| 480 } | 495 } |
| 481 | 496 |
| 482 // Notify |factory_|. |request_| and |bounded_job_| might be deleted already. | 497 // Notify |factory_|. |request_| and |bounded_job_| might be deleted already. |
| 483 if (spdy_session && spdy_session->IsAvailable()) { | 498 if (spdy_session && spdy_session->IsAvailable()) { |
| 484 factory->OnNewSpdySessionReady(spdy_session, direct, used_ssl_config, | 499 factory->OnNewSpdySessionReady(spdy_session, direct, used_ssl_config, |
| 485 used_proxy_info, was_alpn_negotiated, | 500 used_proxy_info, was_alpn_negotiated, |
| 486 negotiated_protocol, using_spdy, net_log); | 501 negotiated_protocol, using_spdy); |
| 487 } | 502 } |
| 488 if (is_job_orphaned) { | 503 if (is_job_orphaned) { |
| 489 OnOrphanedJobComplete(job); | 504 OnOrphanedJobComplete(job); |
| 490 } | 505 } |
| 491 } | 506 } |
| 492 | 507 |
| 493 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) { | 508 void HttpStreamFactoryImpl::JobController::OnPreconnectsComplete(Job* job) { |
| 494 DCHECK_EQ(main_job_.get(), job); | 509 DCHECK_EQ(main_job_.get(), job); |
| 495 main_job_.reset(); | 510 main_job_.reset(); |
| 496 factory_->OnPreconnectsCompleteInternal(); | 511 factory_->OnPreconnectsCompleteInternal(); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 DCHECK(base::ContainsKey(request_set, request_)); | 629 DCHECK(base::ContainsKey(request_set, request_)); |
| 615 request_set.erase(request_); | 630 request_set.erase(request_); |
| 616 if (request_set.empty()) | 631 if (request_set.empty()) |
| 617 spdy_session_request_map.erase(*spdy_session_key); | 632 spdy_session_request_map.erase(*spdy_session_key); |
| 618 request_->ResetSpdySessionKey(); | 633 request_->ResetSpdySessionKey(); |
| 619 } | 634 } |
| 620 } | 635 } |
| 621 | 636 |
| 622 const NetLogWithSource* HttpStreamFactoryImpl::JobController::GetNetLog( | 637 const NetLogWithSource* HttpStreamFactoryImpl::JobController::GetNetLog( |
| 623 Job* job) const { | 638 Job* job) const { |
| 624 if (is_preconnect_ || (job_bound_ && bound_job_ != job)) | 639 return &net_log_; |
| 625 return nullptr; | |
| 626 DCHECK(request_); | |
| 627 return &request_->net_log(); | |
| 628 } | 640 } |
| 629 | 641 |
| 630 void HttpStreamFactoryImpl::JobController::MaybeSetWaitTimeForMainJob( | 642 void HttpStreamFactoryImpl::JobController::MaybeSetWaitTimeForMainJob( |
| 631 const base::TimeDelta& delay) { | 643 const base::TimeDelta& delay) { |
| 632 if (main_job_is_blocked_) | 644 if (main_job_is_blocked_) |
| 633 main_job_wait_time_ = delay; | 645 main_job_wait_time_ = delay; |
| 634 } | 646 } |
| 635 | 647 |
| 636 bool HttpStreamFactoryImpl::JobController::HasPendingMainJob() const { | 648 bool HttpStreamFactoryImpl::JobController::HasPendingMainJob() const { |
| 637 return main_job_.get() != nullptr; | 649 return main_job_.get() != nullptr; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 655 DCHECK(request_); | 667 DCHECK(request_); |
| 656 return request_->websocket_handshake_stream_create_helper(); | 668 return request_->websocket_handshake_stream_create_helper(); |
| 657 } | 669 } |
| 658 | 670 |
| 659 void HttpStreamFactoryImpl::JobController::CreateJobs( | 671 void HttpStreamFactoryImpl::JobController::CreateJobs( |
| 660 const HttpRequestInfo& request_info, | 672 const HttpRequestInfo& request_info, |
| 661 RequestPriority priority, | 673 RequestPriority priority, |
| 662 const SSLConfig& server_ssl_config, | 674 const SSLConfig& server_ssl_config, |
| 663 const SSLConfig& proxy_ssl_config, | 675 const SSLConfig& proxy_ssl_config, |
| 664 HttpStreamRequest::Delegate* delegate, | 676 HttpStreamRequest::Delegate* delegate, |
| 665 HttpStreamRequest::StreamType stream_type, | 677 HttpStreamRequest::StreamType stream_type) { |
| 666 const NetLogWithSource& net_log) { | |
| 667 DCHECK(!main_job_); | 678 DCHECK(!main_job_); |
| 668 DCHECK(!alternative_job_); | 679 DCHECK(!alternative_job_); |
| 669 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | 680 HostPortPair destination(HostPortPair::FromURL(request_info.url)); |
| 670 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | 681 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); |
| 671 | 682 |
| 672 main_job_.reset(job_factory_->CreateJob( | 683 main_job_.reset(job_factory_->CreateJob( |
| 673 this, MAIN, session_, request_info, priority, server_ssl_config, | 684 this, MAIN, session_, request_info, priority, server_ssl_config, |
| 674 proxy_ssl_config, destination, origin_url, net_log.net_log())); | 685 proxy_ssl_config, destination, origin_url, net_log_.net_log())); |
| 675 AttachJob(main_job_.get()); | 686 AttachJob(main_job_.get()); |
| 676 | 687 |
| 677 // Create an alternative job if alternative service is set up for this domain. | 688 // Create an alternative job if alternative service is set up for this domain. |
| 678 const AlternativeService alternative_service = | 689 const AlternativeService alternative_service = |
| 679 GetAlternativeServiceFor(request_info, delegate, stream_type); | 690 GetAlternativeServiceFor(request_info, delegate, stream_type); |
| 680 | 691 |
| 681 if (alternative_service.protocol != kProtoUnknown) { | 692 if (alternative_service.protocol != kProtoUnknown) { |
| 682 // Never share connection with other jobs for FTP requests. | 693 // Never share connection with other jobs for FTP requests. |
| 683 DVLOG(1) << "Selected alternative service (host: " | 694 DVLOG(1) << "Selected alternative service (host: " |
| 684 << alternative_service.host_port_pair().host() | 695 << alternative_service.host_port_pair().host() |
| 685 << " port: " << alternative_service.host_port_pair().port() << ")"; | 696 << " port: " << alternative_service.host_port_pair().port() << ")"; |
| 686 | 697 |
| 687 DCHECK(!request_info.url.SchemeIs(url::kFtpScheme)); | 698 DCHECK(!request_info.url.SchemeIs(url::kFtpScheme)); |
| 688 HostPortPair alternative_destination(alternative_service.host_port_pair()); | 699 HostPortPair alternative_destination(alternative_service.host_port_pair()); |
| 689 ignore_result( | 700 ignore_result( |
| 690 ApplyHostMappingRules(request_info.url, &alternative_destination)); | 701 ApplyHostMappingRules(request_info.url, &alternative_destination)); |
| 691 | 702 |
| 692 alternative_job_.reset(job_factory_->CreateJob( | 703 alternative_job_.reset(job_factory_->CreateJob( |
| 693 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config, | 704 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config, |
| 694 proxy_ssl_config, alternative_destination, origin_url, | 705 proxy_ssl_config, alternative_destination, origin_url, |
| 695 alternative_service, net_log.net_log())); | 706 alternative_service, net_log_.net_log())); |
| 696 AttachJob(alternative_job_.get()); | 707 AttachJob(alternative_job_.get()); |
| 697 | 708 |
| 698 main_job_is_blocked_ = true; | 709 main_job_is_blocked_ = true; |
| 699 alternative_job_->Start(request_->stream_type()); | 710 alternative_job_->Start(request_->stream_type()); |
| 700 } else { | 711 } else { |
| 701 can_start_alternative_proxy_job_ = true; | 712 can_start_alternative_proxy_job_ = true; |
| 702 } | 713 } |
| 703 // Even if |alternative_job| has already finished, it will not have notified | 714 // 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 | 715 // the request yet, since we defer that to the next iteration of the |
| 705 // MessageLoop, so starting |main_job_| is always safe. | 716 // MessageLoop, so starting |main_job_| is always safe. |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 return; | 1130 return; |
| 1120 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); | 1131 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); |
| 1121 alternative_job_->Start(request_->stream_type()); | 1132 alternative_job_->Start(request_->stream_type()); |
| 1122 } | 1133 } |
| 1123 | 1134 |
| 1124 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { | 1135 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { |
| 1125 return !request_ || (job_bound_ && bound_job_ != job); | 1136 return !request_ || (job_bound_ && bound_job_ != job); |
| 1126 } | 1137 } |
| 1127 | 1138 |
| 1128 } // namespace net | 1139 } // namespace net |
| OLD | NEW |