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 <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 } | 762 } |
763 | 763 |
764 int HttpStreamFactoryImpl::JobController::DoCreateJobs() { | 764 int HttpStreamFactoryImpl::JobController::DoCreateJobs() { |
765 DCHECK(!main_job_); | 765 DCHECK(!main_job_); |
766 DCHECK(!alternative_job_); | 766 DCHECK(!alternative_job_); |
767 | 767 |
768 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); | 768 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); |
769 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); | 769 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); |
770 | 770 |
771 // Create an alternative job if alternative service is set up for this domain. | 771 // Create an alternative job if alternative service is set up for this domain. |
772 const AlternativeService alternative_service = | 772 alternative_service_ = |
773 GetAlternativeServiceInfoFor(request_info_, delegate_, stream_type_) | 773 GetAlternativeServiceInfoFor(request_info_, delegate_, stream_type_) |
774 .alternative_service(); | 774 .alternative_service(); |
775 | 775 |
776 if (is_preconnect_) { | 776 if (is_preconnect_) { |
777 // Due to how the socket pools handle priorities and idle sockets, only IDLE | 777 // Due to how the socket pools handle priorities and idle sockets, only IDLE |
778 // priority currently makes sense for preconnects. The priority for | 778 // priority currently makes sense for preconnects. The priority for |
779 // preconnects is currently ignored (see RequestSocketsForPool()), but could | 779 // preconnects is currently ignored (see RequestSocketsForPool()), but could |
780 // be used at some point for proxy resolution or something. | 780 // be used at some point for proxy resolution or something. |
781 if (alternative_service.protocol != kProtoUnknown) { | 781 if (alternative_service_.protocol != kProtoUnknown) { |
782 HostPortPair alternative_destination( | 782 HostPortPair alternative_destination( |
783 alternative_service.host_port_pair()); | 783 alternative_service_.host_port_pair()); |
784 ignore_result( | 784 ignore_result( |
785 ApplyHostMappingRules(request_info_.url, &alternative_destination)); | 785 ApplyHostMappingRules(request_info_.url, &alternative_destination)); |
786 main_job_ = job_factory_->CreateAltSvcJob( | 786 main_job_ = job_factory_->CreateAltSvcJob( |
787 this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, | 787 this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, |
788 server_ssl_config_, proxy_ssl_config_, alternative_destination, | 788 server_ssl_config_, proxy_ssl_config_, alternative_destination, |
789 origin_url, alternative_service, enable_ip_based_pooling_, | 789 origin_url, alternative_service_.protocol, enable_ip_based_pooling_, |
790 session_->net_log()); | 790 session_->net_log()); |
791 } else { | 791 } else { |
792 main_job_ = job_factory_->CreateMainJob( | 792 main_job_ = job_factory_->CreateMainJob( |
793 this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, | 793 this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, |
794 server_ssl_config_, proxy_ssl_config_, destination, origin_url, | 794 server_ssl_config_, proxy_ssl_config_, destination, origin_url, |
795 enable_ip_based_pooling_, session_->net_log()); | 795 enable_ip_based_pooling_, session_->net_log()); |
796 } | 796 } |
797 main_job_->Preconnect(num_streams_); | 797 main_job_->Preconnect(num_streams_); |
798 return OK; | 798 return OK; |
799 } | 799 } |
800 main_job_ = job_factory_->CreateMainJob( | 800 main_job_ = job_factory_->CreateMainJob( |
801 this, MAIN, session_, request_info_, priority_, proxy_info_, | 801 this, MAIN, session_, request_info_, priority_, proxy_info_, |
802 server_ssl_config_, proxy_ssl_config_, destination, origin_url, | 802 server_ssl_config_, proxy_ssl_config_, destination, origin_url, |
803 enable_ip_based_pooling_, net_log_.net_log()); | 803 enable_ip_based_pooling_, net_log_.net_log()); |
804 // Alternative Service can only be set for HTTPS requests while Alternative | 804 // Alternative Service can only be set for HTTPS requests while Alternative |
805 // Proxy is set for HTTP requests. | 805 // Proxy is set for HTTP requests. |
806 if (alternative_service.protocol != kProtoUnknown) { | 806 if (alternative_service_.protocol != kProtoUnknown) { |
807 // Never share connection with other jobs for FTP requests. | 807 // Never share connection with other jobs for FTP requests. |
808 DVLOG(1) << "Selected alternative service (host: " | 808 DVLOG(1) << "Selected alternative service (host: " |
809 << alternative_service.host_port_pair().host() | 809 << alternative_service_.host_port_pair().host() |
810 << " port: " << alternative_service.host_port_pair().port() << ")"; | 810 << " port: " << alternative_service_.host_port_pair().port() |
| 811 << ")"; |
811 | 812 |
812 DCHECK(!request_info_.url.SchemeIs(url::kFtpScheme)); | 813 DCHECK(!request_info_.url.SchemeIs(url::kFtpScheme)); |
813 HostPortPair alternative_destination(alternative_service.host_port_pair()); | 814 HostPortPair alternative_destination(alternative_service_.host_port_pair()); |
814 ignore_result( | 815 ignore_result( |
815 ApplyHostMappingRules(request_info_.url, &alternative_destination)); | 816 ApplyHostMappingRules(request_info_.url, &alternative_destination)); |
816 | 817 |
817 alternative_job_ = job_factory_->CreateAltSvcJob( | 818 alternative_job_ = job_factory_->CreateAltSvcJob( |
818 this, ALTERNATIVE, session_, request_info_, priority_, proxy_info_, | 819 this, ALTERNATIVE, session_, request_info_, priority_, proxy_info_, |
819 server_ssl_config_, proxy_ssl_config_, alternative_destination, | 820 server_ssl_config_, proxy_ssl_config_, alternative_destination, |
820 origin_url, alternative_service, enable_ip_based_pooling_, | 821 origin_url, alternative_service_.protocol, enable_ip_based_pooling_, |
821 net_log_.net_log()); | 822 net_log_.net_log()); |
822 | 823 |
823 main_job_is_blocked_ = true; | 824 main_job_is_blocked_ = true; |
824 alternative_job_->Start(request_->stream_type()); | 825 alternative_job_->Start(request_->stream_type()); |
825 } else { | 826 } else { |
826 ProxyServer alternative_proxy_server; | 827 ProxyServer alternative_proxy_server; |
827 if (ShouldCreateAlternativeProxyServerJob(proxy_info_, request_info_.url, | 828 if (ShouldCreateAlternativeProxyServerJob(proxy_info_, request_info_.url, |
828 &alternative_proxy_server)) { | 829 &alternative_proxy_server)) { |
829 DCHECK(!main_job_is_blocked_); | 830 DCHECK(!main_job_is_blocked_); |
830 ProxyInfo alternative_proxy_info; | 831 ProxyInfo alternative_proxy_info; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 NextProto negotiated_protocol, | 939 NextProto negotiated_protocol, |
939 bool using_spdy) { | 940 bool using_spdy) { |
940 if (request_) | 941 if (request_) |
941 request_->Complete(was_alpn_negotiated, negotiated_protocol, using_spdy); | 942 request_->Complete(was_alpn_negotiated, negotiated_protocol, using_spdy); |
942 } | 943 } |
943 | 944 |
944 void HttpStreamFactoryImpl::JobController::OnAlternativeServiceJobFailed( | 945 void HttpStreamFactoryImpl::JobController::OnAlternativeServiceJobFailed( |
945 int net_error) { | 946 int net_error) { |
946 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); | 947 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); |
947 DCHECK_NE(OK, net_error); | 948 DCHECK_NE(OK, net_error); |
948 DCHECK_NE(kProtoUnknown, alternative_job_->alternative_service().protocol); | 949 DCHECK_NE(kProtoUnknown, alternative_service_.protocol); |
949 | 950 |
950 alternative_job_net_error_ = net_error; | 951 alternative_job_net_error_ = net_error; |
951 failed_alternative_service_ = alternative_job_->alternative_service(); | |
952 | 952 |
953 if (IsJobOrphaned(alternative_job_.get())) { | 953 if (IsJobOrphaned(alternative_job_.get())) { |
954 // If |request_| is gone then it must have been successfully served by | 954 // If |request_| is gone then it must have been successfully served by |
955 // |main_job_|. | 955 // |main_job_|. |
956 // If |request_| is bound to a different job, then it is being | 956 // If |request_| is bound to a different job, then it is being |
957 // successfully serverd by the main job. | 957 // successfully serverd by the main job. |
958 ReportBrokenAlternativeService(); | 958 ReportBrokenAlternativeService(); |
959 } | 959 } |
960 } | 960 } |
961 | 961 |
962 void HttpStreamFactoryImpl::JobController::OnAlternativeProxyJobFailed( | 962 void HttpStreamFactoryImpl::JobController::OnAlternativeProxyJobFailed( |
963 int net_error) { | 963 int net_error) { |
964 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); | 964 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); |
965 DCHECK_NE(OK, net_error); | 965 DCHECK_NE(OK, net_error); |
966 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); | 966 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); |
967 | 967 |
968 // Need to mark alt proxy as broken regardless whether the job is bound. | 968 // Need to mark alt proxy as broken regardless whether the job is bound. |
969 ProxyDelegate* proxy_delegate = session_->context().proxy_delegate; | 969 ProxyDelegate* proxy_delegate = session_->context().proxy_delegate; |
970 if (proxy_delegate) { | 970 if (proxy_delegate) { |
971 proxy_delegate->OnAlternativeProxyBroken( | 971 proxy_delegate->OnAlternativeProxyBroken( |
972 alternative_job_->alternative_proxy_server()); | 972 alternative_job_->alternative_proxy_server()); |
973 } | 973 } |
974 } | 974 } |
975 | 975 |
976 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() { | 976 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() { |
977 DCHECK(failed_alternative_service_.protocol != kProtoUnknown); | 977 DCHECK(alternative_service_.protocol != kProtoUnknown); |
978 DCHECK_NE(OK, alternative_job_net_error_); | 978 DCHECK_NE(OK, alternative_job_net_error_); |
979 | 979 |
980 int error_to_report = alternative_job_net_error_; | 980 int error_to_report = alternative_job_net_error_; |
981 alternative_job_net_error_ = OK; | 981 alternative_job_net_error_ = OK; |
982 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AlternateServiceFailed", -error_to_report); | 982 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AlternateServiceFailed", -error_to_report); |
983 | 983 |
984 if (error_to_report == ERR_NETWORK_CHANGED || | 984 if (error_to_report == ERR_NETWORK_CHANGED || |
985 error_to_report == ERR_INTERNET_DISCONNECTED) { | 985 error_to_report == ERR_INTERNET_DISCONNECTED) { |
986 // No need to mark alternative service or proxy as broken. | 986 // No need to mark alternative service or proxy as broken. |
987 return; | 987 return; |
988 } | 988 } |
989 | 989 |
990 HistogramBrokenAlternateProtocolLocation( | 990 HistogramBrokenAlternateProtocolLocation( |
991 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); | 991 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); |
992 session_->http_server_properties()->MarkAlternativeServiceBroken( | 992 session_->http_server_properties()->MarkAlternativeServiceBroken( |
993 failed_alternative_service_); | 993 alternative_service_); |
994 } | 994 } |
995 | 995 |
996 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { | 996 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { |
997 if (!request_ && !main_job_ && !alternative_job_) { | 997 if (!request_ && !main_job_ && !alternative_job_) { |
998 DCHECK(!bound_job_); | 998 DCHECK(!bound_job_); |
999 factory_->OnJobControllerComplete(this); | 999 factory_->OnJobControllerComplete(this); |
1000 } | 1000 } |
1001 } | 1001 } |
1002 | 1002 |
1003 void HttpStreamFactoryImpl::JobController::NotifyRequestFailed(int rv) { | 1003 void HttpStreamFactoryImpl::JobController::NotifyRequestFailed(int rv) { |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 // If ReconsiderProxyAfterError() failed synchronously, it means | 1285 // If ReconsiderProxyAfterError() failed synchronously, it means |
1286 // there was nothing left to fall-back to, so fail the transaction | 1286 // there was nothing left to fall-back to, so fail the transaction |
1287 // with the last connection error we got. | 1287 // with the last connection error we got. |
1288 // TODO(eroman): This is a confusing contract, make it more obvious. | 1288 // TODO(eroman): This is a confusing contract, make it more obvious. |
1289 rv = error; | 1289 rv = error; |
1290 } | 1290 } |
1291 return rv; | 1291 return rv; |
1292 } | 1292 } |
1293 | 1293 |
1294 } // namespace net | 1294 } // namespace net |
OLD | NEW |