OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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.h" | 5 #include "net/http/http_stream_factory_impl_job.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 return dict.Pass(); | 73 return dict.Pass(); |
74 } | 74 } |
75 | 75 |
76 HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, | 76 HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, |
77 HttpNetworkSession* session, | 77 HttpNetworkSession* session, |
78 const HttpRequestInfo& request_info, | 78 const HttpRequestInfo& request_info, |
79 RequestPriority priority, | 79 RequestPriority priority, |
80 const SSLConfig& server_ssl_config, | 80 const SSLConfig& server_ssl_config, |
81 const SSLConfig& proxy_ssl_config, | 81 const SSLConfig& proxy_ssl_config, |
82 NetLog* net_log) | 82 NetLog* net_log) |
| 83 : Job(stream_factory, |
| 84 session, |
| 85 request_info, |
| 86 priority, |
| 87 server_ssl_config, |
| 88 proxy_ssl_config, |
| 89 AlternativeService(), |
| 90 net_log) { |
| 91 } |
| 92 |
| 93 HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, |
| 94 HttpNetworkSession* session, |
| 95 const HttpRequestInfo& request_info, |
| 96 RequestPriority priority, |
| 97 const SSLConfig& server_ssl_config, |
| 98 const SSLConfig& proxy_ssl_config, |
| 99 AlternativeService alternative_service, |
| 100 NetLog* net_log) |
83 : request_(NULL), | 101 : request_(NULL), |
84 request_info_(request_info), | 102 request_info_(request_info), |
85 priority_(priority), | 103 priority_(priority), |
86 server_ssl_config_(server_ssl_config), | 104 server_ssl_config_(server_ssl_config), |
87 proxy_ssl_config_(proxy_ssl_config), | 105 proxy_ssl_config_(proxy_ssl_config), |
88 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP_STREAM_JOB)), | 106 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP_STREAM_JOB)), |
89 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), | 107 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), |
90 connection_(new ClientSocketHandle), | 108 connection_(new ClientSocketHandle), |
91 session_(session), | 109 session_(session), |
92 stream_factory_(stream_factory), | 110 stream_factory_(stream_factory), |
93 next_state_(STATE_NONE), | 111 next_state_(STATE_NONE), |
94 pac_request_(NULL), | 112 pac_request_(NULL), |
| 113 alternative_service_(alternative_service), |
95 blocking_job_(NULL), | 114 blocking_job_(NULL), |
96 waiting_job_(NULL), | 115 waiting_job_(NULL), |
97 using_ssl_(false), | 116 using_ssl_(false), |
98 using_spdy_(false), | 117 using_spdy_(false), |
99 using_quic_(false), | 118 using_quic_(false), |
100 quic_request_(session_->quic_stream_factory()), | 119 quic_request_(session_->quic_stream_factory()), |
101 using_existing_quic_session_(false), | 120 using_existing_quic_session_(false), |
102 spdy_certificate_error_(OK), | 121 spdy_certificate_error_(OK), |
103 establishing_tunnel_(false), | 122 establishing_tunnel_(false), |
104 was_npn_negotiated_(false), | 123 was_npn_negotiated_(false), |
105 protocol_negotiated_(kProtoUnknown), | 124 protocol_negotiated_(kProtoUnknown), |
106 num_streams_(0), | 125 num_streams_(0), |
107 spdy_session_direct_(false), | 126 spdy_session_direct_(false), |
108 job_status_(STATUS_RUNNING), | 127 job_status_(STATUS_RUNNING), |
109 other_job_status_(STATUS_RUNNING), | 128 other_job_status_(STATUS_RUNNING), |
110 ptr_factory_(this) { | 129 ptr_factory_(this) { |
111 DCHECK(stream_factory); | 130 DCHECK(stream_factory); |
112 DCHECK(session); | 131 DCHECK(session); |
| 132 if (IsQuicAlternative()) { |
| 133 DCHECK(session_->params().enable_quic); |
| 134 using_quic_ = true; |
| 135 } |
113 } | 136 } |
114 | 137 |
115 HttpStreamFactoryImpl::Job::~Job() { | 138 HttpStreamFactoryImpl::Job::~Job() { |
116 net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB); | 139 net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_JOB); |
117 | 140 |
118 // When we're in a partially constructed state, waiting for the user to | 141 // When we're in a partially constructed state, waiting for the user to |
119 // provide certificate handling information or authentication, we can't reuse | 142 // provide certificate handling information or authentication, we can't reuse |
120 // this stream at all. | 143 // this stream at all. |
121 if (next_state_ == STATE_WAITING_USER_ACTION) { | 144 if (next_state_ == STATE_WAITING_USER_ACTION) { |
122 connection_->socket()->Disconnect(); | 145 connection_->socket()->Disconnect(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 case STATE_RESOLVE_PROXY_COMPLETE: | 187 case STATE_RESOLVE_PROXY_COMPLETE: |
165 return session_->proxy_service()->GetLoadState(pac_request_); | 188 return session_->proxy_service()->GetLoadState(pac_request_); |
166 case STATE_INIT_CONNECTION_COMPLETE: | 189 case STATE_INIT_CONNECTION_COMPLETE: |
167 case STATE_CREATE_STREAM_COMPLETE: | 190 case STATE_CREATE_STREAM_COMPLETE: |
168 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); | 191 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); |
169 default: | 192 default: |
170 return LOAD_STATE_IDLE; | 193 return LOAD_STATE_IDLE; |
171 } | 194 } |
172 } | 195 } |
173 | 196 |
174 void HttpStreamFactoryImpl::Job::MarkAsAlternate( | |
175 AlternativeService alternative_service) { | |
176 DCHECK(!IsAlternate()); | |
177 alternative_service_ = alternative_service; | |
178 if (alternative_service.protocol == QUIC) { | |
179 DCHECK(session_->params().enable_quic); | |
180 using_quic_ = true; | |
181 } | |
182 } | |
183 | |
184 void HttpStreamFactoryImpl::Job::WaitFor(Job* job) { | 197 void HttpStreamFactoryImpl::Job::WaitFor(Job* job) { |
185 DCHECK_EQ(STATE_NONE, next_state_); | 198 DCHECK_EQ(STATE_NONE, next_state_); |
186 DCHECK_EQ(STATE_NONE, job->next_state_); | 199 DCHECK_EQ(STATE_NONE, job->next_state_); |
187 DCHECK(!blocking_job_); | 200 DCHECK(!blocking_job_); |
188 DCHECK(!job->waiting_job_); | 201 DCHECK(!job->waiting_job_); |
189 blocking_job_ = job; | 202 blocking_job_ = job; |
190 job->waiting_job_ = this; | 203 job->waiting_job_ = this; |
191 } | 204 } |
192 | 205 |
193 void HttpStreamFactoryImpl::Job::Resume(Job* job) { | 206 void HttpStreamFactoryImpl::Job::Resume(Job* job) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 | 295 |
283 bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const { | 296 bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const { |
284 // We need to make sure that if a spdy session was created for | 297 // We need to make sure that if a spdy session was created for |
285 // https://somehost/ that we don't use that session for http://somehost:443/. | 298 // https://somehost/ that we don't use that session for http://somehost:443/. |
286 // The only time we can use an existing session is if the request URL is | 299 // The only time we can use an existing session is if the request URL is |
287 // https (the normal case) or if we're connection to a SPDY proxy. | 300 // https (the normal case) or if we're connection to a SPDY proxy. |
288 // https://crbug.com/133176 | 301 // https://crbug.com/133176 |
289 // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is | 302 // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is |
290 // working. | 303 // working. |
291 return origin_url_.SchemeIs("https") || | 304 return origin_url_.SchemeIs("https") || |
292 proxy_info_.proxy_server().is_https() || IsSpdyAlternate(); | 305 proxy_info_.proxy_server().is_https() || IsSpdyAlternative(); |
293 } | 306 } |
294 | 307 |
295 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { | 308 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { |
296 DCHECK(stream_.get()); | 309 DCHECK(stream_.get()); |
297 DCHECK(!IsPreconnecting()); | 310 DCHECK(!IsPreconnecting()); |
298 DCHECK(!stream_factory_->for_websockets_); | 311 DCHECK(!stream_factory_->for_websockets_); |
299 | 312 |
300 MaybeCopyConnectionAttemptsFromSocketOrHandle(); | 313 MaybeCopyConnectionAttemptsFromSocketOrHandle(); |
301 | 314 |
302 if (IsOrphaned()) { | 315 if (IsOrphaned()) { |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 } else { | 561 } else { |
549 DCHECK(stream_.get()); | 562 DCHECK(stream_.get()); |
550 base::MessageLoop::current()->PostTask( | 563 base::MessageLoop::current()->PostTask( |
551 FROM_HERE, | 564 FROM_HERE, |
552 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 565 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
553 } | 566 } |
554 return ERR_IO_PENDING; | 567 return ERR_IO_PENDING; |
555 | 568 |
556 default: | 569 default: |
557 DCHECK(result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN || | 570 DCHECK(result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN || |
558 IsAlternate()); | 571 IsSpdyAlternative() || IsQuicAlternative()); |
559 if (job_status_ != STATUS_BROKEN) { | 572 if (job_status_ != STATUS_BROKEN) { |
560 DCHECK_EQ(STATUS_RUNNING, job_status_); | 573 DCHECK_EQ(STATUS_RUNNING, job_status_); |
561 job_status_ = STATUS_FAILED; | 574 job_status_ = STATUS_FAILED; |
562 // TODO(bnc): If (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), | 575 // TODO(bnc): If (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), |
563 // then instead of marking alternative service broken, mark (origin, | 576 // then instead of marking alternative service broken, mark (origin, |
564 // alternative service) couple as invalid. | 577 // alternative service) couple as invalid. |
565 MaybeMarkAlternativeServiceBroken(); | 578 MaybeMarkAlternativeServiceBroken(); |
566 } | 579 } |
567 base::MessageLoop::current()->PostTask( | 580 base::MessageLoop::current()->PostTask( |
568 FROM_HERE, | 581 FROM_HERE, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 | 645 |
633 int HttpStreamFactoryImpl::Job::StartInternal() { | 646 int HttpStreamFactoryImpl::Job::StartInternal() { |
634 CHECK_EQ(STATE_NONE, next_state_); | 647 CHECK_EQ(STATE_NONE, next_state_); |
635 next_state_ = STATE_START; | 648 next_state_ = STATE_START; |
636 int rv = RunLoop(OK); | 649 int rv = RunLoop(OK); |
637 DCHECK_EQ(ERR_IO_PENDING, rv); | 650 DCHECK_EQ(ERR_IO_PENDING, rv); |
638 return rv; | 651 return rv; |
639 } | 652 } |
640 | 653 |
641 int HttpStreamFactoryImpl::Job::DoStart() { | 654 int HttpStreamFactoryImpl::Job::DoStart() { |
642 if (IsAlternate()) { | 655 if (IsSpdyAlternative() || IsQuicAlternative()) { |
643 server_ = alternative_service_.host_port_pair(); | 656 server_ = alternative_service_.host_port_pair(); |
644 } else { | 657 } else { |
645 server_ = HostPortPair::FromURL(request_info_.url); | 658 server_ = HostPortPair::FromURL(request_info_.url); |
646 } | 659 } |
647 origin_url_ = | 660 origin_url_ = |
648 stream_factory_->ApplyHostMappingRules(request_info_.url, &server_); | 661 stream_factory_->ApplyHostMappingRules(request_info_.url, &server_); |
649 valid_spdy_session_pool_.reset(new ValidSpdySessionPool( | 662 valid_spdy_session_pool_.reset(new ValidSpdySessionPool( |
650 session_->spdy_session_pool(), origin_url_, IsSpdyAlternate())); | 663 session_->spdy_session_pool(), origin_url_, IsSpdyAlternative())); |
651 | 664 |
652 net_log_.BeginEvent( | 665 net_log_.BeginEvent( |
653 NetLog::TYPE_HTTP_STREAM_JOB, | 666 NetLog::TYPE_HTTP_STREAM_JOB, |
654 base::Bind(&NetLogHttpStreamJobCallback, &request_info_.url, &origin_url_, | 667 base::Bind(&NetLogHttpStreamJobCallback, &request_info_.url, &origin_url_, |
655 &alternative_service_, priority_)); | 668 &alternative_service_, priority_)); |
656 | 669 |
657 // Don't connect to restricted ports. | 670 // Don't connect to restricted ports. |
658 bool is_port_allowed = IsPortAllowedByDefault(server_.port()); | 671 bool is_port_allowed = IsPortAllowedByDefault(server_.port()); |
659 if (request_info_.url.SchemeIs("ftp")) { | 672 if (request_info_.url.SchemeIs("ftp")) { |
660 // Never share connection with other jobs for FTP requests. | 673 // Never share connection with other jobs for FTP requests. |
(...skipping 23 matching lines...) Expand all Loading... |
684 proxy_info_.UseDirect(); | 697 proxy_info_.UseDirect(); |
685 return OK; | 698 return OK; |
686 } | 699 } |
687 | 700 |
688 // TODO(rch): remove this code since Alt-Svc seems to prohibit it. | 701 // TODO(rch): remove this code since Alt-Svc seems to prohibit it. |
689 GURL url_for_proxy = origin_url_; | 702 GURL url_for_proxy = origin_url_; |
690 // For SPDY via Alt-Svc, set |alternative_service_url_| to | 703 // For SPDY via Alt-Svc, set |alternative_service_url_| to |
691 // https://<alternative host>:<alternative port>/... | 704 // https://<alternative host>:<alternative port>/... |
692 // so the proxy resolution works with the actual destination, and so | 705 // so the proxy resolution works with the actual destination, and so |
693 // that the correct socket pool is used. | 706 // that the correct socket pool is used. |
694 if (IsSpdyAlternate()) { | 707 if (IsSpdyAlternative()) { |
695 // TODO(rch): Figure out how to make QUIC iteract with PAC | 708 // TODO(rch): Figure out how to make QUIC iteract with PAC |
696 // scripts. By not re-writing the URL, we will query the PAC script | 709 // scripts. By not re-writing the URL, we will query the PAC script |
697 // for the proxy to use to reach the original URL via TCP. But | 710 // for the proxy to use to reach the original URL via TCP. But |
698 // the alternate request will be going via UDP to a different port. | 711 // the alternate request will be going via UDP to a different port. |
699 GURL::Replacements replacements; | 712 GURL::Replacements replacements; |
700 // new_port needs to be in scope here because GURL::Replacements references | 713 // new_port needs to be in scope here because GURL::Replacements references |
701 // the memory contained by it directly. | 714 // the memory contained by it directly. |
702 const std::string new_port = base::IntToString(alternative_service_.port); | 715 const std::string new_port = base::IntToString(alternative_service_.port); |
703 replacements.SetSchemeStr("https"); | 716 replacements.SetSchemeStr("https"); |
704 replacements.SetPortStr(new_port); | 717 replacements.SetPortStr(new_port); |
(...skipping 20 matching lines...) Expand all Loading... |
725 | 738 |
726 proxy_info_.RemoveProxiesWithoutScheme(supported_proxies); | 739 proxy_info_.RemoveProxiesWithoutScheme(supported_proxies); |
727 | 740 |
728 if (proxy_info_.is_empty()) { | 741 if (proxy_info_.is_empty()) { |
729 // No proxies/direct to choose from. This happens when we don't support | 742 // No proxies/direct to choose from. This happens when we don't support |
730 // any of the proxies in the returned list. | 743 // any of the proxies in the returned list. |
731 result = ERR_NO_SUPPORTED_PROXIES; | 744 result = ERR_NO_SUPPORTED_PROXIES; |
732 } else if (using_quic_ && | 745 } else if (using_quic_ && |
733 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { | 746 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { |
734 // QUIC can not be spoken to non-QUIC proxies. This error should not be | 747 // QUIC can not be spoken to non-QUIC proxies. This error should not be |
735 // user visible, because the non-alternate job should be resumed. | 748 // user visible, because the non-alternative Job should be resumed. |
736 result = ERR_NO_SUPPORTED_PROXIES; | 749 result = ERR_NO_SUPPORTED_PROXIES; |
737 } | 750 } |
738 } | 751 } |
739 | 752 |
740 if (result != OK) { | 753 if (result != OK) { |
741 if (waiting_job_) { | 754 if (waiting_job_) { |
742 waiting_job_->Resume(this); | 755 waiting_job_->Resume(this); |
743 waiting_job_ = NULL; | 756 waiting_job_ = NULL; |
744 } | 757 } |
745 return result; | 758 return result; |
(...skipping 29 matching lines...) Expand all Loading... |
775 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. | 788 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. |
776 tracked_objects::ScopedTracker tracking_profile( | 789 tracked_objects::ScopedTracker tracking_profile( |
777 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 790 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
778 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); | 791 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); |
779 DCHECK(!blocking_job_); | 792 DCHECK(!blocking_job_); |
780 DCHECK(!connection_->is_initialized()); | 793 DCHECK(!connection_->is_initialized()); |
781 DCHECK(proxy_info_.proxy_server().is_valid()); | 794 DCHECK(proxy_info_.proxy_server().is_valid()); |
782 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 795 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
783 | 796 |
784 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || | 797 using_ssl_ = origin_url_.SchemeIs("https") || origin_url_.SchemeIs("wss") || |
785 IsSpdyAlternate(); | 798 IsSpdyAlternative(); |
786 using_spdy_ = false; | 799 using_spdy_ = false; |
787 | 800 |
788 if (ShouldForceQuic()) | 801 if (ShouldForceQuic()) |
789 using_quic_ = true; | 802 using_quic_ = true; |
790 | 803 |
791 DCHECK(!using_quic_ || session_->params().enable_quic); | 804 DCHECK(!using_quic_ || session_->params().enable_quic); |
792 | 805 |
793 if (proxy_info_.is_quic()) { | 806 if (proxy_info_.is_quic()) { |
794 using_quic_ = true; | 807 using_quic_ = true; |
795 DCHECK(session_->params().enable_quic_for_proxies); | 808 DCHECK(session_->params().enable_quic_for_proxies); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 // paused. | 864 // paused. |
852 if (waiting_job_) { | 865 if (waiting_job_) { |
853 waiting_job_->Resume(this); | 866 waiting_job_->Resume(this); |
854 waiting_job_ = NULL; | 867 waiting_job_ = NULL; |
855 } | 868 } |
856 | 869 |
857 if (proxy_info_.is_http() || proxy_info_.is_https()) | 870 if (proxy_info_.is_http() || proxy_info_.is_https()) |
858 establishing_tunnel_ = using_ssl_; | 871 establishing_tunnel_ = using_ssl_; |
859 | 872 |
860 // TODO(bnc): s/want_spdy_over_npn/expect_spdy_over_npn/ | 873 // TODO(bnc): s/want_spdy_over_npn/expect_spdy_over_npn/ |
861 bool want_spdy_over_npn = IsAlternate(); | 874 bool want_spdy_over_npn = IsSpdyAlternative(); |
862 | 875 |
863 if (proxy_info_.is_https()) { | 876 if (proxy_info_.is_https()) { |
864 InitSSLConfig(proxy_info_.proxy_server().host_port_pair(), | 877 InitSSLConfig(proxy_info_.proxy_server().host_port_pair(), |
865 &proxy_ssl_config_, | 878 &proxy_ssl_config_, |
866 true /* is a proxy server */); | 879 true /* is a proxy server */); |
867 // Disable revocation checking for HTTPS proxies since the revocation | 880 // Disable revocation checking for HTTPS proxies since the revocation |
868 // requests are probably going to need to go through the proxy too. | 881 // requests are probably going to need to go through the proxy too. |
869 proxy_ssl_config_.rev_checking_enabled = false; | 882 proxy_ssl_config_.rev_checking_enabled = false; |
870 } | 883 } |
871 if (using_ssl_) { | 884 if (using_ssl_) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an | 1020 // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an |
1008 // SSL socket, but there was an error before that could happen. This | 1021 // SSL socket, but there was an error before that could happen. This |
1009 // puts the in progress HttpProxy socket into |connection_| in order to | 1022 // puts the in progress HttpProxy socket into |connection_| in order to |
1010 // complete the auth (or read the response body). The tunnel restart code | 1023 // complete the auth (or read the response body). The tunnel restart code |
1011 // is careful to remove it before returning control to the rest of this | 1024 // is careful to remove it before returning control to the rest of this |
1012 // class. | 1025 // class. |
1013 connection_.reset(connection_->release_pending_http_proxy_connection()); | 1026 connection_.reset(connection_->release_pending_http_proxy_connection()); |
1014 return result; | 1027 return result; |
1015 } | 1028 } |
1016 | 1029 |
1017 if (IsSpdyAlternate() && !using_spdy_) { | 1030 if (IsSpdyAlternative() && !using_spdy_) { |
1018 job_status_ = STATUS_BROKEN; | 1031 job_status_ = STATUS_BROKEN; |
1019 MaybeMarkAlternativeServiceBroken(); | 1032 MaybeMarkAlternativeServiceBroken(); |
1020 return ERR_NPN_NEGOTIATION_FAILED; | 1033 return ERR_NPN_NEGOTIATION_FAILED; |
1021 } | 1034 } |
1022 | 1035 |
1023 if (!ssl_started && result < 0 && IsAlternate()) { | 1036 if (!ssl_started && result < 0 && |
| 1037 (IsSpdyAlternative() || IsQuicAlternative())) { |
1024 job_status_ = STATUS_BROKEN; | 1038 job_status_ = STATUS_BROKEN; |
1025 // TODO(bnc): if (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), then | 1039 // TODO(bnc): if (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), then |
1026 // instead of marking alternative service broken, mark (origin, alternative | 1040 // instead of marking alternative service broken, mark (origin, alternative |
1027 // service) couple as invalid. | 1041 // service) couple as invalid. |
1028 MaybeMarkAlternativeServiceBroken(); | 1042 MaybeMarkAlternativeServiceBroken(); |
1029 return result; | 1043 return result; |
1030 } | 1044 } |
1031 | 1045 |
1032 if (using_quic_) { | 1046 if (using_quic_) { |
1033 if (result < 0) { | 1047 if (result < 0) { |
(...skipping 15 matching lines...) Expand all Loading... |
1049 if (!connection_->is_reused()) { | 1063 if (!connection_->is_reused()) { |
1050 ConnectionType type = using_spdy_ ? CONNECTION_SPDY : CONNECTION_HTTP; | 1064 ConnectionType type = using_spdy_ ? CONNECTION_SPDY : CONNECTION_HTTP; |
1051 UpdateConnectionTypeHistograms(type); | 1065 UpdateConnectionTypeHistograms(type); |
1052 } | 1066 } |
1053 } | 1067 } |
1054 | 1068 |
1055 // Handle SSL errors below. | 1069 // Handle SSL errors below. |
1056 if (using_ssl_) { | 1070 if (using_ssl_) { |
1057 DCHECK(ssl_started); | 1071 DCHECK(ssl_started); |
1058 if (IsCertificateError(result)) { | 1072 if (IsCertificateError(result)) { |
1059 if (using_spdy_ && IsAlternate() && origin_url_.SchemeIs("http")) { | 1073 if (IsSpdyAlternative() && origin_url_.SchemeIs("http")) { |
1060 // We ignore certificate errors for http over spdy. | 1074 // We ignore certificate errors for http over spdy. |
1061 spdy_certificate_error_ = result; | 1075 spdy_certificate_error_ = result; |
1062 result = OK; | 1076 result = OK; |
1063 } else { | 1077 } else { |
1064 result = HandleCertificateError(result); | 1078 result = HandleCertificateError(result); |
1065 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { | 1079 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { |
1066 ReturnToStateInitConnection(true /* close connection */); | 1080 ReturnToStateInitConnection(true /* close connection */); |
1067 return result; | 1081 return result; |
1068 } | 1082 } |
1069 } | 1083 } |
(...skipping 30 matching lines...) Expand all Loading... |
1100 stream_.reset(new SpdyHttpStream(session, use_relative_url)); | 1114 stream_.reset(new SpdyHttpStream(session, use_relative_url)); |
1101 return OK; | 1115 return OK; |
1102 } | 1116 } |
1103 | 1117 |
1104 int HttpStreamFactoryImpl::Job::DoCreateStream() { | 1118 int HttpStreamFactoryImpl::Job::DoCreateStream() { |
1105 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462811 is fixed. | 1119 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462811 is fixed. |
1106 tracked_objects::ScopedTracker tracking_profile( | 1120 tracked_objects::ScopedTracker tracking_profile( |
1107 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1121 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1108 "462811 HttpStreamFactoryImpl::Job::DoCreateStream")); | 1122 "462811 HttpStreamFactoryImpl::Job::DoCreateStream")); |
1109 DCHECK(connection_->socket() || existing_spdy_session_.get() || using_quic_); | 1123 DCHECK(connection_->socket() || existing_spdy_session_.get() || using_quic_); |
1110 if (IsAlternate()) | 1124 DCHECK(!IsQuicAlternative()); |
1111 DCHECK(IsSpdyAlternate()); | |
1112 | 1125 |
1113 next_state_ = STATE_CREATE_STREAM_COMPLETE; | 1126 next_state_ = STATE_CREATE_STREAM_COMPLETE; |
1114 | 1127 |
1115 // We only set the socket motivation if we're the first to use | 1128 // We only set the socket motivation if we're the first to use |
1116 // this socket. Is there a race for two SPDY requests? We really | 1129 // this socket. Is there a race for two SPDY requests? We really |
1117 // need to plumb this through to the connect level. | 1130 // need to plumb this through to the connect level. |
1118 if (connection_->socket() && !connection_->is_reused()) | 1131 if (connection_->socket() && !connection_->is_reused()) |
1119 SetSocketMotivation(); | 1132 SetSocketMotivation(); |
1120 | 1133 |
1121 if (!using_spdy_) { | 1134 if (!using_spdy_) { |
1122 DCHECK(!IsSpdyAlternate()); | 1135 DCHECK(!IsSpdyAlternative()); |
1123 // We may get ftp scheme when fetching ftp resources through proxy. | 1136 // We may get ftp scheme when fetching ftp resources through proxy. |
1124 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && | 1137 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && |
1125 (request_info_.url.SchemeIs("http") || | 1138 (request_info_.url.SchemeIs("http") || |
1126 request_info_.url.SchemeIs("ftp")); | 1139 request_info_.url.SchemeIs("ftp")); |
1127 if (stream_factory_->for_websockets_) { | 1140 if (stream_factory_->for_websockets_) { |
1128 DCHECK(request_); | 1141 DCHECK(request_); |
1129 DCHECK(request_->websocket_handshake_stream_create_helper()); | 1142 DCHECK(request_->websocket_handshake_stream_create_helper()); |
1130 websocket_stream_.reset( | 1143 websocket_stream_.reset( |
1131 request_->websocket_handshake_stream_create_helper() | 1144 request_->websocket_handshake_stream_create_helper() |
1132 ->CreateBasicStream(connection_.Pass(), using_proxy)); | 1145 ->CreateBasicStream(connection_.Pass(), using_proxy)); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 if (request_info_.motivation == HttpRequestInfo::PRECONNECT_MOTIVATED) | 1255 if (request_info_.motivation == HttpRequestInfo::PRECONNECT_MOTIVATED) |
1243 connection_->socket()->SetSubresourceSpeculation(); | 1256 connection_->socket()->SetSubresourceSpeculation(); |
1244 else if (request_info_.motivation == HttpRequestInfo::OMNIBOX_MOTIVATED) | 1257 else if (request_info_.motivation == HttpRequestInfo::OMNIBOX_MOTIVATED) |
1245 connection_->socket()->SetOmniboxSpeculation(); | 1258 connection_->socket()->SetOmniboxSpeculation(); |
1246 // TODO(mbelshe): Add other motivations (like EARLY_LOAD_MOTIVATED). | 1259 // TODO(mbelshe): Add other motivations (like EARLY_LOAD_MOTIVATED). |
1247 } | 1260 } |
1248 | 1261 |
1249 bool HttpStreamFactoryImpl::Job::IsHttpsProxyAndHttpUrl() const { | 1262 bool HttpStreamFactoryImpl::Job::IsHttpsProxyAndHttpUrl() const { |
1250 if (!proxy_info_.is_https()) | 1263 if (!proxy_info_.is_https()) |
1251 return false; | 1264 return false; |
1252 if (IsAlternate()) { | 1265 if (IsSpdyAlternative() || IsQuicAlternative()) { |
1253 // We currently only support Alternate-Protocol where the original scheme | 1266 // We currently only support Alternate-Protocol where the original scheme |
1254 // is http. | 1267 // is http. |
1255 DCHECK(origin_url_.SchemeIs("http")); | 1268 DCHECK(origin_url_.SchemeIs("http")); |
1256 return origin_url_.SchemeIs("http"); | 1269 return origin_url_.SchemeIs("http"); |
1257 } | 1270 } |
1258 return request_info_.url.SchemeIs("http"); | 1271 return request_info_.url.SchemeIs("http"); |
1259 } | 1272 } |
1260 | 1273 |
1261 bool HttpStreamFactoryImpl::Job::IsAlternate() const { | 1274 bool HttpStreamFactoryImpl::Job::IsSpdyAlternative() const { |
1262 return alternative_service_.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL; | 1275 return alternative_service_.protocol >= NPN_SPDY_MINIMUM_VERSION && |
| 1276 alternative_service_.protocol <= NPN_SPDY_MAXIMUM_VERSION; |
1263 } | 1277 } |
1264 | 1278 |
1265 bool HttpStreamFactoryImpl::Job::IsSpdyAlternate() const { | 1279 bool HttpStreamFactoryImpl::Job::IsQuicAlternative() const { |
1266 return alternative_service_.protocol >= NPN_SPDY_MINIMUM_VERSION && | 1280 return alternative_service_.protocol == QUIC; |
1267 alternative_service_.protocol <= NPN_SPDY_MAXIMUM_VERSION; | |
1268 } | 1281 } |
1269 | 1282 |
1270 void HttpStreamFactoryImpl::Job::InitSSLConfig(const HostPortPair& server, | 1283 void HttpStreamFactoryImpl::Job::InitSSLConfig(const HostPortPair& server, |
1271 SSLConfig* ssl_config, | 1284 SSLConfig* ssl_config, |
1272 bool is_proxy) const { | 1285 bool is_proxy) const { |
1273 if (!is_proxy) { | 1286 if (!is_proxy) { |
1274 // Prior to HTTP/2 and SPDY, some servers use TLS renegotiation to request | 1287 // Prior to HTTP/2 and SPDY, some servers use TLS renegotiation to request |
1275 // TLS client authentication after the HTTP request was sent. Allow | 1288 // TLS client authentication after the HTTP request was sent. Allow |
1276 // renegotiation for only those connections. | 1289 // renegotiation for only those connections. |
1277 // | 1290 // |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1430 | 1443 |
1431 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { | 1444 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { |
1432 return !IsPreconnecting() && !request_; | 1445 return !IsPreconnecting() && !request_; |
1433 } | 1446 } |
1434 | 1447 |
1435 void HttpStreamFactoryImpl::Job::ReportJobSucceededForRequest() { | 1448 void HttpStreamFactoryImpl::Job::ReportJobSucceededForRequest() { |
1436 if (using_existing_quic_session_) { | 1449 if (using_existing_quic_session_) { |
1437 // If an existing session was used, then no TCP connection was | 1450 // If an existing session was used, then no TCP connection was |
1438 // started. | 1451 // started. |
1439 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE); | 1452 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE); |
1440 } else if (IsAlternate()) { | 1453 } else if (IsSpdyAlternative() || IsQuicAlternative()) { |
1441 // This job was the alternate protocol job, and hence won the race. | 1454 // This Job was the alternative Job, and hence won the race. |
1442 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE); | 1455 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE); |
1443 } else { | 1456 } else { |
1444 // This job was the normal job, and hence the alternate protocol job lost | 1457 // This Job was the normal Job, and hence the alternative Job lost the race. |
1445 // the race. | |
1446 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); | 1458 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE); |
1447 } | 1459 } |
1448 } | 1460 } |
1449 | 1461 |
1450 void HttpStreamFactoryImpl::Job::MarkOtherJobComplete(const Job& job) { | 1462 void HttpStreamFactoryImpl::Job::MarkOtherJobComplete(const Job& job) { |
1451 DCHECK_EQ(STATUS_RUNNING, other_job_status_); | 1463 DCHECK_EQ(STATUS_RUNNING, other_job_status_); |
1452 other_job_status_ = job.job_status_; | 1464 other_job_status_ = job.job_status_; |
1453 other_job_alternative_service_ = job.alternative_service_; | 1465 other_job_alternative_service_ = job.alternative_service_; |
1454 MaybeMarkAlternativeServiceBroken(); | 1466 MaybeMarkAlternativeServiceBroken(); |
1455 } | 1467 } |
1456 | 1468 |
1457 void HttpStreamFactoryImpl::Job::MaybeMarkAlternativeServiceBroken() { | 1469 void HttpStreamFactoryImpl::Job::MaybeMarkAlternativeServiceBroken() { |
1458 if (job_status_ == STATUS_RUNNING || other_job_status_ == STATUS_RUNNING) | 1470 if (job_status_ == STATUS_RUNNING || other_job_status_ == STATUS_RUNNING) |
1459 return; | 1471 return; |
1460 | 1472 |
1461 if (IsAlternate()) { | 1473 if (IsSpdyAlternative() || IsQuicAlternative()) { |
1462 if (job_status_ == STATUS_BROKEN && other_job_status_ == STATUS_SUCCEEDED) { | 1474 if (job_status_ == STATUS_BROKEN && other_job_status_ == STATUS_SUCCEEDED) { |
1463 HistogramBrokenAlternateProtocolLocation( | 1475 HistogramBrokenAlternateProtocolLocation( |
1464 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); | 1476 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); |
1465 session_->http_server_properties()->MarkAlternativeServiceBroken( | 1477 session_->http_server_properties()->MarkAlternativeServiceBroken( |
1466 alternative_service_); | 1478 alternative_service_); |
1467 } | 1479 } |
1468 return; | 1480 return; |
1469 } | 1481 } |
1470 | 1482 |
1471 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { | 1483 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { |
1472 HistogramBrokenAlternateProtocolLocation( | 1484 HistogramBrokenAlternateProtocolLocation( |
1473 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); | 1485 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); |
1474 session_->http_server_properties()->MarkAlternativeServiceBroken( | 1486 session_->http_server_properties()->MarkAlternativeServiceBroken( |
1475 other_job_alternative_service_); | 1487 other_job_alternative_service_); |
1476 } | 1488 } |
1477 } | 1489 } |
1478 | 1490 |
1479 HttpStreamFactoryImpl::Job::ValidSpdySessionPool::ValidSpdySessionPool( | 1491 HttpStreamFactoryImpl::Job::ValidSpdySessionPool::ValidSpdySessionPool( |
1480 SpdySessionPool* spdy_session_pool, | 1492 SpdySessionPool* spdy_session_pool, |
1481 GURL& origin_url, | 1493 GURL& origin_url, |
1482 bool is_spdy_alternate) | 1494 bool is_spdy_alternative) |
1483 : spdy_session_pool_(spdy_session_pool), | 1495 : spdy_session_pool_(spdy_session_pool), |
1484 origin_url_(origin_url), | 1496 origin_url_(origin_url), |
1485 is_spdy_alternate_(is_spdy_alternate) { | 1497 is_spdy_alternative_(is_spdy_alternative) { |
1486 } | 1498 } |
1487 | 1499 |
1488 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::FindAvailableSession( | 1500 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::FindAvailableSession( |
1489 const SpdySessionKey& key, | 1501 const SpdySessionKey& key, |
1490 const BoundNetLog& net_log, | 1502 const BoundNetLog& net_log, |
1491 base::WeakPtr<SpdySession>* spdy_session) { | 1503 base::WeakPtr<SpdySession>* spdy_session) { |
1492 *spdy_session = spdy_session_pool_->FindAvailableSession(key, net_log); | 1504 *spdy_session = spdy_session_pool_->FindAvailableSession(key, net_log); |
1493 return CheckAlternativeServiceValidityForOrigin(*spdy_session); | 1505 return CheckAlternativeServiceValidityForOrigin(*spdy_session); |
1494 } | 1506 } |
1495 | 1507 |
1496 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool:: | 1508 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool:: |
1497 CreateAvailableSessionFromSocket(const SpdySessionKey& key, | 1509 CreateAvailableSessionFromSocket(const SpdySessionKey& key, |
1498 scoped_ptr<ClientSocketHandle> connection, | 1510 scoped_ptr<ClientSocketHandle> connection, |
1499 const BoundNetLog& net_log, | 1511 const BoundNetLog& net_log, |
1500 int certificate_error_code, | 1512 int certificate_error_code, |
1501 bool is_secure, | 1513 bool is_secure, |
1502 base::WeakPtr<SpdySession>* spdy_session) { | 1514 base::WeakPtr<SpdySession>* spdy_session) { |
1503 *spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket( | 1515 *spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket( |
1504 key, connection.Pass(), net_log, certificate_error_code, is_secure); | 1516 key, connection.Pass(), net_log, certificate_error_code, is_secure); |
1505 return CheckAlternativeServiceValidityForOrigin(*spdy_session); | 1517 return CheckAlternativeServiceValidityForOrigin(*spdy_session); |
1506 } | 1518 } |
1507 | 1519 |
1508 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool:: | 1520 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool:: |
1509 CheckAlternativeServiceValidityForOrigin( | 1521 CheckAlternativeServiceValidityForOrigin( |
1510 base::WeakPtr<SpdySession> spdy_session) { | 1522 base::WeakPtr<SpdySession> spdy_session) { |
1511 // For a SPDY alternate Job, server_.host() might be different than | 1523 // For an alternative Job, server_.host() might be different than |
1512 // origin_url_.host(), therefore it needs to be verified that the former | 1524 // origin_url_.host(), therefore it needs to be verified that the former |
1513 // provides a certificate that is valid for the latter. | 1525 // provides a certificate that is valid for the latter. |
1514 if (!is_spdy_alternate_ || !spdy_session || | 1526 if (!is_spdy_alternative_ || !spdy_session || |
1515 spdy_session->VerifyDomainAuthentication(origin_url_.host())) { | 1527 spdy_session->VerifyDomainAuthentication(origin_url_.host())) { |
1516 return OK; | 1528 return OK; |
1517 } | 1529 } |
1518 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | 1530 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; |
1519 } | 1531 } |
1520 | 1532 |
1521 ClientSocketPoolManager::SocketGroupType | 1533 ClientSocketPoolManager::SocketGroupType |
1522 HttpStreamFactoryImpl::Job::GetSocketGroup() const { | 1534 HttpStreamFactoryImpl::Job::GetSocketGroup() const { |
1523 std::string scheme = origin_url_.scheme(); | 1535 std::string scheme = origin_url_.scheme(); |
1524 if (scheme == "https" || scheme == "wss" || IsSpdyAlternate()) | 1536 if (scheme == "https" || scheme == "wss" || IsSpdyAlternative()) |
1525 return ClientSocketPoolManager::SSL_GROUP; | 1537 return ClientSocketPoolManager::SSL_GROUP; |
1526 | 1538 |
1527 if (scheme == "ftp") | 1539 if (scheme == "ftp") |
1528 return ClientSocketPoolManager::FTP_GROUP; | 1540 return ClientSocketPoolManager::FTP_GROUP; |
1529 | 1541 |
1530 return ClientSocketPoolManager::NORMAL_GROUP; | 1542 return ClientSocketPoolManager::NORMAL_GROUP; |
1531 } | 1543 } |
1532 | 1544 |
1533 // If the connection succeeds, failed connection attempts leading up to the | 1545 // If the connection succeeds, failed connection attempts leading up to the |
1534 // success will be returned via the successfully connected socket. If the | 1546 // success will be returned via the successfully connected socket. If the |
1535 // connection fails, failed connection attempts will be returned via the | 1547 // connection fails, failed connection attempts will be returned via the |
1536 // ClientSocketHandle. Check whether a socket was returned and copy the | 1548 // ClientSocketHandle. Check whether a socket was returned and copy the |
1537 // connection attempts from the proper place. | 1549 // connection attempts from the proper place. |
1538 void HttpStreamFactoryImpl::Job:: | 1550 void HttpStreamFactoryImpl::Job:: |
1539 MaybeCopyConnectionAttemptsFromSocketOrHandle() { | 1551 MaybeCopyConnectionAttemptsFromSocketOrHandle() { |
1540 if (IsOrphaned() || !connection_) | 1552 if (IsOrphaned() || !connection_) |
1541 return; | 1553 return; |
1542 | 1554 |
1543 if (connection_->socket()) { | 1555 if (connection_->socket()) { |
1544 ConnectionAttempts socket_attempts; | 1556 ConnectionAttempts socket_attempts; |
1545 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1557 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
1546 request_->AddConnectionAttempts(socket_attempts); | 1558 request_->AddConnectionAttempts(socket_attempts); |
1547 } else { | 1559 } else { |
1548 request_->AddConnectionAttempts(connection_->connection_attempts()); | 1560 request_->AddConnectionAttempts(connection_->connection_attempts()); |
1549 } | 1561 } |
1550 } | 1562 } |
1551 | 1563 |
1552 } // namespace net | 1564 } // namespace net |
OLD | NEW |