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